IMO, adding a toplevel samples/ just for two example sources was a bit
unnecessary, and not how we normally treat examples. Usually examples
are stored in Documentation/ such as
Documentation/filesystems/configfs/configfs_example.c or less
frequently, they are inlined in an existing subdir like
drivers/usb/usb-skeleton.c or drivers/net/pci-skeleton.c.
Please most humbly :) consider pulling from 'samples' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/misc-2.6.git samples
to receive the following updates:
.../markers/marker-example.c | 0
Documentation/{ => markers}/markers.txt | 2 +-
{samples => Documentation}/markers/probe-example.c | 0
Makefile | 3 ---
lib/Kconfig.debug | 1 -
samples/Kconfig | 16 ----------------
samples/Makefile | 3 ---
samples/markers/Makefile | 4 ----
8 files changed, 1 insertions(+), 28 deletions(-)
rename {samples => Documentation}/markers/marker-example.c (100%)
rename Documentation/{ => markers}/markers.txt (98%)
rename {samples => Documentation}/markers/probe-example.c (100%)
delete mode 100644 samples/Kconfig
delete mode 100644 samples/Makefile
delete mode 100644 samples/markers/Makefile
Jeff Garzik (1):
Move markers samples and docs to Documentation/markers/
diff --git a/Documentation/markers.txt b/Documentation/markers.txt
deleted file mode 100644
index 295a71b..0000000
--- a/Documentation/markers.txt
+++ /dev/null
@@ -1,81 +0,0 @@
- Using the Linux Kernel Markers
-
- Mathieu Desnoyers
-
-
-This document introduces Linux Kernel Markers and their use. It provides
-examples of how to insert markers in the kernel and connect probe functions to
-them and provides some examples of probe functions.
-
-
-* Purpose of markers
-
-A marker placed in code provides a hook to call a function (probe) that you can
-provide at runtime. A marker can be "on" (a probe is connected to it) or "off"
-(no probe is attached). When a marker is "off" it has no effect, except for
-adding a tiny time penalty (checking a condition for a branch) and space
-penalty (adding a few bytes for the function call at the end of the
-instrumented function and adds a data structure in a separate section). When a
-marker is "on", the function you provide is called each time the marker is
-executed, in the execution context of the caller. When the function provided
-ends its execution, it returns to the caller (continuing from the marker site).
-
-You can put markers at important locations in the code. Markers are
-lightweight hooks that can pass an arbitrary number of parameters,
-described in a printk-like format string, to the attached probe function.
-
-They can be used for tracing and performance accounting.
-
-
-* Usage
-
-In order to use the macro trace_mark, you should include linux/marker.h.
-
-#include <linux/marker.h>
-
-And,
-
-trace_mark(subsystem_event, "%d %s", someint, somestring);
-Where :
-- subsystem_event is an identifier unique to your event
- - subsystem is the name of your subsystem.
- - event is the name of the event to mark.
-- "%d %s" is the formatted string for the serializer.
-- someint is an integer.
-- somestring is a char pointer.
-
-Connecting a function (probe) to a marker is done by providing a probe (function
-to call) for the specific marker through marker_probe_register() and can be
-activated by calling marker_arm(). Marker deactivation can be done by calling
-marker_disarm() as many times as marker_arm() has been called. Removing a probe
-is done through marker_probe_unregister(); it will disarm the probe and make
-sure there is no caller left using the probe when it returns. Probe removal is
-preempt-safe because preemption is disabled around the probe call. See the
-"Probe example" section below for a sample probe module.
-
-The marker mechanism supports inserting multiple instances of the same marker.
-Markers can be put in inline functions, inlined static functions, and
-unrolled loops as well as regular functions.
-
-The naming scheme "subsystem_event" is suggested here as a convention intended
-to limit collisions. Marker names are global to the kernel: they are considered
-as being the same whether they are in the core kernel image or in modules.
-Conflicting format strings for markers with the same name will cause the markers
-to be detected to have a different format string not to be armed and will output
-a printk warning which identifies the inconsistency:
-
-"Format mismatch for probe probe_name (format), marker (format)"
-
-
-* Probe / marker example
-
-See the example provided in samples/markers/src
-
-Compile them with your kernel.
-
-Run, as root :
-modprobe marker-example (insmod order is not important)
-modprobe probe-example
-cat /proc/marker-example (returns an expected error)
-rmmod marker-example probe-example
-dmesg
diff --git a/Documentation/markers/marker-example.c b/Documentation/markers/marker-example.c
new file mode 100644
index 0000000..e787c6d
--- /dev/null
+++ b/Documentation/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 <[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");
diff --git a/Documentation/markers/markers.txt b/Documentation/markers/markers.txt
new file mode 100644
index 0000000..f098277
--- /dev/null
+++ b/Documentation/markers/markers.txt
@@ -0,0 +1,81 @@
+ Using the Linux Kernel Markers
+
+ Mathieu Desnoyers
+
+
+This document introduces Linux Kernel Markers and their use. It provides
+examples of how to insert markers in the kernel and connect probe functions to
+them and provides some examples of probe functions.
+
+
+* Purpose of markers
+
+A marker placed in code provides a hook to call a function (probe) that you can
+provide at runtime. A marker can be "on" (a probe is connected to it) or "off"
+(no probe is attached). When a marker is "off" it has no effect, except for
+adding a tiny time penalty (checking a condition for a branch) and space
+penalty (adding a few bytes for the function call at the end of the
+instrumented function and adds a data structure in a separate section). When a
+marker is "on", the function you provide is called each time the marker is
+executed, in the execution context of the caller. When the function provided
+ends its execution, it returns to the caller (continuing from the marker site).
+
+You can put markers at important locations in the code. Markers are
+lightweight hooks that can pass an arbitrary number of parameters,
+described in a printk-like format string, to the attached probe function.
+
+They can be used for tracing and performance accounting.
+
+
+* Usage
+
+In order to use the macro trace_mark, you should include linux/marker.h.
+
+#include <linux/marker.h>
+
+And,
+
+trace_mark(subsystem_event, "%d %s", someint, somestring);
+Where :
+- subsystem_event is an identifier unique to your event
+ - subsystem is the name of your subsystem.
+ - event is the name of the event to mark.
+- "%d %s" is the formatted string for the serializer.
+- someint is an integer.
+- somestring is a char pointer.
+
+Connecting a function (probe) to a marker is done by providing a probe (function
+to call) for the specific marker through marker_probe_register() and can be
+activated by calling marker_arm(). Marker deactivation can be done by calling
+marker_disarm() as many times as marker_arm() has been called. Removing a probe
+is done through marker_probe_unregister(); it will disarm the probe and make
+sure there is no caller left using the probe when it returns. Probe removal is
+preempt-safe because preemption is disabled around the probe call. See the
+"Probe example" section below for a sample probe module.
+
+The marker mechanism supports inserting multiple instances of the same marker.
+Markers can be put in inline functions, inlined static functions, and
+unrolled loops as well as regular functions.
+
+The naming scheme "subsystem_event" is suggested here as a convention intended
+to limit collisions. Marker names are global to the kernel: they are considered
+as being the same whether they are in the core kernel image or in modules.
+Conflicting format strings for markers with the same name will cause the markers
+to be detected to have a different format string not to be armed and will output
+a printk warning which identifies the inconsistency:
+
+"Format mismatch for probe probe_name (format), marker (format)"
+
+
+* Probe / marker example
+
+See the examples provided in Documentation/markers/*.c
+
+Compile them with your kernel.
+
+Run, as root :
+modprobe marker-example (insmod order is not important)
+modprobe probe-example
+cat /proc/marker-example (returns an expected error)
+rmmod marker-example probe-example
+dmesg
diff --git a/Documentation/markers/probe-example.c b/Documentation/markers/probe-example.c
new file mode 100644
index 0000000..238b2e3
--- /dev/null
+++ b/Documentation/markers/probe-example.c
@@ -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");
diff --git a/Makefile b/Makefile
index 2a47290..83894ae 100644
--- a/Makefile
+++ b/Makefile
@@ -774,9 +774,6 @@ vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) vmlinux.o
ifdef CONFIG_HEADERS_CHECK
$(Q)$(MAKE) -f $(srctree)/Makefile headers_check
endif
-ifdef CONFIG_SAMPLES
- $(Q)$(MAKE) $(build)=samples
-endif
$(call vmlinux-modpost)
$(call if_changed_rule,vmlinux__)
$(Q)rm -f .old_version
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 1faa508..b26313c 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -509,4 +509,3 @@ config FAULT_INJECTION_STACKTRACE_FILTER
help
Provide stacktrace filter for fault-injection capabilities
-source "samples/Kconfig"
diff --git a/samples/Kconfig b/samples/Kconfig
deleted file mode 100644
index 57bb223..0000000
--- a/samples/Kconfig
+++ /dev/null
@@ -1,16 +0,0 @@
-# samples/Kconfig
-
-menuconfig SAMPLES
- bool "Sample kernel code"
- help
- You can build and test sample kernel code here.
-
-if SAMPLES
-
-config SAMPLE_MARKERS
- tristate "Build markers examples -- loadable modules only"
- depends on MARKERS && m
- help
- This build markers example modules.
-
-endif # SAMPLES
diff --git a/samples/Makefile b/samples/Makefile
deleted file mode 100644
index 5a4f0b6..0000000
--- a/samples/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-# Makefile for Linux samples code
-
-obj-$(CONFIG_SAMPLES) += markers/
diff --git a/samples/markers/Makefile b/samples/markers/Makefile
deleted file mode 100644
index 6d72312..0000000
--- a/samples/markers/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-# 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
deleted file mode 100644
index e787c6d..0000000
--- a/samples/markers/marker-example.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/* 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");
diff --git a/samples/markers/probe-example.c b/samples/markers/probe-example.c
deleted file mode 100644
index 238b2e3..0000000
--- a/samples/markers/probe-example.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/* 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");
Hi Jeff.
Why do you think it is not worthwhile to build the samples so we can check that they
are to some extend valid code?
I noticed you deleted the following - but you did not explain why.
Sam
Makefile b/Makefile
> index 2a47290..83894ae 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -774,9 +774,6 @@ vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) vmlinux.o
> ifdef CONFIG_HEADERS_CHECK
> $(Q)$(MAKE) -f $(srctree)/Makefile headers_check
> endif
> -ifdef CONFIG_SAMPLES
> - $(Q)$(MAKE) $(build)=samples
> -endif
> $(call vmlinux-modpost)
> $(call if_changed_rule,vmlinux__)
> $(Q)rm -f .old_version
* Jeff Garzik ([email protected]) wrote:
>
> IMO, adding a toplevel samples/ just for two example sources was a bit
> unnecessary, and not how we normally treat examples. Usually examples
> are stored in Documentation/ such as
> Documentation/filesystems/configfs/configfs_example.c or less
> frequently, they are inlined in an existing subdir like
> drivers/usb/usb-skeleton.c or drivers/net/pci-skeleton.c.
>
> Please most humbly :) consider pulling from 'samples' branch of
> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/misc-2.6.git samples
>
Please have a look at the following discussion thread, which explains
why such change has been considered useful:
http://lkml.org/lkml/2007/9/24/304
Your patch is basically taking us back to the previous state, where
sample code was embedded within Documentation .txt files, which tends to
be more difficult to keep up to date with API changes.
I am bringing Christoph and Randy in the discussion, since I made this
change on their advice.
Mathieu
> to receive the following updates:
>
> .../markers/marker-example.c | 0
> Documentation/{ => markers}/markers.txt | 2 +-
> {samples => Documentation}/markers/probe-example.c | 0
> Makefile | 3 ---
> lib/Kconfig.debug | 1 -
> samples/Kconfig | 16 ----------------
> samples/Makefile | 3 ---
> samples/markers/Makefile | 4 ----
> 8 files changed, 1 insertions(+), 28 deletions(-)
> rename {samples => Documentation}/markers/marker-example.c (100%)
> rename Documentation/{ => markers}/markers.txt (98%)
> rename {samples => Documentation}/markers/probe-example.c (100%)
> delete mode 100644 samples/Kconfig
> delete mode 100644 samples/Makefile
> delete mode 100644 samples/markers/Makefile
>
> Jeff Garzik (1):
> Move markers samples and docs to Documentation/markers/
>
> diff --git a/Documentation/markers.txt b/Documentation/markers.txt
> deleted file mode 100644
> index 295a71b..0000000
> --- a/Documentation/markers.txt
> +++ /dev/null
> @@ -1,81 +0,0 @@
> - Using the Linux Kernel Markers
> -
> - Mathieu Desnoyers
> -
> -
> -This document introduces Linux Kernel Markers and their use. It provides
> -examples of how to insert markers in the kernel and connect probe functions to
> -them and provides some examples of probe functions.
> -
> -
> -* Purpose of markers
> -
> -A marker placed in code provides a hook to call a function (probe) that you can
> -provide at runtime. A marker can be "on" (a probe is connected to it) or "off"
> -(no probe is attached). When a marker is "off" it has no effect, except for
> -adding a tiny time penalty (checking a condition for a branch) and space
> -penalty (adding a few bytes for the function call at the end of the
> -instrumented function and adds a data structure in a separate section). When a
> -marker is "on", the function you provide is called each time the marker is
> -executed, in the execution context of the caller. When the function provided
> -ends its execution, it returns to the caller (continuing from the marker site).
> -
> -You can put markers at important locations in the code. Markers are
> -lightweight hooks that can pass an arbitrary number of parameters,
> -described in a printk-like format string, to the attached probe function.
> -
> -They can be used for tracing and performance accounting.
> -
> -
> -* Usage
> -
> -In order to use the macro trace_mark, you should include linux/marker.h.
> -
> -#include <linux/marker.h>
> -
> -And,
> -
> -trace_mark(subsystem_event, "%d %s", someint, somestring);
> -Where :
> -- subsystem_event is an identifier unique to your event
> - - subsystem is the name of your subsystem.
> - - event is the name of the event to mark.
> -- "%d %s" is the formatted string for the serializer.
> -- someint is an integer.
> -- somestring is a char pointer.
> -
> -Connecting a function (probe) to a marker is done by providing a probe (function
> -to call) for the specific marker through marker_probe_register() and can be
> -activated by calling marker_arm(). Marker deactivation can be done by calling
> -marker_disarm() as many times as marker_arm() has been called. Removing a probe
> -is done through marker_probe_unregister(); it will disarm the probe and make
> -sure there is no caller left using the probe when it returns. Probe removal is
> -preempt-safe because preemption is disabled around the probe call. See the
> -"Probe example" section below for a sample probe module.
> -
> -The marker mechanism supports inserting multiple instances of the same marker.
> -Markers can be put in inline functions, inlined static functions, and
> -unrolled loops as well as regular functions.
> -
> -The naming scheme "subsystem_event" is suggested here as a convention intended
> -to limit collisions. Marker names are global to the kernel: they are considered
> -as being the same whether they are in the core kernel image or in modules.
> -Conflicting format strings for markers with the same name will cause the markers
> -to be detected to have a different format string not to be armed and will output
> -a printk warning which identifies the inconsistency:
> -
> -"Format mismatch for probe probe_name (format), marker (format)"
> -
> -
> -* Probe / marker example
> -
> -See the example provided in samples/markers/src
> -
> -Compile them with your kernel.
> -
> -Run, as root :
> -modprobe marker-example (insmod order is not important)
> -modprobe probe-example
> -cat /proc/marker-example (returns an expected error)
> -rmmod marker-example probe-example
> -dmesg
> diff --git a/Documentation/markers/marker-example.c b/Documentation/markers/marker-example.c
> new file mode 100644
> index 0000000..e787c6d
> --- /dev/null
> +++ b/Documentation/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 <[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");
> diff --git a/Documentation/markers/markers.txt b/Documentation/markers/markers.txt
> new file mode 100644
> index 0000000..f098277
> --- /dev/null
> +++ b/Documentation/markers/markers.txt
> @@ -0,0 +1,81 @@
> + Using the Linux Kernel Markers
> +
> + Mathieu Desnoyers
> +
> +
> +This document introduces Linux Kernel Markers and their use. It provides
> +examples of how to insert markers in the kernel and connect probe functions to
> +them and provides some examples of probe functions.
> +
> +
> +* Purpose of markers
> +
> +A marker placed in code provides a hook to call a function (probe) that you can
> +provide at runtime. A marker can be "on" (a probe is connected to it) or "off"
> +(no probe is attached). When a marker is "off" it has no effect, except for
> +adding a tiny time penalty (checking a condition for a branch) and space
> +penalty (adding a few bytes for the function call at the end of the
> +instrumented function and adds a data structure in a separate section). When a
> +marker is "on", the function you provide is called each time the marker is
> +executed, in the execution context of the caller. When the function provided
> +ends its execution, it returns to the caller (continuing from the marker site).
> +
> +You can put markers at important locations in the code. Markers are
> +lightweight hooks that can pass an arbitrary number of parameters,
> +described in a printk-like format string, to the attached probe function.
> +
> +They can be used for tracing and performance accounting.
> +
> +
> +* Usage
> +
> +In order to use the macro trace_mark, you should include linux/marker.h.
> +
> +#include <linux/marker.h>
> +
> +And,
> +
> +trace_mark(subsystem_event, "%d %s", someint, somestring);
> +Where :
> +- subsystem_event is an identifier unique to your event
> + - subsystem is the name of your subsystem.
> + - event is the name of the event to mark.
> +- "%d %s" is the formatted string for the serializer.
> +- someint is an integer.
> +- somestring is a char pointer.
> +
> +Connecting a function (probe) to a marker is done by providing a probe (function
> +to call) for the specific marker through marker_probe_register() and can be
> +activated by calling marker_arm(). Marker deactivation can be done by calling
> +marker_disarm() as many times as marker_arm() has been called. Removing a probe
> +is done through marker_probe_unregister(); it will disarm the probe and make
> +sure there is no caller left using the probe when it returns. Probe removal is
> +preempt-safe because preemption is disabled around the probe call. See the
> +"Probe example" section below for a sample probe module.
> +
> +The marker mechanism supports inserting multiple instances of the same marker.
> +Markers can be put in inline functions, inlined static functions, and
> +unrolled loops as well as regular functions.
> +
> +The naming scheme "subsystem_event" is suggested here as a convention intended
> +to limit collisions. Marker names are global to the kernel: they are considered
> +as being the same whether they are in the core kernel image or in modules.
> +Conflicting format strings for markers with the same name will cause the markers
> +to be detected to have a different format string not to be armed and will output
> +a printk warning which identifies the inconsistency:
> +
> +"Format mismatch for probe probe_name (format), marker (format)"
> +
> +
> +* Probe / marker example
> +
> +See the examples provided in Documentation/markers/*.c
> +
> +Compile them with your kernel.
> +
> +Run, as root :
> +modprobe marker-example (insmod order is not important)
> +modprobe probe-example
> +cat /proc/marker-example (returns an expected error)
> +rmmod marker-example probe-example
> +dmesg
> diff --git a/Documentation/markers/probe-example.c b/Documentation/markers/probe-example.c
> new file mode 100644
> index 0000000..238b2e3
> --- /dev/null
> +++ b/Documentation/markers/probe-example.c
> @@ -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");
> diff --git a/Makefile b/Makefile
> index 2a47290..83894ae 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -774,9 +774,6 @@ vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) vmlinux.o
> ifdef CONFIG_HEADERS_CHECK
> $(Q)$(MAKE) -f $(srctree)/Makefile headers_check
> endif
> -ifdef CONFIG_SAMPLES
> - $(Q)$(MAKE) $(build)=samples
> -endif
> $(call vmlinux-modpost)
> $(call if_changed_rule,vmlinux__)
> $(Q)rm -f .old_version
> diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
> index 1faa508..b26313c 100644
> --- a/lib/Kconfig.debug
> +++ b/lib/Kconfig.debug
> @@ -509,4 +509,3 @@ config FAULT_INJECTION_STACKTRACE_FILTER
> help
> Provide stacktrace filter for fault-injection capabilities
>
> -source "samples/Kconfig"
> diff --git a/samples/Kconfig b/samples/Kconfig
> deleted file mode 100644
> index 57bb223..0000000
> --- a/samples/Kconfig
> +++ /dev/null
> @@ -1,16 +0,0 @@
> -# samples/Kconfig
> -
> -menuconfig SAMPLES
> - bool "Sample kernel code"
> - help
> - You can build and test sample kernel code here.
> -
> -if SAMPLES
> -
> -config SAMPLE_MARKERS
> - tristate "Build markers examples -- loadable modules only"
> - depends on MARKERS && m
> - help
> - This build markers example modules.
> -
> -endif # SAMPLES
> diff --git a/samples/Makefile b/samples/Makefile
> deleted file mode 100644
> index 5a4f0b6..0000000
> --- a/samples/Makefile
> +++ /dev/null
> @@ -1,3 +0,0 @@
> -# Makefile for Linux samples code
> -
> -obj-$(CONFIG_SAMPLES) += markers/
> diff --git a/samples/markers/Makefile b/samples/markers/Makefile
> deleted file mode 100644
> index 6d72312..0000000
> --- a/samples/markers/Makefile
> +++ /dev/null
> @@ -1,4 +0,0 @@
> -# 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
> deleted file mode 100644
> index e787c6d..0000000
> --- a/samples/markers/marker-example.c
> +++ /dev/null
> @@ -1,54 +0,0 @@
> -/* 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");
> diff --git a/samples/markers/probe-example.c b/samples/markers/probe-example.c
> deleted file mode 100644
> index 238b2e3..0000000
> --- a/samples/markers/probe-example.c
> +++ /dev/null
> @@ -1,98 +0,0 @@
> -/* 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");
--
Mathieu Desnoyers
Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Honestly, I don't care at all about building the code. If that's what
you want, great.
My objection is more to adding a samples/ directory, which is contra to
past experience:
A new net driver sample should go in drivers/net/ like the existing
skeleton files I already listed, not samples/net/. A top-level
"samples/" seems like it exists only duplicate the rest of the tree
hierarchy.
Jeff
On Wed, 24 Oct 2007 09:19:05 -0400 Jeff Garzik wrote:
> Honestly, I don't care at all about building the code. If that's what
> you want, great.
Yes, that is wanted. They bitrot too easily -- not good.
> My objection is more to adding a samples/ directory, which is contra to
> past experience:
>
> A new net driver sample should go in drivers/net/ like the existing
> skeleton files I already listed, not samples/net/. A top-level
Can't disagree with that.
> "samples/" seems like it exists only duplicate the rest of the tree
> hierarchy.
It seems odd to be building code in Documentation/, but I can live
with that. It was primarily Christoph who was opposed to that.
He suggested samples/ and I went along with it just to break the
impasse (since no one else was making any comments on it at that
time).
Sam, would building code in Documentation/ cause problems for
kbuild?
---
~Randy
On Wed, Oct 24, 2007 at 09:12:40AM -0700, Randy Dunlap wrote:
> On Wed, 24 Oct 2007 09:19:05 -0400 Jeff Garzik wrote:
>
> > Honestly, I don't care at all about building the code. If that's what
> > you want, great.
>
> Yes, that is wanted. They bitrot too easily -- not good.
>
> > My objection is more to adding a samples/ directory, which is contra to
> > past experience:
> >
> > A new net driver sample should go in drivers/net/ like the existing
> > skeleton files I already listed, not samples/net/. A top-level
>
> Can't disagree with that.
>
> > "samples/" seems like it exists only duplicate the rest of the tree
> > hierarchy.
>
> It seems odd to be building code in Documentation/, but I can live
> with that. It was primarily Christoph who was opposed to that.
> He suggested samples/ and I went along with it just to break the
> impasse (since no one else was making any comments on it at that
> time).
>
> Sam, would building code in Documentation/ cause problems for
> kbuild?
I have this pipe dream that we shall introduce a tool to make the
.txt doc readable in some popular format (HTML?) and then we would
have that Makefile in Documentation/ but that could be a special target
so should be OK.
Sam
* Randy Dunlap ([email protected]) wrote:
> On Wed, 24 Oct 2007 09:19:05 -0400 Jeff Garzik wrote:
>
> > Honestly, I don't care at all about building the code. If that's what
> > you want, great.
>
> Yes, that is wanted. They bitrot too easily -- not good.
>
> > My objection is more to adding a samples/ directory, which is contra to
> > past experience:
> >
> > A new net driver sample should go in drivers/net/ like the existing
> > skeleton files I already listed, not samples/net/. A top-level
>
> Can't disagree with that.
>
> > "samples/" seems like it exists only duplicate the rest of the tree
> > hierarchy.
>
> It seems odd to be building code in Documentation/, but I can live
> with that. It was primarily Christoph who was opposed to that.
> He suggested samples/ and I went along with it just to break the
> impasse (since no one else was making any comments on it at that
> time).
>
> Sam, would building code in Documentation/ cause problems for
> kbuild?
Since we already have the Instrumentation menu in
kernel/Kconfig.instrumentation and instrumentation code all over the
kernel tree:
arch/*/oprofile/*.c
kernel/kprobes.c
arch/*/kernel/kprobes.c
kernel/marker.c
kernel/profile.c
kernel/profile.S
kernel/lockdep.c
vm/vmstat.c
block/blktrace.c
We could move them to
instrumentation/
arch/*/instrumentation/
Therefore, we could also move the kprobes and marker samples under
instrumentation/samples/
My main concern is that 15 characters long directory name might be
inelegant (however, it only beats Documentation by 2).
Mathieu
--
Mathieu Desnoyers
Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
On Wed, 24 Oct 2007 13:31:02 -0400 Mathieu Desnoyers wrote:
> * Randy Dunlap ([email protected]) wrote:
> > On Wed, 24 Oct 2007 09:19:05 -0400 Jeff Garzik wrote:
> >
> > > Honestly, I don't care at all about building the code. If that's what
> > > you want, great.
> >
> > Yes, that is wanted. They bitrot too easily -- not good.
> >
> > > My objection is more to adding a samples/ directory, which is contra to
> > > past experience:
> > >
> > > A new net driver sample should go in drivers/net/ like the existing
> > > skeleton files I already listed, not samples/net/. A top-level
> >
> > Can't disagree with that.
> >
> > > "samples/" seems like it exists only duplicate the rest of the tree
> > > hierarchy.
> >
> > It seems odd to be building code in Documentation/, but I can live
> > with that. It was primarily Christoph who was opposed to that.
> > He suggested samples/ and I went along with it just to break the
> > impasse (since no one else was making any comments on it at that
> > time).
> >
> > Sam, would building code in Documentation/ cause problems for
> > kbuild?
>
> Since we already have the Instrumentation menu in
> kernel/Kconfig.instrumentation and instrumentation code all over the
> kernel tree:
>
> arch/*/oprofile/*.c
> kernel/kprobes.c
> arch/*/kernel/kprobes.c
> kernel/marker.c
> kernel/profile.c
> kernel/profile.S
> kernel/lockdep.c
> vm/vmstat.c
> block/blktrace.c
>
> We could move them to
>
> instrumentation/
> arch/*/instrumentation/
>
> Therefore, we could also move the kprobes and marker samples under
>
> instrumentation/samples/
>
> My main concern is that 15 characters long directory name might be
> inelegant (however, it only beats Documentation by 2).
Ack, instrumentation deserves that much (in the new world order).
---
~Randy
On Wed, 24 Oct 2007 13:31:02 EDT, Mathieu Desnoyers said:
> Therefore, we could also move the kprobes and marker samples under
>
> instrumentation/samples/
>
> My main concern is that 15 characters long directory name might be
> inelegant (however, it only beats Documentation by 2).
How so? i n s esc. 4 keystrokes (and still 2 more than D<ESC> ;)