diff options
| author | Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> | 2007-10-19 02:41:08 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-19 14:53:55 -0400 |
| commit | 31155bc03e35a8d2b2551bc2eea3da5791e1b776 (patch) | |
| tree | 64a82cd692af1dc3672d311f5788e2dc6a56e546 | |
| parent | 267c4025f2e198a4e551556a6db31a554ca51814 (diff) | |
Linux Kernel Markers - Samples
Module example showing how to use the Linux Kernel Markers.
[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
| -rw-r--r-- | include/linux/marker.h | 1 | ||||
| -rw-r--r-- | samples/Kconfig | 5 | ||||
| -rw-r--r-- | samples/Makefile | 3 | ||||
| -rw-r--r-- | samples/markers/Makefile | 4 | ||||
| -rw-r--r-- | samples/markers/marker-example.c | 54 | ||||
| -rw-r--r-- | samples/markers/probe-example.c | 98 |
6 files changed, 164 insertions, 1 deletions
diff --git a/include/linux/marker.h b/include/linux/marker.h index 8038d89b835d..5f36cf946bcb 100644 --- a/include/linux/marker.h +++ b/include/linux/marker.h | |||
| @@ -61,7 +61,6 @@ struct marker { | |||
| 61 | __attribute__((section("__markers"), aligned(8))) = \ | 61 | __attribute__((section("__markers"), aligned(8))) = \ |
| 62 | { __mstrtab_name_##name, __mstrtab_format_##name, \ | 62 | { __mstrtab_name_##name, __mstrtab_format_##name, \ |
| 63 | 0, __mark_empty_function, NULL }; \ | 63 | 0, __mark_empty_function, NULL }; \ |
| 64 | asm volatile("" : : "i" (&__mark_##name)); \ | ||
| 65 | __mark_check_format(format, ## args); \ | 64 | __mark_check_format(format, ## args); \ |
| 66 | if (unlikely(__mark_##name.state)) { \ | 65 | if (unlikely(__mark_##name.state)) { \ |
| 67 | preempt_disable(); \ | 66 | preempt_disable(); \ |
diff --git a/samples/Kconfig b/samples/Kconfig index b46b4cf4382f..57bb2236952c 100644 --- a/samples/Kconfig +++ b/samples/Kconfig | |||
| @@ -7,5 +7,10 @@ menuconfig SAMPLES | |||
| 7 | 7 | ||
| 8 | if SAMPLES | 8 | if SAMPLES |
| 9 | 9 | ||
| 10 | config SAMPLE_MARKERS | ||
| 11 | tristate "Build markers examples -- loadable modules only" | ||
| 12 | depends on MARKERS && m | ||
| 13 | help | ||
| 14 | This build markers example modules. | ||
| 10 | 15 | ||
| 11 | endif # SAMPLES | 16 | endif # SAMPLES |
diff --git a/samples/Makefile b/samples/Makefile new file mode 100644 index 000000000000..5a4f0b6bcbed --- /dev/null +++ b/samples/Makefile | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | # Makefile for Linux samples code | ||
| 2 | |||
| 3 | obj-$(CONFIG_SAMPLES) += markers/ | ||
diff --git a/samples/markers/Makefile b/samples/markers/Makefile new file mode 100644 index 000000000000..6d7231265f0f --- /dev/null +++ b/samples/markers/Makefile | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | # builds the kprobes example kernel modules; | ||
| 2 | # then to use one (as root): insmod <module_name.ko> | ||
| 3 | |||
| 4 | obj-$(CONFIG_SAMPLE_MARKERS) += probe-example.o marker-example.o | ||
diff --git a/samples/markers/marker-example.c b/samples/markers/marker-example.c new file mode 100644 index 000000000000..e787c6d16dd7 --- /dev/null +++ b/samples/markers/marker-example.c | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | /* marker-example.c | ||
| 2 | * | ||
| 3 | * Executes a marker when /proc/marker-example is opened. | ||
| 4 | * | ||
| 5 | * (C) Copyright 2007 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> | ||
| 6 | * | ||
| 7 | * This file is released under the GPLv2. | ||
| 8 | * See the file COPYING for more details. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/module.h> | ||
| 12 | #include <linux/marker.h> | ||
| 13 | #include <linux/sched.h> | ||
| 14 | #include <linux/proc_fs.h> | ||
| 15 | |||
| 16 | struct proc_dir_entry *pentry_example; | ||
| 17 | |||
| 18 | static int my_open(struct inode *inode, struct file *file) | ||
| 19 | { | ||
| 20 | int i; | ||
| 21 | |||
| 22 | trace_mark(subsystem_event, "%d %s", 123, "example string"); | ||
| 23 | for (i = 0; i < 10; i++) | ||
| 24 | trace_mark(subsystem_eventb, MARK_NOARGS); | ||
| 25 | return -EPERM; | ||
| 26 | } | ||
| 27 | |||
| 28 | static struct file_operations mark_ops = { | ||
| 29 | .open = my_open, | ||
| 30 | }; | ||
| 31 | |||
| 32 | static int example_init(void) | ||
| 33 | { | ||
| 34 | printk(KERN_ALERT "example init\n"); | ||
| 35 | pentry_example = create_proc_entry("marker-example", 0444, NULL); | ||
| 36 | if (pentry_example) | ||
| 37 | pentry_example->proc_fops = &mark_ops; | ||
| 38 | else | ||
| 39 | return -EPERM; | ||
| 40 | return 0; | ||
| 41 | } | ||
| 42 | |||
| 43 | static void example_exit(void) | ||
| 44 | { | ||
| 45 | printk(KERN_ALERT "example exit\n"); | ||
| 46 | remove_proc_entry("marker-example", NULL); | ||
| 47 | } | ||
| 48 | |||
| 49 | module_init(example_init) | ||
| 50 | module_exit(example_exit) | ||
| 51 | |||
| 52 | MODULE_LICENSE("GPL"); | ||
| 53 | MODULE_AUTHOR("Mathieu Desnoyers"); | ||
| 54 | MODULE_DESCRIPTION("Marker example"); | ||
diff --git a/samples/markers/probe-example.c b/samples/markers/probe-example.c new file mode 100644 index 000000000000..238b2e384fc8 --- /dev/null +++ b/samples/markers/probe-example.c | |||
| @@ -0,0 +1,98 @@ | |||
| 1 | /* probe-example.c | ||
| 2 | * | ||
| 3 | * Connects two functions to marker call sites. | ||
| 4 | * | ||
| 5 | * (C) Copyright 2007 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> | ||
| 6 | * | ||
| 7 | * This file is released under the GPLv2. | ||
| 8 | * See the file COPYING for more details. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/sched.h> | ||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/marker.h> | ||
| 15 | #include <asm/atomic.h> | ||
| 16 | |||
| 17 | struct probe_data { | ||
| 18 | const char *name; | ||
| 19 | const char *format; | ||
| 20 | marker_probe_func *probe_func; | ||
| 21 | }; | ||
| 22 | |||
| 23 | void probe_subsystem_event(const struct marker *mdata, void *private, | ||
| 24 | const char *format, ...) | ||
| 25 | { | ||
| 26 | va_list ap; | ||
| 27 | /* Declare args */ | ||
| 28 | unsigned int value; | ||
| 29 | const char *mystr; | ||
| 30 | |||
| 31 | /* Assign args */ | ||
| 32 | va_start(ap, format); | ||
| 33 | value = va_arg(ap, typeof(value)); | ||
| 34 | mystr = va_arg(ap, typeof(mystr)); | ||
| 35 | |||
| 36 | /* Call printk */ | ||
| 37 | printk(KERN_DEBUG "Value %u, string %s\n", value, mystr); | ||
| 38 | |||
| 39 | /* or count, check rights, serialize data in a buffer */ | ||
| 40 | |||
| 41 | va_end(ap); | ||
| 42 | } | ||
| 43 | |||
| 44 | atomic_t eventb_count = ATOMIC_INIT(0); | ||
| 45 | |||
| 46 | void probe_subsystem_eventb(const struct marker *mdata, void *private, | ||
| 47 | const char *format, ...) | ||
| 48 | { | ||
| 49 | /* Increment counter */ | ||
| 50 | atomic_inc(&eventb_count); | ||
| 51 | } | ||
| 52 | |||
| 53 | static struct probe_data probe_array[] = | ||
| 54 | { | ||
| 55 | { .name = "subsystem_event", | ||
| 56 | .format = "%d %s", | ||
| 57 | .probe_func = probe_subsystem_event }, | ||
| 58 | { .name = "subsystem_eventb", | ||
| 59 | .format = MARK_NOARGS, | ||
| 60 | .probe_func = probe_subsystem_eventb }, | ||
| 61 | }; | ||
| 62 | |||
| 63 | static int __init probe_init(void) | ||
| 64 | { | ||
| 65 | int result; | ||
| 66 | int i; | ||
| 67 | |||
| 68 | for (i = 0; i < ARRAY_SIZE(probe_array); i++) { | ||
| 69 | result = marker_probe_register(probe_array[i].name, | ||
| 70 | probe_array[i].format, | ||
| 71 | probe_array[i].probe_func, &probe_array[i]); | ||
| 72 | if (result) | ||
| 73 | printk(KERN_INFO "Unable to register probe %s\n", | ||
| 74 | probe_array[i].name); | ||
| 75 | result = marker_arm(probe_array[i].name); | ||
| 76 | if (result) | ||
| 77 | printk(KERN_INFO "Unable to arm probe %s\n", | ||
| 78 | probe_array[i].name); | ||
| 79 | } | ||
| 80 | return 0; | ||
| 81 | } | ||
| 82 | |||
| 83 | static void __exit probe_fini(void) | ||
| 84 | { | ||
| 85 | int i; | ||
| 86 | |||
| 87 | for (i = 0; i < ARRAY_SIZE(probe_array); i++) | ||
| 88 | marker_probe_unregister(probe_array[i].name); | ||
| 89 | printk(KERN_INFO "Number of event b : %u\n", | ||
| 90 | atomic_read(&eventb_count)); | ||
| 91 | } | ||
| 92 | |||
| 93 | module_init(probe_init); | ||
| 94 | module_exit(probe_fini); | ||
| 95 | |||
| 96 | MODULE_LICENSE("GPL"); | ||
| 97 | MODULE_AUTHOR("Mathieu Desnoyers"); | ||
| 98 | MODULE_DESCRIPTION("SUBSYSTEM Probe"); | ||
