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

irq: Add tracepoint to softirq_raise

Add a tracepoint for tracing when softirq action is raised.

This and the existing tracepoints complete softirq's tracepoints:
softirq_raise, softirq_entry and softirq_exit.

And when this tracepoint is used in combination with
the softirq_entry tracepoint we can determine
the softirq raise latency.

Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Acked-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Cc: David Miller <davem@davemloft.net>
Cc: Kaneshige Kenji <kaneshige.kenji@jp.fujitsu.com>
Cc: Izumo Taku <izumi.taku@jp.fujitsu.com>
Cc: Kosaki Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Lai Jiangshan <laijs@cn.fujitsu.com>
Cc: Scott Mcmillan <scott.a.mcmillan@intel.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
LKML-Reference: <4C724298.4050509@jp.fujitsu.com>
[ factorize softirq events with DECLARE_EVENT_CLASS ]
Signed-off-by: Koki Sanagi <sanagi.koki@jp.fujitsu.com>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>

authored by

Lai Jiangshan and committed by
Frederic Weisbecker
2bf2160d f6195aa0

+31 -3
+7 -1
include/linux/interrupt.h
··· 18 18 #include <asm/atomic.h> 19 19 #include <asm/ptrace.h> 20 20 #include <asm/system.h> 21 + #include <trace/events/irq.h> 21 22 22 23 /* 23 24 * These correspond to the IORESOURCE_IRQ_* defines in ··· 408 407 asmlinkage void __do_softirq(void); 409 408 extern void open_softirq(int nr, void (*action)(struct softirq_action *)); 410 409 extern void softirq_init(void); 411 - #define __raise_softirq_irqoff(nr) do { or_softirq_pending(1UL << (nr)); } while (0) 410 + static inline void __raise_softirq_irqoff(unsigned int nr) 411 + { 412 + trace_softirq_raise((struct softirq_action *)(unsigned long)nr, NULL); 413 + or_softirq_pending(1UL << nr); 414 + } 415 + 412 416 extern void raise_softirq_irqoff(unsigned int nr); 413 417 extern void raise_softirq(unsigned int nr); 414 418 extern void wakeup_softirqd(void);
+24 -2
include/trace/events/irq.h
··· 5 5 #define _TRACE_IRQ_H 6 6 7 7 #include <linux/tracepoint.h> 8 - #include <linux/interrupt.h> 8 + 9 + struct irqaction; 10 + struct softirq_action; 9 11 10 12 #define softirq_name(sirq) { sirq##_SOFTIRQ, #sirq } 11 13 #define show_softirq_name(val) \ ··· 95 93 ), 96 94 97 95 TP_fast_assign( 98 - __entry->vec = (int)(h - vec); 96 + if (vec) 97 + __entry->vec = (int)(h - vec); 98 + else 99 + __entry->vec = (int)(long)h; 99 100 ), 100 101 101 102 TP_printk("vec=%d [action=%s]", __entry->vec, ··· 135 130 * latency. 136 131 */ 137 132 DEFINE_EVENT(softirq, softirq_exit, 133 + 134 + TP_PROTO(struct softirq_action *h, struct softirq_action *vec), 135 + 136 + TP_ARGS(h, vec) 137 + ); 138 + 139 + /** 140 + * softirq_raise - called immediately when a softirq is raised 141 + * @h: pointer to struct softirq_action 142 + * @vec: pointer to first struct softirq_action in softirq_vec array 143 + * 144 + * The @h parameter contains a pointer to the softirq vector number which is 145 + * raised. @vec is NULL and it means @h includes vector number not 146 + * softirq_action. When used in combination with the softirq_entry tracepoint 147 + * we can determine the softirq raise latency. 148 + */ 149 + DEFINE_EVENT(softirq, softirq_raise, 138 150 139 151 TP_PROTO(struct softirq_action *h, struct softirq_action *vec), 140 152