diff options
| author | Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> | 2007-10-19 02:41:06 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-19 14:53:54 -0400 |
| commit | 8256e47cdc8923e9959eb1d7f95d80da538add80 (patch) | |
| tree | 4702aa3ad7c9025f70314f1146e551b4e1dfcbb2 /include/linux/marker.h | |
| parent | 09cadedbdc01f1a4bea1f427d4fb4642eaa19da9 (diff) | |
Linux Kernel Markers
The marker activation functions sits in kernel/marker.c. A hash table is used
to keep track of the registered probes and armed markers, so the markers
within a newly loaded module that should be active can be activated at module
load time.
marker_query has been removed. marker_get_first, marker_get_next and
marker_release should be used as iterators on the markers.
[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Acked-by: "Frank Ch. Eigler" <fche@redhat.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Mike Mason <mmlnx@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux/marker.h')
| -rw-r--r-- | include/linux/marker.h | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/include/linux/marker.h b/include/linux/marker.h new file mode 100644 index 000000000000..8038d89b835d --- /dev/null +++ b/include/linux/marker.h | |||
| @@ -0,0 +1,130 @@ | |||
| 1 | #ifndef _LINUX_MARKER_H | ||
| 2 | #define _LINUX_MARKER_H | ||
| 3 | |||
| 4 | /* | ||
| 5 | * Code markup for dynamic and static tracing. | ||
| 6 | * | ||
| 7 | * See Documentation/marker.txt. | ||
| 8 | * | ||
| 9 | * (C) Copyright 2006 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> | ||
| 10 | * | ||
| 11 | * This file is released under the GPLv2. | ||
| 12 | * See the file COPYING for more details. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/types.h> | ||
| 16 | |||
| 17 | struct module; | ||
| 18 | struct marker; | ||
| 19 | |||
| 20 | /** | ||
| 21 | * marker_probe_func - Type of a marker probe function | ||
| 22 | * @mdata: pointer of type struct marker | ||
| 23 | * @private_data: caller site private data | ||
| 24 | * @fmt: format string | ||
| 25 | * @...: variable argument list | ||
| 26 | * | ||
| 27 | * Type of marker probe functions. They receive the mdata and need to parse the | ||
| 28 | * format string to recover the variable argument list. | ||
| 29 | */ | ||
| 30 | typedef void marker_probe_func(const struct marker *mdata, | ||
| 31 | void *private_data, const char *fmt, ...); | ||
| 32 | |||
| 33 | struct marker { | ||
| 34 | const char *name; /* Marker name */ | ||
| 35 | const char *format; /* Marker format string, describing the | ||
| 36 | * variable argument list. | ||
| 37 | */ | ||
| 38 | char state; /* Marker state. */ | ||
| 39 | marker_probe_func *call;/* Probe handler function pointer */ | ||
| 40 | void *private; /* Private probe data */ | ||
| 41 | } __attribute__((aligned(8))); | ||
| 42 | |||
| 43 | #ifdef CONFIG_MARKERS | ||
| 44 | |||
| 45 | /* | ||
| 46 | * Note : the empty asm volatile with read constraint is used here instead of a | ||
| 47 | * "used" attribute to fix a gcc 4.1.x bug. | ||
| 48 | * Make sure the alignment of the structure in the __markers section will | ||
| 49 | * not add unwanted padding between the beginning of the section and the | ||
| 50 | * structure. Force alignment to the same alignment as the section start. | ||
| 51 | */ | ||
| 52 | #define __trace_mark(name, call_data, format, args...) \ | ||
| 53 | do { \ | ||
| 54 | static const char __mstrtab_name_##name[] \ | ||
| 55 | __attribute__((section("__markers_strings"))) \ | ||
| 56 | = #name; \ | ||
| 57 | static const char __mstrtab_format_##name[] \ | ||
| 58 | __attribute__((section("__markers_strings"))) \ | ||
| 59 | = format; \ | ||
| 60 | static struct marker __mark_##name \ | ||
| 61 | __attribute__((section("__markers"), aligned(8))) = \ | ||
| 62 | { __mstrtab_name_##name, __mstrtab_format_##name, \ | ||
| 63 | 0, __mark_empty_function, NULL }; \ | ||
| 64 | asm volatile("" : : "i" (&__mark_##name)); \ | ||
| 65 | __mark_check_format(format, ## args); \ | ||
| 66 | if (unlikely(__mark_##name.state)) { \ | ||
| 67 | preempt_disable(); \ | ||
| 68 | (*__mark_##name.call) \ | ||
| 69 | (&__mark_##name, call_data, \ | ||
| 70 | format, ## args); \ | ||
| 71 | preempt_enable(); \ | ||
| 72 | } \ | ||
| 73 | } while (0) | ||
| 74 | |||
| 75 | extern void marker_update_probe_range(struct marker *begin, | ||
| 76 | struct marker *end, struct module *probe_module, int *refcount); | ||
| 77 | #else /* !CONFIG_MARKERS */ | ||
| 78 | #define __trace_mark(name, call_data, format, args...) \ | ||
| 79 | __mark_check_format(format, ## args) | ||
| 80 | static inline void marker_update_probe_range(struct marker *begin, | ||
| 81 | struct marker *end, struct module *probe_module, int *refcount) | ||
| 82 | { } | ||
| 83 | #endif /* CONFIG_MARKERS */ | ||
| 84 | |||
| 85 | /** | ||
| 86 | * trace_mark - Marker | ||
| 87 | * @name: marker name, not quoted. | ||
| 88 | * @format: format string | ||
| 89 | * @args...: variable argument list | ||
| 90 | * | ||
| 91 | * Places a marker. | ||
| 92 | */ | ||
| 93 | #define trace_mark(name, format, args...) \ | ||
| 94 | __trace_mark(name, NULL, format, ## args) | ||
| 95 | |||
| 96 | #define MARK_MAX_FORMAT_LEN 1024 | ||
| 97 | |||
| 98 | /** | ||
| 99 | * MARK_NOARGS - Format string for a marker with no argument. | ||
| 100 | */ | ||
| 101 | #define MARK_NOARGS " " | ||
| 102 | |||
| 103 | /* To be used for string format validity checking with gcc */ | ||
| 104 | static inline void __printf(1, 2) __mark_check_format(const char *fmt, ...) | ||
| 105 | { | ||
| 106 | } | ||
| 107 | |||
| 108 | extern marker_probe_func __mark_empty_function; | ||
| 109 | |||
| 110 | /* | ||
| 111 | * Connect a probe to a marker. | ||
| 112 | * private data pointer must be a valid allocated memory address, or NULL. | ||
| 113 | */ | ||
| 114 | extern int marker_probe_register(const char *name, const char *format, | ||
| 115 | marker_probe_func *probe, void *private); | ||
| 116 | |||
| 117 | /* | ||
| 118 | * Returns the private data given to marker_probe_register. | ||
| 119 | */ | ||
| 120 | extern void *marker_probe_unregister(const char *name); | ||
| 121 | /* | ||
| 122 | * Unregister a marker by providing the registered private data. | ||
| 123 | */ | ||
| 124 | extern void *marker_probe_unregister_private_data(void *private); | ||
| 125 | |||
| 126 | extern int marker_arm(const char *name); | ||
| 127 | extern int marker_disarm(const char *name); | ||
| 128 | extern void *marker_get_private_data(const char *name); | ||
| 129 | |||
| 130 | #endif | ||
