From: jbaron@redhat.com <jbaron@redhat.com> Date: Fri, 22 Aug 2008 14:04:50 -0400 Subject: [misc] markers and tracepoints: markers samples Message-id: 1219428298-7519-7-git-send-email-jbaron@redhat.com O-Subject: [rhel5.3 patch 06/14] markers and tracepoints - markers samples Bugzilla: 329821 bz# 329821 diff --git a/include/linux/marker.h b/include/linux/marker.h index a7ac360..ea04250 100644 --- a/include/linux/marker.h +++ b/include/linux/marker.h @@ -72,7 +72,6 @@ struct marker { { __mstrtab_name_##name, __mstrtab_format_##name, \ 0, 0, marker_probe_cb, \ { __mark_empty_function, NULL}, NULL }; \ - asm volatile("" : : "i" (&__mark_##name)); \ __mark_check_format(format, ## args); \ if (unlikely(__mark_##name.state)) { \ (*__mark_##name.call) \ diff --git a/samples/Kconfig b/samples/Kconfig index 87d26da..b605ea1 100644 --- a/samples/Kconfig +++ b/samples/Kconfig @@ -7,6 +7,12 @@ menuconfig SAMPLES if SAMPLES +config SAMPLE_MARKERS + tristate "Build markers examples -- loadable modules only" + depends on MARKERS && m + help + This build markers example modules. + config SAMPLE_TRACEPOINTS tristate "Build tracepoints examples -- loadable modules only" depends on TRACEPOINTS && m diff --git a/samples/Makefile b/samples/Makefile index 1183778..b210b74 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -1,3 +1,4 @@ # Makefile for Linux samples code obj-$(CONFIG_SAMPLES) += tracepoints/ +obj-$(CONFIG_SAMPLEs) += markers/ diff --git a/samples/markers/Makefile b/samples/markers/Makefile new file mode 100644 index 0000000..6d72312 --- /dev/null +++ b/samples/markers/Makefile @@ -0,0 +1,4 @@ +# builds the kprobes example kernel modules; +# then to use one (as root): insmod <module_name.ko> + +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 0000000..e787c6d --- /dev/null +++ b/samples/markers/marker-example.c @@ -0,0 +1,54 @@ +/* marker-example.c + * + * Executes a marker when /proc/marker-example is opened. + * + * (C) Copyright 2007 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> + * + * This file is released under the GPLv2. + * See the file COPYING for more details. + */ + +#include <linux/module.h> +#include <linux/marker.h> +#include <linux/sched.h> +#include <linux/proc_fs.h> + +struct proc_dir_entry *pentry_example; + +static int my_open(struct inode *inode, struct file *file) +{ + int i; + + trace_mark(subsystem_event, "%d %s", 123, "example string"); + for (i = 0; i < 10; i++) + trace_mark(subsystem_eventb, MARK_NOARGS); + return -EPERM; +} + +static struct file_operations mark_ops = { + .open = my_open, +}; + +static int example_init(void) +{ + printk(KERN_ALERT "example init\n"); + pentry_example = create_proc_entry("marker-example", 0444, NULL); + if (pentry_example) + pentry_example->proc_fops = &mark_ops; + else + return -EPERM; + return 0; +} + +static void example_exit(void) +{ + printk(KERN_ALERT "example exit\n"); + remove_proc_entry("marker-example", NULL); +} + +module_init(example_init) +module_exit(example_exit) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("Marker example"); diff --git a/samples/markers/probe-example.c b/samples/markers/probe-example.c new file mode 100644 index 0000000..9302199 --- /dev/null +++ b/samples/markers/probe-example.c @@ -0,0 +1,91 @@ +/* probe-example.c + * + * Connects two functions to marker call sites. + * + * (C) Copyright 2007 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> + * + * This file is released under the GPLv2. + * See the file COPYING for more details. + */ + +#include <linux/sched.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/marker.h> +#include <asm/atomic.h> + +struct probe_data { + const char *name; + const char *format; + marker_probe_func *probe_func; +}; + +void probe_subsystem_event(void *probe_data, void *call_data, + const char *format, va_list *args) +{ + /* Declare args */ + unsigned int value; + const char *mystr; + + /* Assign args */ + value = va_arg(*args, typeof(value)); + mystr = va_arg(*args, typeof(mystr)); + + /* Call printk */ + printk(KERN_INFO "Value %u, string %s\n", value, mystr); + + /* or count, check rights, serialize data in a buffer */ +} + +atomic_t eventb_count = ATOMIC_INIT(0); + +void probe_subsystem_eventb(void *probe_data, void *call_data, + const char *format, va_list *args) +{ + /* Increment counter */ + atomic_inc(&eventb_count); +} + +static struct probe_data probe_array[] = +{ + { .name = "subsystem_event", + .format = "%d %s", + .probe_func = probe_subsystem_event }, + { .name = "subsystem_eventb", + .format = MARK_NOARGS, + .probe_func = probe_subsystem_eventb }, +}; + +static int __init probe_init(void) +{ + int result; + int i; + + for (i = 0; i < ARRAY_SIZE(probe_array); i++) { + result = marker_probe_register(probe_array[i].name, + probe_array[i].format, + probe_array[i].probe_func, &probe_array[i]); + if (result) + printk(KERN_INFO "Unable to register probe %s\n", + probe_array[i].name); + } + return 0; +} + +static void __exit probe_fini(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(probe_array); i++) + marker_probe_unregister(probe_array[i].name, + probe_array[i].probe_func, &probe_array[i]); + printk(KERN_INFO "Number of event b : %u\n", + atomic_read(&eventb_count)); +} + +module_init(probe_init); +module_exit(probe_fini); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("SUBSYSTEM Probe");