Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf kwork: Add softirq trace BPF support

Implements softirq trace bpf function.

Test cases:
Trace softirq latency without filter:

# perf kwork -k softirq lat -b
Starting trace, Hit <Ctrl+C> to stop and report
^C
Kwork Name | Cpu | Avg delay | Count | Max delay | Max delay start | Max delay end |
--------------------------------------------------------------------------------------------------------------------------------
(s)RCU:9 | 0005 | 0.281 ms | 3 | 0.338 ms | 111295.752222 s | 111295.752560 s |
(s)RCU:9 | 0002 | 0.262 ms | 24 | 1.400 ms | 111301.335986 s | 111301.337386 s |
(s)SCHED:7 | 0005 | 0.177 ms | 14 | 0.212 ms | 111295.752270 s | 111295.752481 s |
(s)RCU:9 | 0007 | 0.161 ms | 47 | 2.022 ms | 111295.402159 s | 111295.404181 s |
(s)NET_RX:3 | 0003 | 0.149 ms | 12 | 1.261 ms | 111301.192964 s | 111301.194225 s |
(s)TIMER:1 | 0001 | 0.105 ms | 9 | 0.198 ms | 111301.180191 s | 111301.180389 s |
... <SNIP> ...
(s)NET_RX:3 | 0002 | 0.098 ms | 6 | 0.124 ms | 111295.403760 s | 111295.403884 s |
(s)SCHED:7 | 0001 | 0.093 ms | 19 | 0.242 ms | 111301.180256 s | 111301.180498 s |
(s)SCHED:7 | 0007 | 0.078 ms | 15 | 0.188 ms | 111300.064226 s | 111300.064415 s |
(s)SCHED:7 | 0004 | 0.077 ms | 11 | 0.213 ms | 111301.361759 s | 111301.361973 s |
(s)SCHED:7 | 0000 | 0.063 ms | 33 | 0.805 ms | 111295.401811 s | 111295.402616 s |
(s)SCHED:7 | 0003 | 0.063 ms | 14 | 0.085 ms | 111301.192255 s | 111301.192340 s |
--------------------------------------------------------------------------------------------------------------------------------

Trace softirq latency with cpu filter:

# perf kwork -k softirq lat -b -C 1
Starting trace, Hit <Ctrl+C> to stop and report
^C
Kwork Name | Cpu | Avg delay | Count | Max delay | Max delay start | Max delay end |
--------------------------------------------------------------------------------------------------------------------------------
(s)RCU:9 | 0001 | 0.178 ms | 5 | 0.572 ms | 111435.534135 s | 111435.534707 s |
--------------------------------------------------------------------------------------------------------------------------------

Trace softirq latency with name filter:

# perf kwork -k softirq lat -b -n SCHED
Starting trace, Hit <Ctrl+C> to stop and report
^C
Kwork Name | Cpu | Avg delay | Count | Max delay | Max delay start | Max delay end |
--------------------------------------------------------------------------------------------------------------------------------
(s)SCHED:7 | 0001 | 0.295 ms | 15 | 2.183 ms | 111452.534950 s | 111452.537133 s |
(s)SCHED:7 | 0002 | 0.215 ms | 10 | 0.315 ms | 111460.000238 s | 111460.000553 s |
(s)SCHED:7 | 0005 | 0.190 ms | 29 | 0.338 ms | 111457.032538 s | 111457.032876 s |
(s)SCHED:7 | 0003 | 0.097 ms | 10 | 0.319 ms | 111452.434351 s | 111452.434670 s |
(s)SCHED:7 | 0006 | 0.089 ms | 1 | 0.089 ms | 111450.737450 s | 111450.737539 s |
(s)SCHED:7 | 0007 | 0.085 ms | 17 | 0.169 ms | 111452.471333 s | 111452.471502 s |
(s)SCHED:7 | 0004 | 0.071 ms | 15 | 0.221 ms | 111452.535252 s | 111452.535473 s |
(s)SCHED:7 | 0000 | 0.044 ms | 32 | 0.130 ms | 111460.001982 s | 111460.002112 s |
--------------------------------------------------------------------------------------------------------------------------------

