1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #undef TRACE_SYSTEM 3 #define TRACE_SYSTEM workqueue 4 5 #if !defined(_TRACE_WORKQUEUE_H) || defined(TRACE_HEADER_MULTI_READ) 6 #define _TRACE_WORKQUEUE_H 7 8 #include <linux/tracepoint.h> 9 #include <linux/workqueue.h> 10 11 struct pool_workqueue; 12 struct worker_pool; 13 14 /** 15 * workqueue_queue_work - called when a work gets queued 16 * @req_cpu: the requested cpu 17 * @pwq: pointer to struct pool_workqueue 18 * @work: pointer to struct work_struct 19 * 20 * This event occurs when a work is queued immediately or once a 21 * delayed work is actually queued on a workqueue (ie: once the delay 22 * has been reached). 23 */ 24 TRACE_EVENT(workqueue_queue_work, 25 26 TP_PROTO(int req_cpu, struct pool_workqueue *pwq, 27 struct work_struct *work), 28 29 TP_ARGS(req_cpu, pwq, work), 30 31 TP_STRUCT__entry( 32 __field( void *, work ) 33 __field( void *, function) 34 __string( workqueue, pwq->wq->name) 35 __field( int, req_cpu ) 36 __field( int, cpu ) 37 ), 38 39 TP_fast_assign( 40 __entry->work = work; 41 __entry->function = work->func; 42 __assign_str(workqueue); 43 __entry->req_cpu = req_cpu; 44 __entry->cpu = pwq->pool->cpu; 45 ), 46 47 TP_printk("work struct=%p function=%ps workqueue=%s req_cpu=%d cpu=%d", 48 __entry->work, __entry->function, __get_str(workqueue), 49 __entry->req_cpu, __entry->cpu) 50 ); 51 52 /** 53 * workqueue_activate_work - called when a work gets activated 54 * @work: pointer to struct work_struct 55 * 56 * This event occurs when a queued work is put on the active queue, 57 * which happens immediately after queueing unless @max_active limit 58 * is reached. 59 */ 60 TRACE_EVENT(workqueue_activate_work, 61 62 TP_PROTO(struct work_struct *work), 63 64 TP_ARGS(work), 65 66 TP_STRUCT__entry( 67 __field( void *, work ) 68 __field( void *, function) 69 ), 70 71 TP_fast_assign( 72 __entry->work = work; 73 __entry->function = work->func; 74 ), 75 76 TP_printk("work struct %p function=%ps ", __entry->work, __entry->function) 77 ); 78 79 /** 80 * workqueue_execute_start - called immediately before the workqueue callback 81 * @work: pointer to struct work_struct 82 * 83 * Allows to track workqueue execution. 84 */ 85 TRACE_EVENT(workqueue_execute_start, 86 87 TP_PROTO(struct work_struct *work), 88 89 TP_ARGS(work), 90 91 TP_STRUCT__entry( 92 __field( void *, work ) 93 __field( void *, function) 94 ), 95 96 TP_fast_assign( 97 __entry->work = work; 98 __entry->function = work->func; 99 ), 100 101 TP_printk("work struct %p: function %ps", __entry->work, __entry->function) 102 ); 103 104 /** 105 * workqueue_execute_end - called immediately after the workqueue callback 106 * @work: pointer to struct work_struct 107 * @function: pointer to worker function 108 * 109 * Allows to track workqueue execution. 110 */ 111 TRACE_EVENT(workqueue_execute_end, 112 113 TP_PROTO(struct work_struct *work, work_func_t function), 114 115 TP_ARGS(work, function), 116 117 TP_STRUCT__entry( 118 __field( void *, work ) 119 __field( void *, function) 120 ), 121 122 TP_fast_assign( 123 __entry->work = work; 124 __entry->function = function; 125 ), 126 127 TP_printk("work struct %p: function %ps", __entry->work, __entry->function) 128 ); 129 130 /** 131 * workqueue_cpu_intensive - called when a work item exceeds cpu_intensive threshold 132 * @pwq: pointer to struct pool_workqueue 133 * @work: pointer to struct work_struct 134 * @function: pointer to worker function 135 * @duration_us: CPU time consumed in microseconds 136 * 137 * This event occurs when a concurrency-managed work item runs for longer 138 * than wq_cpu_intensive_thresh_us without sleeping and is excluded from 139 * concurrency management to prevent stalling other work items. 140 */ 141 TRACE_EVENT(workqueue_cpu_intensive, 142 143 TP_PROTO(struct pool_workqueue *pwq, struct work_struct *work, 144 work_func_t function, u64 duration_us), 145 146 TP_ARGS(pwq, work, function, duration_us), 147 148 TP_STRUCT__entry( 149 __field( void *, work ) 150 __field( void *, function ) 151 __string( workqueue, pwq->wq->name ) 152 __field( int, cpu ) 153 __field( u64, duration_us ) 154 ), 155 156 TP_fast_assign( 157 __entry->work = work; 158 __entry->function = function; 159 __assign_str(workqueue); 160 __entry->cpu = pwq->pool->cpu; 161 __entry->duration_us = duration_us; 162 ), 163 164 TP_printk("work struct=%p function=%ps workqueue=%s cpu=%d duration_us=%llu", 165 __entry->work, __entry->function, __get_str(workqueue), 166 __entry->cpu, __entry->duration_us) 167 ); 168 169 /** 170 * workqueue_mayday - called when a pool_workqueue sends mayday to rescuer 171 * @pwq: pointer to struct pool_workqueue 172 * 173 * This event occurs when a worker pool fails to create a new worker and 174 * requests the workqueue's rescuer thread to process pending works. 175 */ 176 TRACE_EVENT(workqueue_mayday, 177 178 TP_PROTO(struct pool_workqueue *pwq), 179 180 TP_ARGS(pwq), 181 182 TP_STRUCT__entry( 183 __string( workqueue, pwq->wq->name ) 184 __field( int, pool_id ) 185 __field( int, cpu ) 186 __field( int, nr_active ) 187 ), 188 189 TP_fast_assign( 190 __assign_str(workqueue); 191 __entry->pool_id = pwq->pool->id; 192 __entry->cpu = pwq->pool->cpu; 193 __entry->nr_active = pwq->nr_active; 194 ), 195 196 TP_printk("workqueue=%s pool_id=%d cpu=%d nr_active=%d", 197 __get_str(workqueue), __entry->pool_id, __entry->cpu, 198 __entry->nr_active) 199 ); 200 201 /** 202 * workqueue_rescued - called when a work item is assigned to a rescuer 203 * @pwq: pointer to struct pool_workqueue 204 * @work: pointer to struct work_struct 205 * @function: pointer to worker function 206 * 207 * This event occurs when a work item is claimed by a rescuer thread 208 * to guarantee forward progress. 209 */ 210 TRACE_EVENT(workqueue_rescued, 211 212 TP_PROTO(struct pool_workqueue *pwq, struct work_struct *work, 213 work_func_t function), 214 215 TP_ARGS(pwq, work, function), 216 217 TP_STRUCT__entry( 218 __field( void *, work ) 219 __field( void *, function ) 220 __string( workqueue, pwq->wq->name ) 221 __field( int, cpu ) 222 ), 223 224 TP_fast_assign( 225 __entry->work = work; 226 __entry->function = function; 227 __assign_str(workqueue); 228 __entry->cpu = pwq->pool->cpu; 229 ), 230 231 TP_printk("work struct=%p function=%ps workqueue=%s cpu=%d", 232 __entry->work, __entry->function, __get_str(workqueue), 233 __entry->cpu) 234 ); 235 236 /** 237 * workqueue_bh_budget_yield - called when a BH worker yields due to budget exhaustion 238 * @pool: pointer to struct worker_pool 239 * @restarts: number of restarts executed 240 * @timeout: whether execution hit the time limit (BH_WORKER_JIFFIES) 241 * @highpri: whether this is a high-priority BH pool 242 * 243 * This event occurs when a bottom-half (BH) worker pool running in softirq 244 * context exhausts its execution time slice or restart limit and must yield 245 * execution. 246 */ 247 TRACE_EVENT(workqueue_bh_budget_yield, 248 249 TP_PROTO(struct worker_pool *pool, int restarts, bool timeout, bool highpri), 250 251 TP_ARGS(pool, restarts, timeout, highpri), 252 253 TP_STRUCT__entry( 254 __field( int, pool_id ) 255 __field( int, cpu ) 256 __field( int, restarts ) 257 __field( bool, timeout ) 258 __field( bool, highpri ) 259 ), 260 261 TP_fast_assign( 262 __entry->pool_id = pool->id; 263 __entry->cpu = pool->cpu; 264 __entry->restarts = restarts; 265 __entry->timeout = timeout; 266 __entry->highpri = highpri; 267 ), 268 269 TP_printk("pool_id=%d cpu=%d restarts=%d timeout=%d highpri=%d", 270 __entry->pool_id, __entry->cpu, __entry->restarts, 271 __entry->timeout, __entry->highpri) 272 ); 273 274 #endif /* _TRACE_WORKQUEUE_H */ 275 276 /* This part must be outside protection */ 277 #include <trace/define_trace.h> 278 279