at v2.6.30 266 lines 8.0 kB view raw
1#ifndef _LINUX_TRACEPOINT_H 2#define _LINUX_TRACEPOINT_H 3 4/* 5 * Kernel Tracepoint API. 6 * 7 * See Documentation/tracepoint.txt. 8 * 9 * (C) Copyright 2008 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> 10 * 11 * Heavily inspired from the Linux Kernel Markers. 12 * 13 * This file is released under the GPLv2. 14 * See the file COPYING for more details. 15 */ 16 17#include <linux/types.h> 18#include <linux/rcupdate.h> 19 20struct module; 21struct tracepoint; 22 23struct tracepoint { 24 const char *name; /* Tracepoint name */ 25 int state; /* State. */ 26 void **funcs; 27} __attribute__((aligned(32))); /* 28 * Aligned on 32 bytes because it is 29 * globally visible and gcc happily 30 * align these on the structure size. 31 * Keep in sync with vmlinux.lds.h. 32 */ 33 34#define TP_PROTO(args...) args 35#define TP_ARGS(args...) args 36 37#ifdef CONFIG_TRACEPOINTS 38 39/* 40 * it_func[0] is never NULL because there is at least one element in the array 41 * when the array itself is non NULL. 42 */ 43#define __DO_TRACE(tp, proto, args) \ 44 do { \ 45 void **it_func; \ 46 \ 47 rcu_read_lock_sched_notrace(); \ 48 it_func = rcu_dereference((tp)->funcs); \ 49 if (it_func) { \ 50 do { \ 51 ((void(*)(proto))(*it_func))(args); \ 52 } while (*(++it_func)); \ 53 } \ 54 rcu_read_unlock_sched_notrace(); \ 55 } while (0) 56 57/* 58 * Make sure the alignment of the structure in the __tracepoints section will 59 * not add unwanted padding between the beginning of the section and the 60 * structure. Force alignment to the same alignment as the section start. 61 */ 62#define DECLARE_TRACE(name, proto, args) \ 63 extern struct tracepoint __tracepoint_##name; \ 64 static inline void trace_##name(proto) \ 65 { \ 66 if (unlikely(__tracepoint_##name.state)) \ 67 __DO_TRACE(&__tracepoint_##name, \ 68 TP_PROTO(proto), TP_ARGS(args)); \ 69 } \ 70 static inline int register_trace_##name(void (*probe)(proto)) \ 71 { \ 72 return tracepoint_probe_register(#name, (void *)probe); \ 73 } \ 74 static inline int unregister_trace_##name(void (*probe)(proto)) \ 75 { \ 76 return tracepoint_probe_unregister(#name, (void *)probe);\ 77 } 78 79#define DEFINE_TRACE(name) \ 80 static const char __tpstrtab_##name[] \ 81 __attribute__((section("__tracepoints_strings"))) = #name; \ 82 struct tracepoint __tracepoint_##name \ 83 __attribute__((section("__tracepoints"), aligned(32))) = \ 84 { __tpstrtab_##name, 0, NULL } 85 86#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) \ 87 EXPORT_SYMBOL_GPL(__tracepoint_##name) 88#define EXPORT_TRACEPOINT_SYMBOL(name) \ 89 EXPORT_SYMBOL(__tracepoint_##name) 90 91extern void tracepoint_update_probe_range(struct tracepoint *begin, 92 struct tracepoint *end); 93 94#else /* !CONFIG_TRACEPOINTS */ 95#define DECLARE_TRACE(name, proto, args) \ 96 static inline void _do_trace_##name(struct tracepoint *tp, proto) \ 97 { } \ 98 static inline void trace_##name(proto) \ 99 { } \ 100 static inline int register_trace_##name(void (*probe)(proto)) \ 101 { \ 102 return -ENOSYS; \ 103 } \ 104 static inline int unregister_trace_##name(void (*probe)(proto)) \ 105 { \ 106 return -ENOSYS; \ 107 } 108 109#define DEFINE_TRACE(name) 110#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) 111#define EXPORT_TRACEPOINT_SYMBOL(name) 112 113static inline void tracepoint_update_probe_range(struct tracepoint *begin, 114 struct tracepoint *end) 115{ } 116#endif /* CONFIG_TRACEPOINTS */ 117 118/* 119 * Connect a probe to a tracepoint. 120 * Internal API, should not be used directly. 121 */ 122extern int tracepoint_probe_register(const char *name, void *probe); 123 124/* 125 * Disconnect a probe from a tracepoint. 126 * Internal API, should not be used directly. 127 */ 128extern int tracepoint_probe_unregister(const char *name, void *probe); 129 130extern int tracepoint_probe_register_noupdate(const char *name, void *probe); 131extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe); 132extern void tracepoint_probe_update_all(void); 133 134struct tracepoint_iter { 135 struct module *module; 136 struct tracepoint *tracepoint; 137}; 138 139extern void tracepoint_iter_start(struct tracepoint_iter *iter); 140extern void tracepoint_iter_next(struct tracepoint_iter *iter); 141extern void tracepoint_iter_stop(struct tracepoint_iter *iter); 142extern void tracepoint_iter_reset(struct tracepoint_iter *iter); 143extern int tracepoint_get_iter_range(struct tracepoint **tracepoint, 144 struct tracepoint *begin, struct tracepoint *end); 145 146/* 147 * tracepoint_synchronize_unregister must be called between the last tracepoint 148 * probe unregistration and the end of module exit to make sure there is no 149 * caller executing a probe when it is freed. 150 */ 151static inline void tracepoint_synchronize_unregister(void) 152{ 153 synchronize_sched(); 154} 155 156#define PARAMS(args...) args 157#define TRACE_FORMAT(name, proto, args, fmt) \ 158 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) 159 160 161/* 162 * For use with the TRACE_EVENT macro: 163 * 164 * We define a tracepoint, its arguments, its printk format 165 * and its 'fast binay record' layout. 166 * 167 * Firstly, name your tracepoint via TRACE_EVENT(name : the 168 * 'subsystem_event' notation is fine. 169 * 170 * Think about this whole construct as the 171 * 'trace_sched_switch() function' from now on. 172 * 173 * 174 * TRACE_EVENT(sched_switch, 175 * 176 * * 177 * * A function has a regular function arguments 178 * * prototype, declare it via TP_PROTO(): 179 * * 180 * 181 * TP_PROTO(struct rq *rq, struct task_struct *prev, 182 * struct task_struct *next), 183 * 184 * * 185 * * Define the call signature of the 'function'. 186 * * (Design sidenote: we use this instead of a 187 * * TP_PROTO1/TP_PROTO2/TP_PROTO3 ugliness.) 188 * * 189 * 190 * TP_ARGS(rq, prev, next), 191 * 192 * * 193 * * Fast binary tracing: define the trace record via 194 * * TP_STRUCT__entry(). You can think about it like a 195 * * regular C structure local variable definition. 196 * * 197 * * This is how the trace record is structured and will 198 * * be saved into the ring buffer. These are the fields 199 * * that will be exposed to user-space in 200 * * /debug/tracing/events/<*>/format. 201 * * 202 * * The declared 'local variable' is called '__entry' 203 * * 204 * * __field(pid_t, prev_prid) is equivalent to a standard declariton: 205 * * 206 * * pid_t prev_pid; 207 * * 208 * * __array(char, prev_comm, TASK_COMM_LEN) is equivalent to: 209 * * 210 * * char prev_comm[TASK_COMM_LEN]; 211 * * 212 * 213 * TP_STRUCT__entry( 214 * __array( char, prev_comm, TASK_COMM_LEN ) 215 * __field( pid_t, prev_pid ) 216 * __field( int, prev_prio ) 217 * __array( char, next_comm, TASK_COMM_LEN ) 218 * __field( pid_t, next_pid ) 219 * __field( int, next_prio ) 220 * ), 221 * 222 * * 223 * * Assign the entry into the trace record, by embedding 224 * * a full C statement block into TP_fast_assign(). You 225 * * can refer to the trace record as '__entry' - 226 * * otherwise you can put arbitrary C code in here. 227 * * 228 * * Note: this C code will execute every time a trace event 229 * * happens, on an active tracepoint. 230 * * 231 * 232 * TP_fast_assign( 233 * memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN); 234 * __entry->prev_pid = prev->pid; 235 * __entry->prev_prio = prev->prio; 236 * memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN); 237 * __entry->next_pid = next->pid; 238 * __entry->next_prio = next->prio; 239 * ) 240 * 241 * * 242 * * Formatted output of a trace record via TP_printk(). 243 * * This is how the tracepoint will appear under ftrace 244 * * plugins that make use of this tracepoint. 245 * * 246 * * (raw-binary tracing wont actually perform this step.) 247 * * 248 * 249 * TP_printk("task %s:%d [%d] ==> %s:%d [%d]", 250 * __entry->prev_comm, __entry->prev_pid, __entry->prev_prio, 251 * __entry->next_comm, __entry->next_pid, __entry->next_prio), 252 * 253 * ); 254 * 255 * This macro construct is thus used for the regular printk format 256 * tracing setup, it is used to construct a function pointer based 257 * tracepoint callback (this is used by programmatic plugins and 258 * can also by used by generic instrumentation like SystemTap), and 259 * it is also used to expose a structured trace record in 260 * /debug/tracing/events/. 261 */ 262 263#define TRACE_EVENT(name, proto, args, struct, assign, print) \ 264 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) 265 266#endif