Skip to content

Commit b5dce20

Browse files
Daniel Bristot de Oliveirarostedt
authored andcommitted
tracing/osnoise: Add preempt and/or irq disabled options
The osnoise workload runs with preemption and IRQs enabled in such a way as to allow all sorts of noise to disturb osnoise's execution. hwlat tracer has a similar workload but works with irq disabled, allowing only NMIs and the hardware to generate noise. While thinking about adding an options file to hwlat tracer to allow the system to panic, and other features I was thinking to add, like having a tracepoint at each noise detection, it came to my mind that is easier to make osnoise and also do hardware latency detection than making hwlat "feature compatible" with osnoise. Other points are: - osnoise already has an independent cpu file. - osnoise has a more intuitive interface, e.g., runtime/period vs. window/width (and people often need help remembering what it is). - osnoise: tracepoints - osnoise stop options - osnoise options file itself Moreover, the user-space side (in rtla) is simplified by reusing the existing osnoise code. Finally, people have been asking me about using osnoise for hw latency detection, and I have to explain that it was sufficient but not necessary. These options make it sufficient and necessary. Adding a Suggested-by Clark, as he often asked me about this possibility. Link: https://lkml.kernel.org/r/d9c6c19135497054986900f94c8e47410b15316a.1670623111.git.bristot@kernel.org Cc: Suggested-by: Clark Williams <[email protected]> Cc: Juri Lelli <[email protected]> Cc: Bagas Sanjaya <[email protected]> Cc: Daniel Bristot de Oliveira <[email protected]> Cc: Masami Hiramatsu <[email protected]> Cc: Jonathan Corbet <[email protected]> Signed-off-by: Daniel Bristot de Oliveira <[email protected]> Signed-off-by: Steven Rostedt (Google) <[email protected]>
1 parent 1603dda commit b5dce20

File tree

1 file changed

+43
-5
lines changed

1 file changed

+43
-5
lines changed

kernel/trace/trace_osnoise.c

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,17 @@ enum osnoise_options_index {
5555
OSN_DEFAULTS = 0,
5656
OSN_WORKLOAD,
5757
OSN_PANIC_ON_STOP,
58+
OSN_PREEMPT_DISABLE,
59+
OSN_IRQ_DISABLE,
5860
OSN_MAX
5961
};
6062

61-
static const char * const osnoise_options_str[OSN_MAX] = { "DEFAULTS", "OSNOISE_WORKLOAD", "PANIC_ON_STOP" };
63+
static const char * const osnoise_options_str[OSN_MAX] = {
64+
"DEFAULTS",
65+
"OSNOISE_WORKLOAD",
66+
"PANIC_ON_STOP",
67+
"OSNOISE_PREEMPT_DISABLE",
68+
"OSNOISE_IRQ_DISABLE" };
6269

6370
#define OSN_DEFAULT_OPTIONS 0x2
6471
static unsigned long osnoise_options = OSN_DEFAULT_OPTIONS;
@@ -1308,18 +1315,26 @@ static void notify_new_max_latency(u64 latency)
13081315
*/
13091316
static int run_osnoise(void)
13101317
{
1318+
bool disable_irq = test_bit(OSN_IRQ_DISABLE, &osnoise_options);
13111319
struct osnoise_variables *osn_var = this_cpu_osn_var();
13121320
u64 start, sample, last_sample;
13131321
u64 last_int_count, int_count;
13141322
s64 noise = 0, max_noise = 0;
13151323
s64 total, last_total = 0;
13161324
struct osnoise_sample s;
1325+
bool disable_preemption;
13171326
unsigned int threshold;
13181327
u64 runtime, stop_in;
13191328
u64 sum_noise = 0;
13201329
int hw_count = 0;
13211330
int ret = -1;
13221331

1332+
/*
1333+
* Disabling preemption is only required if IRQs are enabled,
1334+
* and the options is set on.
1335+
*/
1336+
disable_preemption = !disable_irq && test_bit(OSN_PREEMPT_DISABLE, &osnoise_options);
1337+
13231338
/*
13241339
* Considers the current thread as the workload.
13251340
*/
@@ -1335,6 +1350,15 @@ static int run_osnoise(void)
13351350
*/
13361351
threshold = tracing_thresh ? : 5000;
13371352

1353+
/*
1354+
* Apply PREEMPT and IRQ disabled options.
1355+
*/
1356+
if (disable_irq)
1357+
local_irq_disable();
1358+
1359+
if (disable_preemption)
1360+
preempt_disable();
1361+
13381362
/*
13391363
* Make sure NMIs see sampling first
13401364
*/
@@ -1422,16 +1446,21 @@ static int run_osnoise(void)
14221446
* cond_resched()
14231447
*/
14241448
if (IS_ENABLED(CONFIG_PREEMPT_RCU)) {
1425-
local_irq_disable();
1449+
if (!disable_irq)
1450+
local_irq_disable();
1451+
14261452
rcu_momentary_dyntick_idle();
1427-
local_irq_enable();
1453+
1454+
if (!disable_irq)
1455+
local_irq_enable();
14281456
}
14291457

14301458
/*
14311459
* For the non-preemptive kernel config: let threads runs, if
1432-
* they so wish.
1460+
* they so wish, unless set not do to so.
14331461
*/
1434-
cond_resched();
1462+
if (!disable_irq && !disable_preemption)
1463+
cond_resched();
14351464

14361465
last_sample = sample;
14371466
last_int_count = int_count;
@@ -1450,6 +1479,15 @@ static int run_osnoise(void)
14501479
*/
14511480
barrier();
14521481

1482+
/*
1483+
* Return to the preemptive state.
1484+
*/
1485+
if (disable_preemption)
1486+
preempt_enable();
1487+
1488+
if (disable_irq)
1489+
local_irq_enable();
1490+
14531491
/*
14541492
* Save noise info.
14551493
*/

0 commit comments

Comments
 (0)