Skip to content

Commit a065bbf

Browse files
lenticularis39rostedt
authored andcommitted
trace/osnoise: Add trace events for samples
Add trace events that fire at osnoise and timerlat sample generation, in addition to the already existing noise and threshold events. This allows processing the samples directly in the kernel, either with ftrace triggers or with BPF. Cc: John Kacur <[email protected]> Cc: Luis Goncalves <[email protected]> Link: https://lore.kernel.org/[email protected] Signed-off-by: Tomas Glozar <[email protected]> Tested-by: Gabriele Monaco <[email protected]> Signed-off-by: Steven Rostedt (Google) <[email protected]>
1 parent d082ecb commit a065bbf

File tree

2 files changed

+112
-39
lines changed

2 files changed

+112
-39
lines changed

include/trace/events/osnoise.h

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,105 @@
33
#define TRACE_SYSTEM osnoise
44

55
#if !defined(_OSNOISE_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
6+
7+
#ifndef _OSNOISE_TRACE_H
68
#define _OSNOISE_TRACE_H
9+
/*
10+
* osnoise sample structure definition. Used to store the statistics of a
11+
* sample run.
12+
*/
13+
struct osnoise_sample {
14+
u64 runtime; /* runtime */
15+
u64 noise; /* noise */
16+
u64 max_sample; /* max single noise sample */
17+
int hw_count; /* # HW (incl. hypervisor) interference */
18+
int nmi_count; /* # NMIs during this sample */
19+
int irq_count; /* # IRQs during this sample */
20+
int softirq_count; /* # softirqs during this sample */
21+
int thread_count; /* # threads during this sample */
22+
};
23+
24+
#ifdef CONFIG_TIMERLAT_TRACER
25+
/*
26+
* timerlat sample structure definition. Used to store the statistics of
27+
* a sample run.
28+
*/
29+
struct timerlat_sample {
30+
u64 timer_latency; /* timer_latency */
31+
unsigned int seqnum; /* unique sequence */
32+
int context; /* timer context */
33+
};
34+
#endif // CONFIG_TIMERLAT_TRACER
35+
#endif // _OSNOISE_TRACE_H
736

