forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Module example showing how to use the Linux Kernel Markers. [[email protected]: coding-style fixes] Signed-off-by: Mathieu Desnoyers <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
- Loading branch information
Mathieu Desnoyers
authored and
Linus Torvalds
committed
Oct 19, 2007
1 parent
267c402
commit 31155bc
Showing
6 changed files
with
164 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Makefile for Linux samples code | ||
|
||
obj-$(CONFIG_SAMPLES) += markers/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* marker-example.c | ||
* | ||
* Executes a marker when /proc/marker-example is opened. | ||
* | ||
* (C) Copyright 2007 Mathieu Desnoyers <[email protected]> | ||
* | ||
* 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"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
/* probe-example.c | ||
* | ||
* Connects two functions to marker call sites. | ||
* | ||
* (C) Copyright 2007 Mathieu Desnoyers <[email protected]> | ||
* | ||
* 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(const struct marker *mdata, void *private, | ||
const char *format, ...) | ||
{ | ||
va_list ap; | ||
/* Declare args */ | ||
unsigned int value; | ||
const char *mystr; | ||
|
||
/* Assign args */ | ||
va_start(ap, format); | ||
value = va_arg(ap, typeof(value)); | ||
mystr = va_arg(ap, typeof(mystr)); | ||
|
||
/* Call printk */ | ||
printk(KERN_DEBUG "Value %u, string %s\n", value, mystr); | ||
|
||
/* or count, check rights, serialize data in a buffer */ | ||
|
||
va_end(ap); | ||
} | ||
|
||
atomic_t eventb_count = ATOMIC_INIT(0); | ||
|
||
void probe_subsystem_eventb(const struct marker *mdata, void *private, | ||
const char *format, ...) | ||
{ | ||
/* 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); | ||
result = marker_arm(probe_array[i].name); | ||
if (result) | ||
printk(KERN_INFO "Unable to arm 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); | ||
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"); |