|  | /* 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 = "integer %d string %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)); | 
|  | marker_synchronize_unregister(); | 
|  | } | 
|  |  | 
|  | module_init(probe_init); | 
|  | module_exit(probe_fini); | 
|  |  | 
|  | MODULE_LICENSE("GPL"); | 
|  | MODULE_AUTHOR("Mathieu Desnoyers"); | 
|  | MODULE_DESCRIPTION("SUBSYSTEM Probe"); |