837
#include <linux/tracepoint.h>
38+
TRACE_EVENT(osnoise_sample,
39+
40+
TP_PROTO(struct osnoise_sample *s),
41+
42+
TP_ARGS(s),
43+
44+
TP_STRUCT__entry(
45+
__field( u64, runtime )
46+
__field( u64, noise )
47+
__field( u64, max_sample )
48+
__field( int, hw_count )
49+
__field( int, irq_count )
50+
__field( int, nmi_count )
51+
__field( int, softirq_count )
52+
__field( int, thread_count )
53+
),
54+
55+
TP_fast_assign(
56+
__entry->runtime = s->runtime;
57+
__entry->noise = s->noise;
58+
__entry->max_sample = s->max_sample;
59+
__entry->hw_count = s->hw_count;
60+
__entry->irq_count = s->irq_count;
61+
__entry->nmi_count = s->nmi_count;
62+
__entry->softirq_count = s->softirq_count;
63+
__entry->thread_count = s->thread_count;
64+
),
65+
66+
TP_printk("runtime=%llu noise=%llu max_sample=%llu hw_count=%d"
67+
" irq_count=%d nmi_count=%d softirq_count=%d"
68+
" thread_count=%d",
69+
__entry->runtime,
70+
__entry->noise,
71+
__entry->max_sample,
72+
__entry->hw_count,
73+
__entry->irq_count,
74+
__entry->nmi_count,
75+
__entry->softirq_count,
76+
__entry->thread_count)
77+
);
78+
79+
#ifdef CONFIG_TIMERLAT_TRACER
80+
TRACE_EVENT(timerlat_sample,
81+
82+
TP_PROTO(struct timerlat_sample *s),
83+
84+
TP_ARGS(s),
85+
86+
TP_STRUCT__entry(
87+
__field( u64, timer_latency )
88+
__field( unsigned int, seqnum )
89+
__field( int, context )
90+
),
91+
92+
TP_fast_assign(
93+
__entry->timer_latency = s->timer_latency;
94+
__entry->seqnum = s->seqnum;
95+
__entry->context = s->context;
96+
),
97+
98+
TP_printk("timer_latency=%llu seqnum=%u context=%d",
99+
__entry->timer_latency,
100+
__entry->seqnum,
101+
__entry->context)
102+
);
103+
#endif // CONFIG_TIMERLAT_TRACER
104+
9105
TRACE_EVENT(thread_noise,
10106

11107
TP_PROTO(struct task_struct *t, u64 start, u64 duration),

kernel/trace/trace_osnoise.c

Lines changed: 16 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -315,33 +315,6 @@ static inline void osn_var_reset_all(void)
315315
*/
316316
bool trace_osnoise_callback_enabled;
317317

318-
/*
319-
* osnoise sample structure definition. Used to store the statistics of a
320-
* sample run.
321-
*/
322-
struct osnoise_sample {
323-
u64 runtime; /* runtime */
324-
u64 noise; /* noise */
325-
u64 max_sample; /* max single noise sample */
326-
int hw_count; /* # HW (incl. hypervisor) interference */
327-
int nmi_count; /* # NMIs during this sample */
328-
int irq_count; /* # IRQs during this sample */
329-
int softirq_count; /* # softirqs during this sample */
330-
int thread_count; /* # threads during this sample */
331-
};
332-
333-
#ifdef CONFIG_TIMERLAT_TRACER
334-
/*
335-
* timerlat sample structure definition. Used to store the statistics of
336-
* a sample run.
337-
*/
338-
struct timerlat_sample {
339-
u64 timer_latency; /* timer_latency */
340-
unsigned int seqnum; /* unique sequence */
341-
int context; /* timer context */
342-
};
343-
#endif
344-
345318
/*
346319
* Tracer data.
347320
*/
@@ -497,7 +470,7 @@ static void print_osnoise_headers(struct seq_file *s)
497470
* Record an osnoise_sample into the tracer buffer.
498471
*/
499472
static void
500-
__trace_osnoise_sample(struct osnoise_sample *sample, struct trace_buffer *buffer)
473+
__record_osnoise_sample(struct osnoise_sample *sample, struct trace_buffer *buffer)
501474
{
502475
struct ring_buffer_event *event;
503476
struct osnoise_entry *entry;
@@ -520,17 +493,19 @@ __trace_osnoise_sample(struct osnoise_sample *sample, struct trace_buffer *buffe
520493
}
521494

522495
/*
523-
* Record an osnoise_sample on all osnoise instances.
496+
* Record an osnoise_sample on all osnoise instances and fire trace event.
524497
*/
525-
static void trace_osnoise_sample(struct osnoise_sample *sample)
498+
static void record_osnoise_sample(struct osnoise_sample *sample)
526499
{
527500
struct osnoise_instance *inst;
528501
struct trace_buffer *buffer;
529502

503+
trace_osnoise_sample(sample);
504+
530505
rcu_read_lock();
531506
list_for_each_entry_rcu(inst, &osnoise_instances, list) {
532507
buffer = inst->tr->array_buffer.buffer;
533-
__trace_osnoise_sample(sample, buffer);
508+
__record_osnoise_sample(sample, buffer);
534509
}
535510
rcu_read_unlock();
536511
}
@@ -574,7 +549,7 @@ static void print_timerlat_headers(struct seq_file *s)
574549
#endif /* CONFIG_PREEMPT_RT */
575550

576551
static void
577-
__trace_timerlat_sample(struct timerlat_sample *sample, struct trace_buffer *buffer)
552+
__record_timerlat_sample(struct timerlat_sample *sample, struct trace_buffer *buffer)
578553
{
579554
struct ring_buffer_event *event;
580555
struct timerlat_entry *entry;
@@ -594,15 +569,17 @@ __trace_timerlat_sample(struct timerlat_sample *sample, struct trace_buffer *buf
594569
/*
595570
* Record an timerlat_sample into the tracer buffer.
596571
*/
597-
static void trace_timerlat_sample(struct timerlat_sample *sample)
572+
static void record_timerlat_sample(struct timerlat_sample *sample)
598573
{
599574
struct osnoise_instance *inst;
600575
struct trace_buffer *buffer;
601576

577+
trace_timerlat_sample(sample);
578+
602579
rcu_read_lock();
603580
list_for_each_entry_rcu(inst, &osnoise_instances, list) {
604581
buffer = inst->tr->array_buffer.buffer;
605-
__trace_timerlat_sample(sample, buffer);
582+
__record_timerlat_sample(sample, buffer);
606583
}
607584
rcu_read_unlock();
608585
}
@@ -1608,7 +1585,7 @@ static int run_osnoise(void)
16081585
/* Save interference stats info */
16091586
diff_osn_sample_stats(osn_var, &s);
16101587

1611-
trace_osnoise_sample(&s);
1588+
record_osnoise_sample(&s);
16121589

16131590
notify_new_max_latency(max_noise);
16141591

@@ -1803,7 +1780,7 @@ static enum hrtimer_restart timerlat_irq(struct hrtimer *timer)
18031780
s.timer_latency = diff;
18041781
s.context = IRQ_CONTEXT;
18051782

1806-
trace_timerlat_sample(&s);
1783+
record_timerlat_sample(&s);
18071784

18081785
if (osnoise_data.stop_tracing) {
18091786
if (time_to_us(diff) >= osnoise_data.stop_tracing) {
@@ -1923,7 +1900,7 @@ static int timerlat_main(void *data)
19231900
s.timer_latency = diff;
19241901
s.context = THREAD_CONTEXT;
19251902

1926-
trace_timerlat_sample(&s);
1903+
record_timerlat_sample(&s);
19271904

19281905
notify_new_max_latency(diff);
19291906

@@ -2529,7 +2506,7 @@ timerlat_fd_read(struct file *file, char __user *ubuf, size_t count,
25292506
s.timer_latency = diff;
25302507
s.context = THREAD_URET;
25312508

2532-
trace_timerlat_sample(&s);
2509+
record_timerlat_sample(&s);
25332510

25342511
notify_new_max_latency(diff);
25352512

@@ -2564,7 +2541,7 @@ timerlat_fd_read(struct file *file, char __user *ubuf, size_t count,
25642541
s.timer_latency = diff;
25652542
s.context = THREAD_CONTEXT;
25662543

2567-
trace_timerlat_sample(&s);
2544+
record_timerlat_sample(&s);
25682545

25692546
if (osnoise_data.stop_tracing_total) {
25702547
if (time_to_us(diff) >= osnoise_data.stop_tracing_total) {

0 commit comments

Comments
 (0)