1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #undef TRACE_SYSTEM 3 #define TRACE_SYSTEM irq 4 5 #if !defined(_TRACE_IRQ_H) || defined(TRACE_HEADER_MULTI_READ) 6 #define _TRACE_IRQ_H 7 8 #include <linux/tracepoint.h> 9 10 struct irqaction; 11 struct softirq_action; 12 13 #define SOFTIRQ_NAME_LIST \ 14 softirq_name(HI) \ 15 softirq_name(TIMER) \ 16 softirq_name(NET_TX) \ 17 softirq_name(NET_RX) \ 18 softirq_name(BLOCK) \ 19 softirq_name(IRQ_POLL) \ 20 softirq_name(TASKLET) \ 21 softirq_name(SCHED) \ 22 softirq_name(HRTIMER) \ 23 softirq_name_end(RCU) 24 25 #undef softirq_name 26 #undef softirq_name_end 27 28 #define softirq_name(sirq) TRACE_DEFINE_ENUM(sirq##_SOFTIRQ); 29 #define softirq_name_end(sirq) TRACE_DEFINE_ENUM(sirq##_SOFTIRQ); 30 31 SOFTIRQ_NAME_LIST 32 33 #undef softirq_name 34 #undef softirq_name_end 35 36 #define softirq_name(sirq) { sirq##_SOFTIRQ, #sirq }, 37 #define softirq_name_end(sirq) { sirq##_SOFTIRQ, #sirq } 38 39 #define show_softirq_name(val) \ 40 __print_symbolic(val, SOFTIRQ_NAME_LIST) 41 42 /** 43 * irq_handler_entry - called immediately before the irq action handler 44 * @irq: irq number 45 * @action: pointer to struct irqaction 46 * 47 * The struct irqaction pointed to by @action contains various 48 * information about the handler, including the device name, 49 * @action->name, and the device id, @action->dev_id. When used in 50 * conjunction with the irq_handler_exit tracepoint, we can figure 51 * out irq handler latencies. 52 */ 53 TRACE_EVENT(irq_handler_entry, 54 55 TP_PROTO(int irq, struct irqaction *action), 56 57 TP_ARGS(irq, action), 58 59 TP_STRUCT__entry( 60 __field( int, irq ) 61 __string( name, action->name ) 62 ), 63 64 TP_fast_assign( 65 __entry->irq = irq; 66 __assign_str(name, action->name); 67 ), 68 69 TP_printk("irq=%d name=%s", __entry->irq, __get_str(name)) 70 ); 71 72 /** 73 * irq_handler_exit - called immediately after the irq action handler returns 74 * @irq: irq number 75 * @action: pointer to struct irqaction 76 * @ret: return value 77 * 78 * If the @ret value is set to IRQ_HANDLED, then we know that the corresponding 79 * @action->handler successfully handled this irq. Otherwise, the irq might be 80 * a shared irq line, or the irq was not handled successfully. Can be used in 81 * conjunction with the irq_handler_entry to understand irq handler latencies. 82 */ 83 TRACE_EVENT(irq_handler_exit, 84 85 TP_PROTO(int irq, struct irqaction *action, int ret), 86 87 TP_ARGS(irq, action, ret), 88 89 TP_STRUCT__entry( 90 __field( int, irq ) 91 __field( int, ret ) 92 ), 93 94 TP_fast_assign( 95 __entry->irq = irq; 96 __entry->ret = ret; 97 ), 98 99 TP_printk("irq=%d ret=%s", 100 __entry->irq, __entry->ret ? "handled" : "unhandled") 101 ); 102 103 DECLARE_EVENT_CLASS(softirq, 104 105 TP_PROTO(unsigned int vec_nr), 106 107 TP_ARGS(vec_nr), 108 109 TP_STRUCT__entry( 110 __field( unsigned int, vec ) 111 ), 112 113 TP_fast_assign( 114 __entry->vec = vec_nr; 115 ), 116 117 TP_printk("vec=%u [action=%s]", __entry->vec, 118 show_softirq_name(__entry->vec)) 119 ); 120 121 /** 122 * softirq_entry - called immediately before the softirq handler 123 * @vec_nr: softirq vector number 124 * 125 * When used in combination with the softirq_exit tracepoint 126 * we can determine the softirq handler routine. 127 */ 128 DEFINE_EVENT(softirq, softirq_entry, 129 130 TP_PROTO(unsigned int vec_nr), 131 132 TP_ARGS(vec_nr) 133 ); 134 135 /** 136 * softirq_exit - called immediately after the softirq handler returns 137 * @vec_nr: softirq vector number 138 * 139 * When used in combination with the softirq_entry tracepoint 140 * we can determine the softirq handler routine. 141 */ 142 DEFINE_EVENT(softirq, softirq_exit, 143 144 TP_PROTO(unsigned int vec_nr), 145 146 TP_ARGS(vec_nr) 147 ); 148 149 /** 150 * softirq_raise - called immediately when a softirq is raised 151 * @vec_nr: softirq vector number 152 * 153 * When used in combination with the softirq_entry tracepoint 154 * we can determine the softirq raise to run latency. 155 */ 156 DEFINE_EVENT(softirq, softirq_raise, 157 158 TP_PROTO(unsigned int vec_nr), 159 160 TP_ARGS(vec_nr) 161 ); 162 163 DECLARE_EVENT_CLASS(tasklet, 164 165 TP_PROTO(struct tasklet_struct *t, void *func), 166 167 TP_ARGS(t, func), 168 169 TP_STRUCT__entry( 170 __field( void *, tasklet) 171 __field( void *, func) 172 ), 173 174 TP_fast_assign( 175 __entry->tasklet = t; 176 __entry->func = func; 177 ), 178 179 TP_printk("tasklet=%ps function=%ps", __entry->tasklet, __entry->func) 180 ); 181 182 /** 183 * tasklet_entry - called immediately before the tasklet is run 184 * @t: tasklet pointer 185 * @func: tasklet callback or function being run 186 * 187 * Used to find individual tasklet execution time 188 */ 189 DEFINE_EVENT(tasklet, tasklet_entry, 190 191 TP_PROTO(struct tasklet_struct *t, void *func), 192 193 TP_ARGS(t, func) 194 ); 195 196 /** 197 * tasklet_exit - called immediately after the tasklet is run 198 * @t: tasklet pointer 199 * @func: tasklet callback or function being run 200 * 201 * Used to find individual tasklet execution time 202 */ 203 DEFINE_EVENT(tasklet, tasklet_exit, 204 205 TP_PROTO(struct tasklet_struct *t, void *func), 206 207 TP_ARGS(t, func) 208 ); 209 210 #endif /* _TRACE_IRQ_H */ 211 212 /* This part must be outside protection */ 213 #include <trace/define_trace.h> 214