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