Signed-off-by: Yang Jihong <yangjihong1@huawei.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Clarke <pc@us.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20220709015033.38326-17-yangjihong1@huawei.com
[ Add {} for multiline if blocks ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Yang Jihong and committed by
Arnaldo Carvalho de Melo
5a81927a 420298ae

+92 -1
+17 -1
tools/perf/util/bpf_kwork.c
··· 98 98 .get_work_name = get_work_name_from_map, 99 99 }; 100 100 101 + static void softirq_load_prepare(struct perf_kwork *kwork) 102 + { 103 + if (kwork->report == KWORK_REPORT_RUNTIME) { 104 + bpf_program__set_autoload(skel->progs.report_softirq_entry, true); 105 + bpf_program__set_autoload(skel->progs.report_softirq_exit, true); 106 + } else if (kwork->report == KWORK_REPORT_LATENCY) { 107 + bpf_program__set_autoload(skel->progs.latency_softirq_raise, true); 108 + bpf_program__set_autoload(skel->progs.latency_softirq_entry, true); 109 + } 110 + } 111 + 112 + static struct kwork_class_bpf kwork_softirq_bpf = { 113 + .load_prepare = softirq_load_prepare, 114 + .get_work_name = get_work_name_from_map, 115 + }; 116 + 101 117 static struct kwork_class_bpf * 102 118 kwork_class_bpf_supported_list[KWORK_CLASS_MAX] = { 103 119 [KWORK_CLASS_IRQ] = &kwork_irq_bpf, 104 - [KWORK_CLASS_SOFTIRQ] = NULL, 120 + [KWORK_CLASS_SOFTIRQ] = &kwork_softirq_bpf, 105 121 [KWORK_CLASS_WORKQUEUE] = NULL, 106 122 }; 107 123
+75
tools/perf/util/bpf_skel/kwork_trace.bpf.c
··· 221 221 return update_timeend(&perf_kwork_report, &perf_kwork_time, &key); 222 222 } 223 223 224 + static char softirq_name_list[NR_SOFTIRQS][MAX_KWORKNAME] = { 225 + { "HI" }, 226 + { "TIMER" }, 227 + { "NET_TX" }, 228 + { "NET_RX" }, 229 + { "BLOCK" }, 230 + { "IRQ_POLL" }, 231 + { "TASKLET" }, 232 + { "SCHED" }, 233 + { "HRTIMER" }, 234 + { "RCU" }, 235 + }; 236 + 237 + SEC("tracepoint/irq/softirq_entry") 238 + int report_softirq_entry(struct trace_event_raw_softirq *ctx) 239 + { 240 + unsigned int vec = ctx->vec; 241 + struct work_key key = { 242 + .type = KWORK_CLASS_SOFTIRQ, 243 + .cpu = bpf_get_smp_processor_id(), 244 + .id = (__u64)vec, 245 + }; 246 + 247 + if (vec < NR_SOFTIRQS) { 248 + return update_timestart_and_name(&perf_kwork_time, 249 + &perf_kwork_names, &key, 250 + softirq_name_list[vec]); 251 + } 252 + 253 + return 0; 254 + } 255 + 256 + SEC("tracepoint/irq/softirq_exit") 257 + int report_softirq_exit(struct trace_event_raw_softirq *ctx) 258 + { 259 + struct work_key key = { 260 + .type = KWORK_CLASS_SOFTIRQ, 261 + .cpu = bpf_get_smp_processor_id(), 262 + .id = (__u64)ctx->vec, 263 + }; 264 + 265 + return update_timeend(&perf_kwork_report, &perf_kwork_time, &key); 266 + } 267 + 268 + SEC("tracepoint/irq/softirq_raise") 269 + int latency_softirq_raise(struct trace_event_raw_softirq *ctx) 270 + { 271 + unsigned int vec = ctx->vec; 272 + struct work_key key = { 273 + .type = KWORK_CLASS_SOFTIRQ, 274 + .cpu = bpf_get_smp_processor_id(), 275 + .id = (__u64)vec, 276 + }; 277 + 278 + if (vec < NR_SOFTIRQS) { 279 + return update_timestart_and_name(&perf_kwork_time, 280 + &perf_kwork_names, &key, 281 + softirq_name_list[vec]); 282 + } 283 + 284 + return 0; 285 + } 286 + 287 + SEC("tracepoint/irq/softirq_entry") 288 + int latency_softirq_entry(struct trace_event_raw_softirq *ctx) 289 + { 290 + struct work_key key = { 291 + .type = KWORK_CLASS_SOFTIRQ, 292 + .cpu = bpf_get_smp_processor_id(), 293 + .id = (__u64)ctx->vec, 294 + }; 295 + 296 + return update_timeend(&perf_kwork_report, &perf_kwork_time, &key); 297 + } 298 + 224 299 char LICENSE[] SEC("license") = "Dual BSD/GPL";