diff options
| -rw-r--r-- | arch/powerpc/platforms/cell/spufs/sputrace.c | 31 | ||||
| -rw-r--r-- | include/linux/marker.h | 59 | ||||
| -rw-r--r-- | include/linux/module.h | 2 | ||||
| -rw-r--r-- | kernel/marker.c | 677 | ||||
| -rw-r--r-- | kernel/module.c | 7 | ||||
| -rw-r--r-- | samples/markers/probe-example.c | 25 |
6 files changed, 565 insertions, 236 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/sputrace.c b/arch/powerpc/platforms/cell/spufs/sputrace.c index 2b1953f6f12e..01974f7776e1 100644 --- a/arch/powerpc/platforms/cell/spufs/sputrace.c +++ b/arch/powerpc/platforms/cell/spufs/sputrace.c | |||
| @@ -146,34 +146,28 @@ static void sputrace_log_item(const char *name, struct spu_context *ctx, | |||
| 146 | wake_up(&sputrace_wait); | 146 | wake_up(&sputrace_wait); |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | static void spu_context_event(const struct marker *mdata, | 149 | static void spu_context_event(void *probe_private, void *call_data, |
| 150 | void *private, const char *format, ...) | 150 | const char *format, va_list *args) |
| 151 | { | 151 | { |
| 152 | struct spu_probe *p = mdata->private; | 152 | struct spu_probe *p = probe_private; |
| 153 | va_list ap; | ||
| 154 | struct spu_context *ctx; | 153 | struct spu_context *ctx; |
| 155 | struct spu *spu; | 154 | struct spu *spu; |
| 156 | 155 | ||
| 157 | va_start(ap, format); | 156 | ctx = va_arg(*args, struct spu_context *); |
| 158 | ctx = va_arg(ap, struct spu_context *); | 157 | spu = va_arg(*args, struct spu *); |
| 159 | spu = va_arg(ap, struct spu *); | ||
| 160 | 158 | ||
| 161 | sputrace_log_item(p->name, ctx, spu); | 159 | sputrace_log_item(p->name, ctx, spu); |
| 162 | va_end(ap); | ||
| 163 | } | 160 | } |
| 164 | 161 | ||
| 165 | static void spu_context_nospu_event(const struct marker *mdata, | 162 | static void spu_context_nospu_event(void *probe_private, void *call_data, |
| 166 | void *private, const char *format, ...) | 163 | const char *format, va_list *args) |
| 167 | { | 164 | { |
| 168 | struct spu_probe *p = mdata->private; | 165 | struct spu_probe *p = probe_private; |
| 169 | va_list ap; | ||
| 170 | struct spu_context *ctx; | 166 | struct spu_context *ctx; |
| 171 | 167 | ||
| 172 | va_start(ap, format); | 168 | ctx = va_arg(*args, struct spu_context *); |
| 173 | ctx = va_arg(ap, struct spu_context *); | ||
| 174 | 169 | ||
| 175 | sputrace_log_item(p->name, ctx, NULL); | 170 | sputrace_log_item(p->name, ctx, NULL); |
| 176 | va_end(ap); | ||
| 177 | } | 171 | } |
| 178 | 172 | ||
| 179 | struct spu_probe spu_probes[] = { | 173 | struct spu_probe spu_probes[] = { |
| @@ -219,10 +213,6 @@ static int __init sputrace_init(void) | |||
| 219 | if (error) | 213 | if (error) |
| 220 | printk(KERN_INFO "Unable to register probe %s\n", | 214 | printk(KERN_INFO "Unable to register probe %s\n", |
| 221 | p->name); | 215 | p->name); |
| 222 | |||
| 223 | error = marker_arm(p->name); | ||
| 224 | if (error) | ||
| 225 | printk(KERN_INFO "Unable to arm probe %s\n", p->name); | ||
| 226 | } | 216 | } |
| 227 | 217 | ||
| 228 | return 0; | 218 | return 0; |
| @@ -238,7 +228,8 @@ static void __exit sputrace_exit(void) | |||
| 238 | int i; | 228 | int i; |
| 239 | 229 | ||
| 240 | for (i = 0; i < ARRAY_SIZE(spu_probes); i++) | 230 | for (i = 0; i < ARRAY_SIZE(spu_probes); i++) |
| 241 | marker_probe_unregister(spu_probes[i].name); | 231 | marker_probe_unregister(spu_probes[i].name, |
| 232 | spu_probes[i].probe_func, &spu_probes[i]); | ||
| 242 | 233 | ||
| 243 | remove_proc_entry("sputrace", NULL); | 234 | remove_proc_entry("sputrace", NULL); |
| 244 | kfree(sputrace_log); | 235 | kfree(sputrace_log); |
diff --git a/include/linux/marker.h b/include/linux/marker.h index 5f36cf946bcb..b5f95637f289 100644 --- a/include/linux/marker.h +++ b/include/linux/marker.h | |||
| @@ -19,16 +19,23 @@ struct marker; | |||
| 19 | 19 | ||
| 20 | /** | 20 | /** |
| 21 | * marker_probe_func - Type of a marker probe function | 21 | * marker_probe_func - Type of a marker probe function |
| 22 | * @mdata: pointer of type struct marker | 22 | * @probe_private: probe private data |
| 23 | * @private_data: caller site private data | 23 | * @call_private: call site private data |
| 24 | * @fmt: format string | 24 | * @fmt: format string |
| 25 | * @...: variable argument list | 25 | * @args: variable argument list pointer. Use a pointer to overcome C's |
| 26 | * inability to pass this around as a pointer in a portable manner in | ||
| 27 | * the callee otherwise. | ||
| 26 | * | 28 | * |
| 27 | * Type of marker probe functions. They receive the mdata and need to parse the | 29 | * Type of marker probe functions. They receive the mdata and need to parse the |
| 28 | * format string to recover the variable argument list. | 30 | * format string to recover the variable argument list. |
| 29 | */ | 31 | */ |
| 30 | typedef void marker_probe_func(const struct marker *mdata, | 32 | typedef void marker_probe_func(void *probe_private, void *call_private, |
| 31 | void *private_data, const char *fmt, ...); | 33 | const char *fmt, va_list *args); |
| 34 | |||
| 35 | struct marker_probe_closure { | ||
| 36 | marker_probe_func *func; /* Callback */ | ||
| 37 | void *probe_private; /* Private probe data */ | ||
| 38 | }; | ||
| 32 | 39 | ||
| 33 | struct marker { | 40 | struct marker { |
| 34 | const char *name; /* Marker name */ | 41 | const char *name; /* Marker name */ |
| @@ -36,8 +43,11 @@ struct marker { | |||
| 36 | * variable argument list. | 43 | * variable argument list. |
| 37 | */ | 44 | */ |
| 38 | char state; /* Marker state. */ | 45 | char state; /* Marker state. */ |
| 39 | marker_probe_func *call;/* Probe handler function pointer */ | 46 | char ptype; /* probe type : 0 : single, 1 : multi */ |
| 40 | void *private; /* Private probe data */ | 47 | void (*call)(const struct marker *mdata, /* Probe wrapper */ |
| 48 | void *call_private, const char *fmt, ...); | ||
| 49 | struct marker_probe_closure single; | ||
| 50 | struct marker_probe_closure *multi; | ||
| 41 | } __attribute__((aligned(8))); | 51 | } __attribute__((aligned(8))); |
| 42 | 52 | ||
| 43 | #ifdef CONFIG_MARKERS | 53 | #ifdef CONFIG_MARKERS |
| @@ -49,7 +59,7 @@ struct marker { | |||
| 49 | * not add unwanted padding between the beginning of the section and the | 59 | * not add unwanted padding between the beginning of the section and the |
| 50 | * structure. Force alignment to the same alignment as the section start. | 60 | * structure. Force alignment to the same alignment as the section start. |
| 51 | */ | 61 | */ |
| 52 | #define __trace_mark(name, call_data, format, args...) \ | 62 | #define __trace_mark(name, call_private, format, args...) \ |
| 53 | do { \ | 63 | do { \ |
| 54 | static const char __mstrtab_name_##name[] \ | 64 | static const char __mstrtab_name_##name[] \ |
| 55 | __attribute__((section("__markers_strings"))) \ | 65 | __attribute__((section("__markers_strings"))) \ |
| @@ -60,24 +70,23 @@ struct marker { | |||
| 60 | static struct marker __mark_##name \ | 70 | static struct marker __mark_##name \ |
| 61 | __attribute__((section("__markers"), aligned(8))) = \ | 71 | __attribute__((section("__markers"), aligned(8))) = \ |
| 62 | { __mstrtab_name_##name, __mstrtab_format_##name, \ | 72 | { __mstrtab_name_##name, __mstrtab_format_##name, \ |
| 63 | 0, __mark_empty_function, NULL }; \ | 73 | 0, 0, marker_probe_cb, \ |
| 74 | { __mark_empty_function, NULL}, NULL }; \ | ||
| 64 | __mark_check_format(format, ## args); \ | 75 | __mark_check_format(format, ## args); \ |
| 65 | if (unlikely(__mark_##name.state)) { \ | 76 | if (unlikely(__mark_##name.state)) { \ |
| 66 | preempt_disable(); \ | ||
| 67 | (*__mark_##name.call) \ | 77 | (*__mark_##name.call) \ |
| 68 | (&__mark_##name, call_data, \ | 78 | (&__mark_##name, call_private, \ |
| 69 | format, ## args); \ | 79 | format, ## args); \ |
| 70 | preempt_enable(); \ | ||
| 71 | } \ | 80 | } \ |
| 72 | } while (0) | 81 | } while (0) |
| 73 | 82 | ||
| 74 | extern void marker_update_probe_range(struct marker *begin, | 83 | extern void marker_update_probe_range(struct marker *begin, |
| 75 | struct marker *end, struct module *probe_module, int *refcount); | 84 | struct marker *end); |
| 76 | #else /* !CONFIG_MARKERS */ | 85 | #else /* !CONFIG_MARKERS */ |
| 77 | #define __trace_mark(name, call_data, format, args...) \ | 86 | #define __trace_mark(name, call_private, format, args...) \ |
| 78 | __mark_check_format(format, ## args) | 87 | __mark_check_format(format, ## args) |
| 79 | static inline void marker_update_probe_range(struct marker *begin, | 88 | static inline void marker_update_probe_range(struct marker *begin, |
| 80 | struct marker *end, struct module *probe_module, int *refcount) | 89 | struct marker *end) |
| 81 | { } | 90 | { } |
| 82 | #endif /* CONFIG_MARKERS */ | 91 | #endif /* CONFIG_MARKERS */ |
| 83 | 92 | ||
| @@ -92,8 +101,6 @@ static inline void marker_update_probe_range(struct marker *begin, | |||
| 92 | #define trace_mark(name, format, args...) \ | 101 | #define trace_mark(name, format, args...) \ |
