Linux Kernel Markers for 2.6.23-rc4-mm1
Subsystems (21)
cover Linux Kernel Markers for 2.6.23-rc4-mm1
Hi Andrew,
Here are the Linux Kernel Markers for 2.6.23-rc4-mm1. They depend on the sorted module list and on the immediate values.
Mathieu
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 1/6 Linux Kernel Markers - Architecture Independent Code
The marker activation functions sits in kernel/marker.c. A hash table is used to keep track of the registered probes and armed markers, so the markers within a newly loaded module that should be active can be activated at module load time.
marker_query has been removed. marker_get_first, marker_get_next and marker_release should be used as iterators on the markers.
Changelog:
- markers_mutex now nests inside module_mutex rather than the opposite.
---
include/asm-generic/vmlinux.lds.h | 11 include/linux/marker.h | 169 +++++++++ include/linux/module.h | 5 kernel/marker.c | 699 ++++++++++++++++++++++++++++++++++++++ kernel/module.c | 11 5 files changed, 894 insertions(+), 1 deletion(-)
include/asm-generic/vmlinux.lds.h +10 -1
@@ -12,7 +12,11 @@/* .data section */ #define DATA_DATA \ *(.data) \ - *(.data.init.refok) + *(.data.init.refok) \ + . = ALIGN(8); \ + VMLINUX_SYMBOL(__start___markers) = .; \ + *(__markers) \ + VMLINUX_SYMBOL(__stop___markers) = .;#define RO_DATA (align) \ . = ALIGN((align)); \
@@ -129,6 +133,11 @@ VMLINUX_SYMBOL(__stop___immediate) = .; \ } \ \ +/* Markers: strings */ \ + __markers_strings : AT(ADDR(__markers_strings) - LOAD_OFFSET) { \ + *(__markers_strings) \ + } \ + \/* Kernel symbol table: strings */ \ __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \ *(__ksymtab_strings) \
include/linux/marker.h new file +169 -0
169 lines not on this page · raw message
include/linux/module.h +5 -0
@@ -16,6 +16,7 @@#include <linux/kobject.h> #include <linux/moduleparam.h> #include <linux/immediate.h> +#include <linux/marker.h> #include <asm/local.h> #include <asm/module.h>
@@ -380,6 +381,10 @@ struct moduleconst struct __immediate *immediate;unsigned int num_immediate;#endif +#ifdef CONFIG_MARKERS +struct __mark_marker *markers; +unsigned int num_markers; +#endif };#ifndef MODULE_ARCH_INIT #define MODULE_ARCH_INIT {}
kernel/module.c +11 -0
@@ -1721,6 +1721,8 @@ static struct module *load_module(void _unsigned int unusedgplindex;unsigned int unusedgplcrcindex;unsigned int immediateindex; +unsigned int markersindex; +unsigned int markersstringsindex;struct module *mod;long err =0 ;void *percpu =NULL , *ptr =NULL ;/* Stops spurious gcc warning */
@@ -1973,6 +1975,8 @@ static struct module *load_module(void _ mod->num_immediate = sechdrs[immediateindex].sh_size /sizeof (*mod->immediate);#endif + markersindex =find_sec (hdr, sechdrs, secstrings,"__markers" ); + markersstringsindex =find_sec (hdr, sechdrs, secstrings,"__markers_strings" ); mod->unused_syms = (void *)sechdrs[unusedindex].sh_addr;if (unusedcrcindex)
@@ -2014,6 +2018,11 @@ static struct module *load_module(void _if (err <0 ) goto cleanup; } +#ifdef CONFIG_MARKERS + mod->markers = (void *)sechdrs[markersindex].sh_addr; + mod->num_markers = + sechdrs[markersindex].sh_size /sizeof (*mod->markers); +#endif /* Find duplicate symbols */ err =verify_export_symbols (mod);
@@ -2038,6 +2047,8 @@ static struct module *load_module(void _ goto nomodsectinfo;#endif +module_marker_update (mod); +module_immediate_setup (mod); err =module_finalize (hdr, sechdrs, mod);
kernel/marker.c new file +699 -0
699 lines not on this page · raw message
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 3/6 Linux Kernel Markers - Documentation
In reply to Mathieu DesnoyersHere is some documentation explaining what is/how to use the Linux Kernel Markers.
---
Documentation/marker.txt | 257 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 257 insertions(+)
Documentation/marker.txt new file +257 -0
@@ -0,0 +1,257 @@ + 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 your 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 penality (checking a condition for a branch) and space +penality (adding a few bytes for the function call at the end of the +instrumented function and adds a data structure in a separate section). The +immediate values are used to minimize the impact on data cache, encoding the +condition in the instruction stream. 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> + +Add, in your code : + +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. + +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)" + + +* Optimization for a given architecture + +One can implement optimized markers for a given architecture by replacing +asm-$ARCH/marker.h. + +To force use of a non-optimized version of the markers, _trace_mark() should be +used. It takes the same parameters as the normal markers, but it does not use +the immediate values based on code patching. + + +* Probe example + +You can build the kernel modules, probe-example.ko and marker-example.ko, +using the following Makefile: +------------------------------ CUT ------------------------------------- +obj-m := probe-example.o marker-example.o +KDIR := /lib/modules/$(shell uname -r)/build +PWD := $(shell pwd) +default: + $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules +clean: + rm -f *.mod.c *.ko *.o +------------------------------ CUT ------------------------------------- +/* 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 __mark_marker *mdata, + 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("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 __mark_marker *mdata, + 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("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"); +------------------------------ CUT ------------------------------------- +/* 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 = NULL; + +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("Linux Trace Toolkit example"); +------------------------------ CUT ------------------------------------- +Sequence of operations : (as root) +make +insmod marker-example.ko (insmod order is not important) +insmod probe-example.ko +cat /proc/marker-example (returns an expected error) +rmmod marker-example probe-example +dmesg +------------------------------ CUT -------------------------------------
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 2/6 Linux Kernel Markers - Add kconfig menus for the marker code
In reply to Mathieu DesnoyersWith the increasing complexity of today's user-space application and the wide deployment of SMP systems, the users need an increasing understanding of the behavior and performance of a system across multiple processes/different execution contexts/multiple CPUs. In applications such as large clusters (Google, IBM), video acquisition (Autodesk), embedded real-time systems (Wind River, Monta Vista, Sony) or sysadmin/programmer-type tasks (SystemTAP from Redhat), a tool that permits tracing of kernel-user space interaction becomes necessary.
Usage of such tools have been made to successfully pinpoint problems such as:
latency issues in a user-space video acquisition application, slowdown problems in large clusters due to a switch to a different filesystems with a different cache size, abnormal Linux scheduler latency (just to name a few that I have personally investigated).
The currently existing solutions does not give a system-wide overview of what
- and when - things are happening on the system. Ptracing a program works with few processes, but quickly becomes useless when it comes to keeping track of many processes.
Bugs occuring because of bad interaction of such complex systems can be very hard to find due to the fact that they occur rarely (sometimes once a week on hundreds of machines). One can therefore only hope at having the best conditions to statistically reproduce the bug while extracting information from the system. Some bugs have been successfully found at Google using their ktrace tracer only because they could enable it on production machines and therefore recreate the same context where the bug happened.
Therefore, it makes sense to offer an instrumentation set of the most relevant events occurring in the Linux that can have the smallest performance cost possible when not active while not requiring a reboot of a production system to activate. This is essentially what the markers are providing.
Since we cannot limit the growth of the Linux kernel, nor can we pre-determine each and every "interesting" instrumentation within each subsystem and driver, it is sensible to let this task to the persons who knows the best their code. Adding instrumentation should therefore be as easy as adding and maintaining a "printk" in the kernel code from the developer's point of view.
Towards a complete tracing mechanism in the Linux kernel, the markers are only one step forward. The following step is to connect probes to those markers that will record the tracing information in buffers exported to user-space, organized in timestamped "events". Probe callbacks are responsible for serializing the information passed as parameter to the markers (described by the format string) into the events. A control mechanism to activate/stop the tracing is required, as well as a daemon that maps the buffers to write them to disk or send them through the network.
Keeping track of the events also requires a centralized infrastructure : the idea is to assign a unique ID to each event so they can be later recognized in the trace. Keeping in mind that recording the complete instrumentation site name string for each event would be more that inefficient, assigning a numeric unique identifier makes sense.
Finally, support for gathering events coming from user-space, with a minimal performance impact, is very useful to see the interaction between the system's execution contexts.
The last steps are currently implemented in Linux Trace Toolkit Next Generation (LTTng).
The SystemTAP project could clearly benefit from such an infrastructure for tracing. In addition, they would be providing support for dynamic addition of kernel probes through breakpoints/jumps when possible, with the associated restrictions (accessing local variables, reentrancy, speed).
This marker infrastructure is a hook-callback mechanism. It is meant to have an impact as low as possible on the system performances when no callback (probe) is connected so markers (hooks) can be compiled into a production kernel without noticeable slowdown.
Why use the markers instead of kprobes?
The rationale behind this mechanism the following :
1 - It makes sense to have instrumentation (for tracing, profiling)
within the kernel source tree so that it can follow its evolution. Other options, such as kprobes, imply maintaining an external set of instrumentation that must be adapted to each kernel version. Although it may make sense for distributions, it is not well suited for kernel developers, since they rarely work on a major distribution image.
2 - kprobes, although being a very good attempt at providing a dynamic
hooking mechanism that has no impact when disabled, suffers from important limitations :
a - It cannot access local variables of a function at a particular
point within its body that will be consistent thorough the kernel versions without involving a lot of recurrent hair-pulling.
b - Kprobes is slow, since it involves going though a trap each time
a probe site is executed. Even though the djprobes project made a good effort to make things faster, it cannot currently instrument fully-preemptible kernels and does not solve (1), (2a) and (2c).
c - On the reentrancy side, going though a trap (thus playing with
interrupt enable/disable) and taking spinlocks are not suited to some code paths, i.e. :
kernel/lockdep.c, printk (within the lockdep_on()/lockdep_off()). It must be understood that some code paths interesting for instrumentation often present a particular reentrancy challenge.
Some more details :
The probe callback connection to its markers is done dynamically. A predicted branch (see the immediate values infrastructure) is used to skip the hook stack setup and function call when the marker is "disabled" (no probe is connected). Further optimizations can be implemented for each architecture to make this branch faster.
Instrumentation of a subsystem becomes therefore a straightforward task. One has to add instrumentation within the key locations of the kernel code in the following form :
trace_mark(subsystem_event, "%d %p", myint, myptr);
Jim Keniston <[email protected]> adds:
kprobes remains a vital foundation for SystemTap. But markers are attactive as an alternate source of trace/debug info. Here's why:
1. Markers will live in the kernel and presumably be kept up to date by the maintainers of the enclosing code. We have a growing set of tapsets (probe libraries), each of which "knows" the source code for a certain area of the kernel. Whenever the underlying kernel code changes (e.g., a function or one of its args disappears or is renamed), there's a chance that the tapset will become invalid until we bring it back in sync with the kernel. As you can imagine, maintaining tapsets separate from the kernel source is a maintenance headache. Markers could mitigate this.
2. Because the kernel code is highly optimized, the kernel's dwarf info doesn't always accurately reflect which variables have which values on which lines (sometimes even upon entry to a function). A marker is a way to ensure that values of interest are available to SystemTap at marked points.
3. Sometimes the overhead of a kprobe probepoint is too much (either in terms of time or locking) for the particular hotspot we want to probe.
In OLS2006 proceedings, vol. 1
http://www.linuxsymposium.org/2006/linuxsymposium_procv1.pdf
Frank C. Eigler, from SystemTAP, presents its "static probing markers" (pp. 261-268) in his paper "Problem Solving With Systemtap".
He explains the advantages :
"In exchange for this effort, systemtap marker-based probes are faster and
more precise than kprobes. The better precision comes from not having to covet the compiler's favours. Such fickle favours include retaining clean boundaries in the instruction stream between interesting statements, and precisely describing positions of variables in the stack frame. Since markers don't rely on debugging information, neither favour is required, and the compiler can channel its charms into unabated optimization. The speed advantage comes from using direct call instructions rather than int 3 breakpoints to dispatch to the systemtap handlers. We will see below just how big a difference this makes."
He does a comparison of his "simple" marker solution with kprobes (his simple solution looks like my generic markers, but with a major race condition). I also posted numbers about the markers performance impact a few months ago in the initial thread. I can dig into my emails to find them for you if you consider it important for the Changelog.
He concludes with :
"To the extent that is true, we propose that these groups consider using a
shared pool of static markers as the basic kernel-side instrumentation mechanism. If they prove to have as low dormant cost and as high active performance as initial experience suggests, perhaps this could motivate the various tracing efforts and kernel subsystem developers to finally join forces. Let's designate standard trace/probe points once and for all. Tracing backends can attach to these markers the same way systemtap would. There would be no need for them to maintain kernel patches any more. Let's think about it."
This patch:
Add Kconfig menus for the marker code.
---
arch/alpha/Kconfig | 2 ++ arch/arm/Kconfig | 2 ++ arch/avr32/Kconfig.debug | 7 +++++++ arch/cris/Kconfig | 2 ++ arch/frv/Kconfig | 2 ++ arch/h8300/Kconfig | 2 ++ arch/i386/Kconfig | 2 ++ arch/ia64/Kconfig | 2 ++ arch/m32r/Kconfig | 2 ++ arch/m68k/Kconfig | 2 ++ arch/m68knommu/Kconfig | 2 ++ arch/mips/Kconfig | 2 ++ arch/parisc/Kconfig | 2 ++ arch/powerpc/Kconfig | 2 ++ arch/ppc/Kconfig | 2 ++ arch/s390/Kconfig | 2 ++ arch/sh/Kconfig | 2 ++ arch/sh64/Kconfig | 2 ++ arch/sparc/Kconfig | 2 ++ arch/sparc64/Kconfig | 2 ++ arch/um/Kconfig | 2 ++ arch/v850/Kconfig | 2 ++ arch/x86_64/Kconfig | 2 ++ arch/xtensa/Kconfig | 2 ++ kernel/Kconfig.marker | 7 +++++++ kernel/Makefile | 1 + 26 files changed, 61 insertions(+)
arch/alpha/Kconfig +2 -0
@@ -646,6 +646,8 @@ config SRM_ENV source "fs/Kconfig.binfmt" +source "kernel/Kconfig.marker" + endmenu source "net/Kconfig"
arch/arm/Kconfig +2 -0
@@ -1057,6 +1057,8 @@ source "drivers/rtc/Kconfig" source "drivers/dma/Kconfig" +source "kernel/Kconfig.marker" + endmenu source "fs/Kconfig"
arch/cris/Kconfig +2 -0
@@ -151,6 +151,8 @@ source "net/Kconfig" menu "Drivers for built-in interfaces" source arch/cris/arch-v10/drivers/Kconfig +source "kernel/Kconfig.marker" + endmenu source "drivers/base/Kconfig"
arch/frv/Kconfig +2 -0
@@ -367,6 +367,8 @@ menu "Executable formats" source "fs/Kconfig.binfmt" +source "kernel/Kconfig.marker" + endmenu source "net/Kconfig"
arch/h8300/Kconfig +2 -0
@@ -219,6 +219,8 @@ source "drivers/hwmon/Kconfig" source "drivers/usb/Kconfig" +source "kernel/Kconfig.marker" + endmenu source "fs/Kconfig"
arch/i386/Kconfig +2 -0
@@ -1263,6 +1263,8 @@ config KPROBES for kernel debugging, non-intrusive instrumentation and testing. If in doubt, say "N". +source "kernel/Kconfig.marker" + endif # INSTRUMENTATION source "arch/i386/Kconfig.debug"
arch/ia64/Kconfig +2 -0
@@ -537,6 +537,8 @@ source "drivers/pci/hotplug/Kconfig" source "drivers/pcmcia/Kconfig" +source "kernel/Kconfig.marker" + endmenu endif
arch/m32r/Kconfig +2 -0
@@ -418,6 +418,8 @@ menu "Executable file formats" source "fs/Kconfig.binfmt" +source "kernel/Kconfig.marker" + endmenu source "net/Kconfig"
arch/m68k/Kconfig +2 -0
@@ -679,6 +679,8 @@ config SERIAL_CONSOLE If unsure, say N. +source "kernel/Kconfig.marker" + endmenu source "fs/Kconfig"
arch/m68knommu/Kconfig +2 -0
@@ -673,6 +673,8 @@ source "drivers/pcmcia/Kconfig" source "drivers/pci/hotplug/Kconfig" +source "kernel/Kconfig.marker" + endmenu menu "Executable file formats"
arch/mips/Kconfig +2 -0
@@ -1950,6 +1950,8 @@ menu "Power management options" source "kernel/power/Kconfig" +source "kernel/Kconfig.marker" + endmenu source "net/Kconfig"
arch/parisc/Kconfig +2 -0
@@ -259,6 +259,8 @@ menu "Executable file formats" source "fs/Kconfig.binfmt" +source "kernel/Kconfig.marker" + endmenu source "net/Kconfig"
arch/powerpc/Kconfig +2 -0
@@ -495,6 +495,8 @@ source "drivers/pcmcia/Kconfig" source "drivers/pci/hotplug/Kconfig" +source "kernel/Kconfig.marker" + endmenu menu "Advanced setup"
arch/ppc/Kconfig +2 -0
@@ -1303,6 +1303,8 @@ config SERIAL_SICC_CONSOLE depends on SERIAL_SICC && UART0_TTYS1 default y +source "kernel/Kconfig.marker" + endmenu source "lib/Kconfig"
arch/s390/Kconfig +2 -0
@@ -543,6 +543,8 @@ config KPROBES for kernel debugging, non-intrusive instrumentation and testing. If in doubt, say "N". +source "kernel/Kconfig.marker" + endmenu source "arch/s390/Kconfig.debug"
arch/sh/Kconfig +2 -0
@@ -720,6 +720,8 @@ depends on EXPERIMENTAL && SYS_SUPPORTS_ source kernel/power/Kconfig +source "kernel/Kconfig.marker" + endmenu source "net/Kconfig"
arch/sh64/Kconfig +2 -0
@@ -277,6 +277,8 @@ menu "Executable file formats" source "fs/Kconfig.binfmt" +source "kernel/Kconfig.marker" + endmenu source "net/Kconfig"
arch/sparc/Kconfig +2 -0
@@ -316,6 +316,8 @@ config UNIX98_PTY_COUNT When not in use, each additional set of 256 PTYs occupy approximately 8 KB of kernel memory on 32-bit architectures. +source "kernel/Kconfig.marker" + endmenu source "fs/Kconfig"
arch/sparc64/Kconfig +2 -0
@@ -412,6 +412,8 @@ config SOLARIS_EMUL To compile this code as a module, choose M here: the module will be called solaris. +source "kernel/Kconfig.marker" + endmenu config SCHED_SMT
arch/um/Kconfig +2 -0
@@ -253,6 +253,8 @@ config UML_REAL_TIME_CLOCK This could result in a noticeable lag. If this is a problem, then disable this option. +source "kernel/Kconfig.marker" + endmenu source "init/Kconfig"
arch/v850/Kconfig +2 -0
@@ -294,6 +294,8 @@ source "drivers/ide/Kconfig" source "drivers/scsi/Kconfig" +source "kernel/Kconfig.marker" + endmenu #############################################################################
arch/x86_64/Kconfig +2 -0
@@ -827,6 +827,8 @@ config SYSVIPC_COMPAT depends on COMPAT && SYSVIPC default y +source "kernel/Kconfig.marker" + endmenu source "net/Kconfig"
arch/xtensa/Kconfig +2 -0
@@ -226,6 +226,8 @@ config KCORE_ELF source "fs/Kconfig.binfmt" +source "kernel/Kconfig.marker" + endmenu source "net/Kconfig"
kernel/Kconfig.marker new file +7 -0
@@ -0,0 +1,7 @@ +# Code markers configuration + +config MARKERS + bool "Activate markers" + help + Place an empty function call at each marker site. Can be + dynamically changed for a probe function.
arch/avr32/Kconfig.debug +7 -0
@@ -6,6 +6,9 @@ config TRACE_IRQFLAGS_SUPPORT source "lib/Kconfig.debug" +menu "Instrumentation Support" + depends on EXPERIMENTAL + config KPROBES bool "Kprobes" depends on DEBUG_KERNEL
@@ -16,4 +19,8 @@ config KPROBES for kernel debugging, non-intrusive instrumentation and testing. If in doubt, say "N". +source "kernel/Kconfig.marker" + +endmenu + endmenu
kernel/Makefile +1 -0
@@ -62,6 +62,7 @@ obj-$(CONFIG_TASK_DELAY_ACCT) += delayac obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o obj-$(CONFIG_RESOURCE_COUNTERS) += res_counter.o obj-$(CONFIG_IMMEDIATE) += immediate.o +obj-$(CONFIG_MARKERS) += marker.o ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y) # According to Alan Modra <[email protected]>, the -fno-omit-frame-pointer is
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 6/6 Linux Kernel Markers - Port SPU to markers
In reply to Mathieu DesnoyersAndrew, any chance to get this into -mm ASAP so we can have it in 2.6.24?
Just in case anyone wonders what this is usefulfor I've ported my hacking spu tracing code to it, and if markers get in I'd push a cleaned up version of this in the tree of the benefit of everyone trying to follow what's going on in the spufs code. Similarly I'd like to port the xfs tracing code over to it which is very helpful in trying to debug filesystem issues.
Note that in this patch the actual logging code is rather nasty hand-crafted code lifted from the tcp probe in tree which would benefit of going away in favour of more general tracing code aswell.
Changelog:
- Porting to 2.6.23-rc4-mm1 gave a reject (a trace point location disappeared) from spufs_ps_nopfn() : spufs_ps_nopfn__sleep and spufs_ps_nopfn__wake.
--- arch/powerpc/platforms/cell/spufs/Makefile | 2 arch/powerpc/platforms/cell/spufs/file.c | 3 arch/powerpc/platforms/cell/spufs/sched.c | 29 ++- arch/powerpc/platforms/cell/spufs/spufs.h | 5 arch/powerpc/platforms/cell/spufs/sputrace.c | 246 +++++++++++++++++++++++++++ 5 files changed, 279 insertions(+), 6 deletions(-)
arch/powerpc/platforms/cell/spufs/Makefile +2 -0
@@ -4,6 +4,8 @@ obj-$(CONFIG_SPU_FS) += spufs.o spufs-y += inode.o file.o context.o syscalls.o coredump.o spufs-y += sched.o backing_ops.o hw_ops.o run.o gang.o +obj-m += sputrace.o + # Rules to build switch.o with the help of SPU tool chain SPU_CROSS := spu- SPU_CC := $(SPU_CROSS)gcc
arch/powerpc/platforms/cell/spufs/sched.c +23 -6
@@ -39,6 +39,7 @@#include <linux/pid_namespace.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> +#include <linux/marker.h> #include <asm/io.h> #include <asm/mmu_context.h>
@@ -224,8 +225,8 @@ EXPORT_SYMBOL_GPL(spu_switch_event_unreg*/ static void spu_bind_context (struct spu *spu,struct spu_context *ctx) { -pr_debug ("%s: pid=%d SPU=%d NODE=%d\n" , __FUNCTION__, current->pid, - spu->number, spu->node); +spu_context_trace (spu_bind_context__enter, ctx, spu); +spuctx_switch_state (ctx,SPU_UTIL_SYSTEM );if (ctx->flags &SPU_CREATE_NOSCHED )
@@ -412,8 +413,8 @@ static int has_affinity(struct spu_conte*/ static void spu_unbind_context (struct spu *spu,struct spu_context *ctx) { -pr_debug ("%s: unbind pid=%d SPU=%d NODE=%d\n" , __FUNCTION__, - spu->pid, spu->number, spu->node); +spu_context_trace (spu_unbind_context__enter, ctx, spu); +spuctx_switch_state (ctx,SPU_UTIL_SYSTEM );if (spu->ctx->flags &SPU_CREATE_NOSCHED )
@@ -514,6 +515,8 @@ static struct spu *spu_get_idle(struct sstruct spu *spu;int node, n; +spu_context_nospu_trace (spu_get_idle__enter, ctx); +if (has_affinity (ctx)) { node = ctx->gang->aff_ref_spu->node;
@@ -522,7 +525,7 @@ static struct spu *spu_get_idle(struct sif (spu && spu->alloc_state ==SPU_FREE ) goto found;mutex_unlock (&cbe_spu_info[node].list_mutex); -return NULL ; + goto not_found; } node =cpu_to_node (raw_smp_processor_id ());
@@ -539,12 +542,14 @@ static struct spu *spu_get_idle(struct smutex_unlock (&cbe_spu_info[node].list_mutex); } + not_found: +spu_context_nospu_trace (spu_get_idle__not_found, ctx);return NULL ; found: spu->alloc_state =SPU_USED ;mutex_unlock (&cbe_spu_info[node].list_mutex); -pr_debug ("Got SPU %d %d\n" , spu->number, spu->node); +spu_context_trace (spu_get_idle__found, ctx, spu);spu_init_channels (spu);return spu; }
@@ -561,6 +566,8 @@ static struct spu *find_victim(struct spstruct spu *spu;int node, n; +spu_context_nospu_trace (spu_find_vitim__enter, ctx); +/* * Look for a possible preemption candidate on the local node first. * If there is no candidate look at the other nodes. This isn't
@@ -717,6 +724,8 @@ static int __spu_deactivate(struct spu_cif (new || force) {int node = spu->node; +spu_context_trace (__spu_deactivate__unload, ctx, spu); +mutex_lock (&cbe_spu_info[node].list_mutex);spu_unbind_context (spu, ctx); spu->alloc_state =SPU_FREE ;
@@ -744,6 +753,7 @@ static int __spu_deactivate(struct spu_c*/ void spu_deactivate (struct spu_context *ctx) { +spu_context_nospu_trace (spu_deactivate__enter, ctx);__spu_deactivate (ctx,1 ,MAX_PRIO ); }
@@ -757,6 +767,7 @@ void spu_deactivate(struct spu_context **/ void spu_yield (struct spu_context *ctx) { +spu_context_nospu_trace (spu_yield__enter, ctx);if (!(ctx->flags &SPU_CREATE_NOSCHED )) {mutex_lock (&ctx->state_mutex);__spu_deactivate (ctx,0 ,MAX_PRIO );
@@ -783,6 +794,8 @@ static noinline void spusched_tick(strucstruct spu *spu = ctx->spu;struct spu_context *new; +spu_context_trace (spusched_tick__preempt, ctx, spu); + new =grab_runnable_context (ctx->prio +1 , spu->node);if (new) {spu_unbind_context (spu, ctx);
@@ -797,10 +810,14 @@ static noinline void spusched_tick(struc* gets put on the runqueue again ASAP. */ wake_up (&ctx->stop_wq); + }else { +spu_context_trace (spusched_tick__preempt_failed, + ctx, spu); }spu_set_timeslice (ctx);mutex_unlock (&ctx->state_mutex); }else { +spu_context_nospu_trace (spusched_tick__newslice, ctx); ctx->time_slice++; } }
arch/powerpc/platforms/cell/spufs/sputrace.c new file +246 -0
246 lines not on this page · raw message
arch/powerpc/platforms/cell/spufs/file.c +3 -0
@@ -29,6 +29,7 @@#include <linux/poll.h> #include <linux/ptrace.h> #include <linux/seq_file.h> +#include <linux/marker.h> #include <asm/io.h> #include <asm/semaphore.h>
@@ -238,6 +239,8 @@ static unsigned long spufs_ps_nopfn(struunsigned long area, offset = address - vma->vm_start;int ret; +spu_context_nospu_trace (spufs_ps_nopfn__enter, ctx); + offset += vma->vm_pgoff <<PAGE_SHIFT ;if (offset >= ps_size)return NOPFN_SIGBUS ;
arch/powerpc/platforms/cell/spufs/spufs.h +5 -0
@@ -338,4 +338,9 @@ static inline void spuctx_switch_state(s } } +#define spu_context_trace (name, ctx, spu) \ + trace_mark(name, "%p %p", ctx, spu); +#define spu_context_nospu_trace (name, ctx) \ + trace_mark(name, "%p", ctx); +#endif
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 4/6 Linux Kernel Markers - Documentation Fix
In reply to Mathieu DesnoyersWhile porting my code from an older markers version I noticed the marker callbacks have grown a void *private argument. Add it to the documentation aswell.
--- Documentation/marker.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Documentation/marker.txt +1 -1
@@ -115,7 +115,7 @@ struct probe_data { }; void probe_subsystem_event(const struct __mark_marker *mdata, - const char *format, ...) + void *private, const char *format, ...) { va_list ap; /* Declare args */
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 5/6 Port of blktrace to the Linux Kernel Markers.
In reply to Mathieu DesnoyersHere is the first stage of a port of blktrace to the Linux Kernel Markers. The advantage of this port is that it minimizes the impact on the running when blktrace is not active.
A few remarks : this patch has the positive effect of removing some code from the block io tracing hot paths, minimizing the i-cache impact in a system where the io tracing is compiled in but inactive.
It also moves the blk tracing code from a header (and therefore from the body of the instrumented functions) to a separate C file.
There, as soon as one device has to be traced, all devices have to execute the tracing function call when they pass by the instrumentation site. This is slower than the previous inline function which tested the condition quickly.
It does not make the code smaller, since I left all the specialized tracing functions for requests, bio, generic, remap, which would go away once a generic infrastructure is in place to serialize the information passed to the marker. This is mostly why I consider it as a step towards the full improvements that could bring the markers.
---
block/Kconfig | 1 block/blktrace.c | 343 ++++++++++++++++++++++++++++++++++++++++++- block/elevator.c | 6 block/ll_rw_blk.c | 35 ++-- drivers/block/cciss.c | 4 drivers/md/dm.c | 14 - fs/bio.c | 6 include/linux/blktrace_api.h | 145 +----------------- mm/bounce.c | 4 mm/highmem.c | 2 10 files changed, 388 insertions(+), 172 deletions(-)
block/elevator.c +3 -3
@@ -32,7 +32,7 @@#include <linux/init.h> #include <linux/compiler.h> #include <linux/delay.h> -#include <linux/blktrace_api.h> +#include <linux/marker.h> #include <linux/hash.h> #include <asm/uaccess.h>
@@ -548,7 +548,7 @@ void elv_insert(struct request_queue *q,unsigned ordseq;int unplug_it =1 ; -blk_add_trace_rq (q, rq,BLK_TA_INSERT ); +trace_mark (blk_request_insert,"%p %p" , q, rq); rq->q = q;
@@ -735,7 +735,7 @@ struct request *elv_next_request(struct* not be passed by new incoming requests */ rq->cmd_flags |=REQ_STARTED ; -blk_add_trace_rq (q, rq,BLK_TA_ISSUE ); +trace_mark (blk_request_issue,"%p %p" , q, rq); }if (!q->boundary_rq || q->boundary_rq == rq) {
block/ll_rw_blk.c +19 -16
@@ -28,6 +28,7 @@#include <linux/task_io_accounting_ops.h> #include <linux/interrupt.h> #include <linux/cpu.h> +#include <linux/marker.h> #include <linux/blktrace_api.h> #include <linux/fault-inject.h> #include <linux/scatterlist.h>
@@ -1559,7 +1560,7 @@ void blk_plug_device(struct request_queuif (!test_and_set_bit (QUEUE_FLAG_PLUGGED , &q->queue_flags)) {mod_timer (&q->unplug_timer, jiffies + q->unplug_delay); -blk_add_trace_generic (q,NULL ,0 ,BLK_TA_PLUG ); +trace_mark (blk_plug_device,"%p %p %d" , q,NULL ,0 ); } }
@@ -1625,7 +1626,7 @@ static void blk_backing_dev_unplug(struc* devices don't necessarily have an ->unplug_fn defined */ if (q->unplug_fn) { -blk_add_trace_pdu_int (q,BLK_TA_UNPLUG_IO ,NULL , +trace_mark (blk_pdu_unplug_io,"%p %p %d" , q,NULL , q->rq.count[READ ] + q->rq.count[WRITE ]); q->unplug_fn (q);
@@ -1637,7 +1638,7 @@ static void blk_unplug_work(struct work_struct request_queue *q = container_of(work, struct request_queue, unplug_work); -blk_add_trace_pdu_int (q,BLK_TA_UNPLUG_IO ,NULL , +trace_mark (blk_pdu_unplug_io,"%p %p %d" , q,NULL , q->rq.count[READ ] + q->rq.count[WRITE ]); q->unplug_fn (q);
@@ -1647,7 +1648,7 @@ static void blk_unplug_timeout(unsigned {struct request_queue *q = (struct request_queue *)data; -blk_add_trace_pdu_int (q,BLK_TA_UNPLUG_TIMER ,NULL , +trace_mark (blk_pdu_unplug_timer,"%p %p %d" , q,NULL , q->rq.count[READ ] + q->rq.count[WRITE ]);kblockd_schedule_work (&q->unplug_work);
@@ -2160,7 +2161,7 @@ rq_starved:rq_init (q, rq); -blk_add_trace_generic (q, bio, rw,BLK_TA_GETRQ ); +trace_mark (blk_get_request,"%p %p %d" , q, bio, rw); out:return rq; }
@@ -2190,7 +2191,7 @@ static struct request *get_request_wait(if (!rq) {struct io_context *ioc; -blk_add_trace_generic (q, bio, rw,BLK_TA_SLEEPRQ ); +trace_mark (blk_sleep_request,"%p %p %d" , q, bio, rw);__generic_unplug_device (q);spin_unlock_irq (q->queue_lock);
@@ -2264,7 +2265,7 @@ EXPORT_SYMBOL(blk_start_queueing);*/ void blk_requeue_request (struct request_queue *q,struct request *rq) { -blk_add_trace_rq (q, rq,BLK_TA_REQUEUE ); +trace_mark (blk_requeue,"%p %p" , q, rq);if (blk_rq_tagged (rq))blk_queue_end_tag (q, rq);
@@ -2987,7 +2988,7 @@ static int __make_request(struct requestif (!ll_back_merge_fn (q, req, bio))break ; -blk_add_trace_bio (q, bio,BLK_TA_BACKMERGE ); +trace_mark (blk_bio_backmerge,"%p %p" , q, bio); req->biotail->bi_next = bio; req->biotail = bio;
@@ -3004,7 +3005,7 @@ static int __make_request(struct requestif (!ll_front_merge_fn (q, req, bio))break ; -blk_add_trace_bio (q, bio,BLK_TA_FRONTMERGE ); +trace_mark (blk_bio_frontmerge,"%p %p" , q, bio); bio->bi_next = req->bio; req->bio = bio;
@@ -3087,9 +3088,10 @@ static inline void blk_partition_remap(s bio->bi_sector += p->start_sect; bio->bi_bdev = bdev->bd_contains; -blk_add_trace_remap (bdev_get_queue (bio->bi_bdev), bio, - bdev->bd_dev, bio->bi_sector, - bio->bi_sector - p->start_sect); +trace_mark (blk_remap,"%p %p %llu %llu %llu" , +bdev_get_queue (bio->bi_bdev), bio, + (u64 )bdev->bd_dev, (u64 )bio->bi_sector, + (u64 )bio->bi_sector - p->start_sect); } }
@@ -3254,10 +3256,11 @@ end_io:blk_partition_remap (bio);if (old_sector !=-1 ) -blk_add_trace_remap (q, bio, old_dev, bio->bi_sector, - old_sector); +trace_mark (blk_remap,"%p %p %llu %llu %llu" , + q, bio, (u64 )old_dev, + (u64 )bio->bi_sector, (u64 )old_sector); -blk_add_trace_bio (q, bio,BLK_TA_QUEUE ); +trace_mark (blk_bio_queue,"%p %p" , q, bio); old_sector = bio->bi_sector; old_dev = bio->bi_bdev->bd_dev;
@@ -3446,7 +3449,7 @@ static int __end_that_request_first(struint total_bytes, bio_nbytes, error, next_idx =0 ;struct bio *bio; -blk_add_trace_rq (req->q, req,BLK_TA_COMPLETE ); +trace_mark (blk_request_complete,"%p %p" , req->q, req);/* * extend uptodate bool to allow < 0 value to be direct io error
block/Kconfig +1 -0
@@ -32,6 +32,7 @@ config BLK_DEV_IO_TRACE depends on SYSFS select RELAY select DEBUG_FS + select MARKERS help Say Y here, if you want to be able to trace the block layer actions on a given queue. Tracing allows you to see any traffic happening
block/blktrace.c +341 -2
380 lines not on this page · raw message
include/linux/blktrace_api.h +9 -136
165 lines not on this page · raw message
mm/bounce.c +2 -2
@@ -13,7 +13,7 @@#include <linux/init.h> #include <linux/hash.h> #include <linux/highmem.h> -#include <linux/blktrace_api.h> +#include <linux/marker.h> #include <asm/tlbflush.h> #define POOL_SIZE 64
@@ -237,7 +237,7 @@ static void __blk_queue_bounce(struct reif (!bio)return ; -blk_add_trace_bio (q, *bio_orig,BLK_TA_BOUNCE ); +trace_mark (blk_bio_bounce,"%p %p" , q, *bio_orig);/* * at least one page was bounced, fill in possible non-highmem
mm/highmem.c +1 -1
@@ -26,7 +26,7 @@#include <linux/init.h> #include <linux/hash.h> #include <linux/highmem.h> -#include <linux/blktrace_api.h> +#include <linux/marker.h> #include <asm/tlbflush.h> /*
fs/bio.c +3 -3
@@ -25,7 +25,7 @@#include <linux/module.h> #include <linux/mempool.h> #include <linux/workqueue.h> -#include <linux/blktrace_api.h> +#include <linux/marker.h> #include <scsi/sg.h> /* for struct sg_iovec */ #define BIO_POOL_SIZE 2
@@ -1072,8 +1072,8 @@ struct bio_pair *bio_split(struct bio *bif (!bp)return bp; -blk_add_trace_pdu_int (bdev_get_queue (bi->bi_bdev),BLK_TA_SPLIT , bi, - bi->bi_sector + first_sectors); +trace_mark (blk_pdu_split,"%p %p %llu" ,bdev_get_queue (bi->bi_bdev), bi, + (u64 )bi->bi_sector + first_sectors);BUG_ON (bi->bi_vcnt !=1 );BUG_ON (bi->bi_idx !=0 );
drivers/block/cciss.c +2 -2
@@ -37,7 +37,7 @@#include <linux/hdreg.h> #include <linux/spinlock.h> #include <linux/compat.h> -#include <linux/blktrace_api.h> +#include <linux/marker.h> #include <asm/uaccess.h> #include <asm/io.h>
@@ -2545,7 +2545,7 @@ after_error_processing: } cmd->rq->data_len =0 ; cmd->rq->completion_data = cmd; -blk_add_trace_rq (cmd->rq->q, cmd->rq,BLK_TA_COMPLETE ); +trace_mark (blk_request_complete,"%p %p" , cmd->rq->q, cmd->rq);blk_complete_request (cmd->rq); }
drivers/md/dm.c +7 -7
@@ -19,7 +19,7 @@#include <linux/slab.h> #include <linux/idr.h> #include <linux/hdreg.h> -#include <linux/blktrace_api.h> +#include <linux/marker.h> #include <linux/smp_lock.h> #define DM_MSG_PREFIX "core"
@@ -481,8 +481,8 @@ static void dec_pending(struct dm_io *iowake_up (&io->md->wait);if (io->error !=DM_ENDIO_REQUEUE ) { -blk_add_trace_bio (io->md->queue, io->bio, -BLK_TA_COMPLETE ); +trace_mark (blk_request_complete,"%p %p" , + io->md->queue, io->bio);bio_endio (io->bio, io->bio->bi_size, io->error); }
@@ -578,10 +578,10 @@ static void __map_bio(struct dm_target * r = ti->type->map (ti, clone, &tio->info);if (r ==DM_MAPIO_REMAPPED ) {/* the bio has been remapped so dispatch it */ - -blk_add_trace_remap (bdev_get_queue (clone->bi_bdev), clone, - tio->io->bio->bi_bdev->bd_dev, - clone->bi_sector, sector); +trace_mark (blk_remap,"%p %p %llu %llu %llu" , +bdev_get_queue (clone->bi_bdev), clone, + (u64 )tio->io->bio->bi_bdev->bd_dev, (u64 )sector, + (u64 )clone->bi_sector);generic_make_request (clone); }else if (r <0 || r ==DM_MAPIO_REQUEUE ) {
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Re: [patch 1/6] Linux Kernel Markers - Architecture Independent Code
In reply to Mathieu DesnoyersQuoted 7 lines · On Thu, 06 Sep 2007 16:07:34 -0400 Mathieu Desnoyers wrote:
Changelog:
-markers_mutexnow nests insidemodule_mutexrather than the opposite.Signed-off-by Mathieu Desnoyers <[email protected]>Reviewed-by Christoph Hellwig <[email protected]>Reviewed-by Rusty Russell <[email protected]>Reviewed-by "Frank Ch. Eigler" <[email protected]>
Documentation/SubmittingPatches recognizes Signed-off-by: and Acked-by:. Nothing about Reviewed-by. Quote:
Acked-by: is not as formal as Signed-off-by:. It is a record that the acker has at least reviewed the patch and has indicated acceptance.
Reviewed-by: carries no such connotation or indication IMO. Please use Acked-by if that's what these reviewers have done.
Quoted 15 lines
---
include/asm-generic/vmlinux.lds.h | 11 include/linux/marker.h | 169 +++++++++ include/linux/module.h | 5 kernel/marker.c | 699 ++++++++++++++++++++++++++++++++++++++ kernel/module.c | 11 5 files changed, 894 insertions(+), 1 deletion(-)Index:
linux-2.6-lttng/include/linux/marker.h
===================================================================
include/linux/marker.h line 140
Quoted 3 lines
include/linux/marker.h new file +2
-0@@ -0,0 +1,169 @@ +/* +* Connect a probe to a markers.
marker.
Quoted 10 lines
+ * pdata must be a valid allocated memory address, or NULL.
+ */include/linux/marker.h new file +2
-0+extern int marker_probe_register (const char *name,const char *format, +marker_probe_func *probe,void *pdata);Index:
linux-2.6-lttng/kernel/marker.c
===================================================================
kernel/marker.c line 5
Quoted 5 lines
kernel/marker.c new file +5
-0@@ -0,0 +1,699 @@ +/* +* Marker deferred synchronization. +* Upon marker probe_unregister, we delay call to synchronize_sched() to +* accelerate mass unregistration (only when there is no more reference to a +* give module do we call synchronize_sched()). However, we need to make sure
given
kernel/marker.c line 42
Quoted 1 line
kernel/marker.c new file +1
-0+* every critical region have ended before we re-arm a marker that has been
has
Quoted 20 lines
kernel/marker.c new file +20
-0+* unregistered and then registered back with a different probe data. +*/ +static int deferred_sync; + +/* +* Marker hash table, containing the active markers. +* Protected by module_mutex. +*/ +#define MARKER_HASH_BITS 6 +#define MARKER_TABLE_SIZE (1 << MARKER_HASH_BITS) + +struct marker_entry { +struct hlist_node hlist; +char *format; +marker_probe_func *probe; +void *pdata; +int refcount;/* Number of times armed. 0 if disarmed. */ +char name[0 ];/* Contains name'\0'format'\0' */ +}; +
kernel/marker.c line 72
Quoted 10 lines
kernel/marker.c new file +10
-0+static struct hlist_head marker_table[MARKER_TABLE_SIZE ]; + +/** +* __mark_empty_function - Empty probe callback +* @mdata: pointer of type const struct __mark_marker +* @fmt: format string +* @...: variable argument list +* +* Empty callback provided as a probe to the markers. By providing this to a +* disabled marker, we makes sure the execution flow is always valid even
make
Quoted 8 lines
kernel/marker.c new file +8
-0+* though the function pointer change and the marker enabling are two distinct +* operations that modifies the execution flow of preemptible code. +*/ +void __mark_empty_function (const struct __mark_marker *mdata, +void *private_data, +const char *fmt, ...) +{ } +EXPORT_SYMBOL_GPL (__mark_empty_function);
kernel/marker.c
Quoted 10 lines
kernel/marker.c new file +8
-0+/* +* Sets the probe callback corresponding to one marker. +*/ +static int set_marker (struct marker_entry **entry, +struct __mark_marker *elem) +{ +int ret; +BUG_ON (strcmp ((*entry)->name, elem->name) !=0 );
You can't return -ENOENT here?
Quoted 25 lines
kernel/marker.c new file +25
-0+ +if ((*entry)->format) { +if (strcmp ((*entry)->format, elem->format) !=0 ) { +printk (KERN_NOTICE +"Format mismatch for probe %s " +"(%s), marker (%s)\n" , + (*entry)->name, + (*entry)->format, + elem->format); +return -EPERM ; + } + }else { + ret =marker_set_format (entry, elem->format); +if (ret) +return ret; + } + elem->call = (*entry)->probe; + elem->pdata = (*entry)->pdata; +_immediate_set (&elem->state,1 ); +return 0 ; +} + +/* +* Disable a marker and its probe callback. +* Note: only after a synchronize_sched() issued after setting elem->call to the
kernel/marker.c line 249
Quoted 10 lines
kernel/marker.c new file +10
-0+* empty function insures that the original callback is not used anymore. This +* insured by preemption disabling around the call site. +*/ +static void disable_marker (struct __mark_marker *elem) +{ +_immediate_set (&elem->state,0 ); + elem->call = __mark_empty_function; +/* +* Leave the pdata and id there, because removal is racy and should be +* done only after a synchronize_sched(). There are never used until
These
Quoted 13 lines
kernel/marker.c new file +12
-0+* the next initialization anyway. +*/ +} + +#ifdef CONFIG_MODULES +/* +* Update module probes. +* Must be called with markers_mutex held. +*/ +static inline void marker_update_probes_modules (struct module *probe_module, +int *refcount) +{
kernel/marker.c line 301
Quoted 10 lines
kernel/marker.c new file +10
-0+struct module *mod; + +list_for_each_entry (mod, &modules, list) { +if (!mod->taints) { +marker_update_probe_range (mod->markers, + mod->markers+mod->num_markers, + probe_module, refcount); + } + } +}
hm, so if the module is tainted, markers won't be applied to it? That's OK IMO. However, I tend to think that something that modifies code on the fly (like kprobes or text edit) should set some flag somewhere so that when the system crashes, we can know that code was modified. This could be done via taints flags or some other mechanism. Has this already been discussed?
Quoted 19 lines
kernel/marker.c new file +19
-0+#else +static inline void marker_update_probes_modules (struct module *probe_module, +int *refcount) +{ } +#endif + +/* +* Update probes, removing the faulty probes. +* Issues a synchronize_sched() when no reference to the module passed +* as parameter is found in the probes so the probe module can be +* safely unloaded from now on. +*/ +static inline void _marker_update_probes (struct module *probe_module) +{ +int refcount =0 ; + +/* Core kernel markers */ +marker_update_probe_range (__start___markers, + __stop___markers, probe_module, &refcount);
kernel/marker.c
Quoted 10 lines
kernel/marker.c new file +9
-0+/* Markers in modules. */ +marker_update_probes_modules (probe_module, &refcount); +if (probe_module && refcount ==0 ) { +synchronize_sched (); + deferred_sync =0 ; + } +} +/** +* marker_probe_unregister - Disconnect a probe from a marker
wrong function name above.
Quoted 7 lines
+ * @pdata: probe private data
+ *
+ * Unregister a marker by providing the registered pdata.
+ * Returns the pdata given tomarker_probe_register, or anERR_PTR().
+ */kernel/marker.c new file +2
-0+void *marker_probe_unregister_pdata (void *pdata) +{
...
kernel/marker.c
Quoted 2 lines
kernel/marker.c new file +2
-0+} +EXPORT_SYMBOL_GPL (marker_probe_unregister_pdata);
---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***
Andrew Morton
maintainerRe: [patch 1/6] Linux Kernel Markers - Architecture Independent Code
Quoted 11 lines · On Thu, 6 Sep 2007 16:00:01 -0700 Randy Dunlap <[email protected]> wrote:
Quoted 7 lines · On Thu, 06 Sep 2007 16:07:34 -0400 Mathieu Desnoyers wrote:
Changelog:
-markers_mutexnow nests insidemodule_mutexrather than the opposite.Signed-off-by Mathieu Desnoyers <[email protected]>Reviewed-by Christoph Hellwig <[email protected]>Reviewed-by Rusty Russell <[email protected]>Reviewed-by "Frank Ch. Eigler" <[email protected]>
Quoted 8 lines
Documentation/SubmittingPatchesrecognizes Signed-off-by: and Acked-by:. Nothing about Reviewed-by. Quote:Acked-by: is not as formal as Signed-off-by:. It is a record that the acker has at least reviewed the patch and has indicated acceptance.
Reviewed-by: carries no such connotation or indication IMO. Please use Acked-by if that's what these reviewers have done.
Yeah. We will start introducing Reviewed-by: (I haven't yet quite worked out how yet) but it will be a quite formal thing and it would be something which the reviewer explicitly provided. For now, let's please stick with acked-by (if those individuals did indeed send an acked-by)
Re: [patch 1/6] Linux Kernel Markers - Architecture Independent Code
Quoted 17 lines · On Thu, 6 Sep 2007 16:04:29 -0700 Andrew Morton wrote:
Quoted 17 lines · On Thu, 6 Sep 2007 16:00:01 -0700 Randy Dunlap <[email protected]> wrote:
Quoted 7 lines · On Thu, 06 Sep 2007 16:07:34 -0400 Mathieu Desnoyers wrote:
Changelog:
-markers_mutexnow nests insidemodule_mutexrather than the opposite.Signed-off-by Mathieu Desnoyers <[email protected]>Reviewed-by Christoph Hellwig <[email protected]>Reviewed-by Rusty Russell <[email protected]>Reviewed-by "Frank Ch. Eigler" <[email protected]>
Documentation/SubmittingPatchesrecognizes Signed-off-by: and Acked-by:. Nothing about Reviewed-by. Quote:Acked-by: is not as formal as Signed-off-by:. It is a record that the acker has at least reviewed the patch and has indicated acceptance.
Quoted 8 lines
Quoted 2 lines
Reviewed-by: carries no such connotation or indication IMO. Please use Acked-by if that's what these reviewers have done.
Yeah. We will start introducing Reviewed-by: (I haven't yet quite worked out how yet) but it will be a quite formal thing and it would be something which the reviewer explicitly provided. For now, let's please stick with acked-by (if those individuals did indeed send an acked-by)
-
Thanks. I look forward to the explanation of Reviewed-by, what it means, and how it differs from Acked-by.
---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***
Re: [patch 2/6] Linux Kernel Markers - Add kconfig menus for the marker code
In reply to Mathieu DesnoyersOn Thu, 06 Sep 2007 16:07:35 -0400 Mathieu Desnoyers wrote:
[snip]
Quoted 79 lines
This patch:
Add
Kconfigmenus for the marker code.[[email protected]: Never ever select MODULES]Signed-off-by Mathieu Desnoyers <[email protected]>Reviewed-by Christoph Hellwig <[email protected]>Reviewed-by "Frank Ch. Eigler" <[email protected]>CC Adrian Bunk <[email protected]>---
arch/alpha/Kconfig | 2 ++ arch/arm/Kconfig | 2 ++ arch/avr32/Kconfig.debug | 7 +++++++ arch/cris/Kconfig | 2 ++ arch/frv/Kconfig | 2 ++ arch/h8300/Kconfig | 2 ++ arch/i386/Kconfig | 2 ++ arch/ia64/Kconfig | 2 ++ arch/m32r/Kconfig | 2 ++ arch/m68k/Kconfig | 2 ++ arch/m68knommu/Kconfig | 2 ++ arch/mips/Kconfig | 2 ++ arch/parisc/Kconfig | 2 ++ arch/powerpc/Kconfig | 2 ++ arch/ppc/Kconfig | 2 ++ arch/s390/Kconfig | 2 ++ arch/sh/Kconfig | 2 ++ arch/sh64/Kconfig | 2 ++ arch/sparc/Kconfig | 2 ++ arch/sparc64/Kconfig | 2 ++ arch/um/Kconfig | 2 ++ arch/v850/Kconfig | 2 ++ arch/x86_64/Kconfig | 2 ++ arch/xtensa/Kconfig | 2 ++ kernel/Kconfig.marker | 7 +++++++ kernel/Makefile | 1 + 26 files changed, 61 insertions(+)Index: linux-2.6-lttng/arch/alpha/Kconfig
===================================================================arch/alpha/Kconfig +2
-0@@ -646,6 +646,8 @@ config SRM_ENV source "fs/Kconfig.binfmt" +source "kernel/Kconfig.marker" + endmenu source "net/Kconfig"Index: linux-2.6-lttng/kernel/Kconfig.marker
===================================================================kernel/Kconfig.marker new file +7
-0@@ -0,0 +1,7 @@ +# Code markers configuration + +config MARKERS + bool "Activate markers" + help + Place an empty function call at each marker site. Can be + dynamically changed for a probe function.Index: linux-2.6-lttng/arch/avr32/Kconfig.debug
===================================================================arch/avr32/Kconfig.debug +3
-0@@ -6,6 +6,9 @@ config TRACE_IRQFLAGS_SUPPORT source "lib/Kconfig.debug" +menu "Instrumentation Support" + depends on EXPERIMENTAL + config KPROBES bool "Kprobes" depends on DEBUG_KERNEL
arch/avr32/Kconfig.debug config KPROBES · line 26
Quoted 8 lines
arch/avr32/Kconfig.debug +4
-0@@ -16,4 +19,8 @@ config KPROBES for kernel debugging, non-intrusive instrumentation and testing. If in doubt, say "N". +source "kernel/Kconfig.marker" + +endmenu + endmenu
It seems sad that this patch sources Kconfig.marker, a 7-line file, 20-something times. Yes, you (we) don't want to put those 7 lines into 20-something different files, so sourcing is the right thing.
However, what you did for avr32 seems more on the right track to me:
make _one_ Instrumentation support menu that includes PROFILING, OPROFILE, KPROBES, and MARKERS and then use (source) that in all of the arches.
---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***
Re: [patch 3/6] Linux Kernel Markers - Documentation
In reply to Mathieu DesnoyersQuoted 15 lines · On Thu, 06 Sep 2007 16:07:36 -0400 Mathieu Desnoyers wrote:
Here is some documentation explaining what is/how to use the Linux Kernel Markers.
---Documentation/marker.txt | 257 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 257 insertions(+)Index:
linux-2.6-lttng/Documentation/marker.txt
===================================================================Documentation/marker.txt new file +3
-0@@ -0,0 +1,257 @@ + Using the Linux Kernel Markers + + Mathieu Desnoyers
Documentation/marker.txt line 13
Quoted 10 lines
Documentation/marker.txt new file +10
-0+ + +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 your code provides a hook to call a function (probe) that
^^^^ I would drop "your". It quite likely
could be someone else's code.
Documentation/marker.txt line 16
Quoted 3 lines
Documentation/marker.txt new file +3
-0+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 penality (checking a condition for a branch) and space
penalty
Documentation/marker.txt line 17
Quoted 1 line
Documentation/marker.txt new file +1
-0+penality (adding a few bytes for the function call at the end of the
penalty
Quoted 11 lines
Documentation/marker.txt new file +11
-0+instrumented function and adds a data structure in a separate section). The +immediate values are used to minimize the impact on data cache, encoding the +condition in the instruction stream. 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. +
Documentation/marker.txt line 38
Quoted 10 lines
Documentation/marker.txt new file +10
-0+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> + +Add, in your code :
And,
Quoted 34 lines
Documentation/marker.txt new file +34
-0+ +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. + +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)" + + +* Optimization for a given architecture
Documentation/marker.txt line 82
Quoted 10 lines
Documentation/marker.txt new file +10
-0+ +One can implement optimized markers for a given architecture by replacing +asm-$ARCH/marker.h. + +To force use of a non-optimized version of the markers, _trace_mark() should be +used. It takes the same parameters as the normal markers, but it does not use +the immediate values based on code patching. + + +* Probe example
I would much prefer that you put marker-related docs into Documentation/marker[s]/ and then put the Makefile and source files into Documentation/marker[s]/src/.
This make the source files more visible (findable, grepable) to other developers & users. It also makes it feasible to use and test them on a regular basis so that API changes (=> bugs:) can be easily found and fixed.
And then you can drop those "CUT" lines. :)
Quoted 164 lines
Documentation/marker.txt new file +164
-0+You can build the kernel modules, probe-example.ko and marker-example.ko, +using the following Makefile: +------------------------------ CUT ------------------------------------- +obj-m := probe-example.o marker-example.o +KDIR := /lib/modules/$(shell uname -r)/build +PWD := $(shell pwd) +default: + $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules +clean: + rm -f *.mod.c *.ko *.o +------------------------------ CUT ------------------------------------- +/* 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 __mark_marker *mdata, + 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("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 __mark_marker *mdata, + 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("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"); +------------------------------ CUT ------------------------------------- +/* 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 = NULL; + +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");
Documentation/marker.txt line 257
Quoted 10 lines
Documentation/marker.txt new file +10
-0+MODULE_DESCRIPTION("Linux Trace Toolkit example"); +------------------------------ CUT ------------------------------------- +Sequence of operations : (as root) +make +insmod marker-example.ko (insmod order is not important) +insmod probe-example.ko +cat /proc/marker-example (returns an expected error) +rmmod marker-example probe-example +dmesg +------------------------------ CUT -------------------------------------
---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***
Re: [patch 1/6] Linux Kernel Markers - Architecture Independent Code
In reply to Randy DunlapQuoted 2 lines · Randy Dunlap
Thanks. I look forward to the explanation of Reviewed-by, what it means, and how it differs from Acked-by.
As long as you're at it, the only tag *I* seem to need is 'Tested-By:' :)
Re: [patch 1/6] Linux Kernel Markers - Architecture Independent Code
Quoted 6 lines · [email protected] wrote:
Quoted 2 lines · Randy Dunlap
Thanks. I look forward to the explanation of Reviewed-by, what it means, and how it differs from Acked-by.
As long as you're at it, the only tag *I* seem to need is 'Tested-By:' :)
Yep, and that's a good one IMO.
Signature · 2 lines
~Randy *** Remember to use Documentation/SubmitChecklist when testing your code ***
Re: [patch 1/6] Linux Kernel Markers - Architecture Independent Code
In reply to Randy Dunlap* Randy Dunlap ([email protected]) wrote:
[snip]
Quoted 12 lines
kernel/marker.c line 214
Quoted 9 lines
kernel/marker.c new file +8
-0+/* +* Sets the probe callback corresponding to one marker. +*/ +static int set_marker (struct marker_entry **entry, +struct __mark_marker *elem) +{ +int ret; +BUG_ON (strcmp ((*entry)->name, elem->name) !=0 );You can't return
-ENOENThere?
I could, but it's really a bug: if this condition happens, there would be an inconsistency in the hash table get_marker() function. Therefore I prefer to yell if this happens rather than simply telling the caller that the entry does not exist.
And actually, marker_update_probe_range ignores errors from set_marker (there is even a comment saying that in the code) :
if (mark_entry && mark_entry->refcount) {
set_marker(&mark_entry, iter);
/*
* ignore error, continue
*/It is done on purpose: if a marker does not have the right arguments, it will simply be skipped and a printk warning will be emitted. I prefer this approach rather than stopping marker activation/disactivation as soon as a bad marker is found.
[...]
Quoted 13 lines
Quoted 13 lines
kernel/marker.c new file +13
-0+#ifdef CONFIG_MODULES +/* +* Update module probes. +* Must be called with markers_mutex held. +*/ +static inline void marker_update_probes_modules (struct module *probe_module, +int *refcount) +{ +struct module *mod; + +list_for_each_entry (mod, &modules, list) { +if (!mod->taints) { + marker_update_probe_range(mod->markers,
Quoted 8 lines
kernel/marker.c line 301
Quoted 5 lines
kernel/marker.c new file +5
-0+ mod->markers+mod->num_markers, + probe_module, refcount); + } + } +}hm, so if the module is tainted, markers won't be applied to it? That's OK IMO.
Yep,
Quoted 6 lines
However, I tend to think that something that
modifies code on the fly (like kprobes or text edit) should set some flag somewhere so that when the system crashes, we can know that code was modified. This could be done via taints flags or some other mechanism. Has this already been discussed?
I am not aware of discussions about this. But then we would have to do the same for paravirt, alternatives, kprobes and immediate values.
As soon as the kernel code of a crashing kernel may have been modified in memory, the image of the crashed kernel should be used instead of the compiled image to analyze the crash. But code patching becomes so common that we will have to start using core dumps more and more.
Yes, your idea makes sense. printking that kind of information in a OOPS would be useful IMO.
Mathieu
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Re: [patch 1/6] Linux Kernel Markers - Architecture Independent Code
In reply to Randy DunlapQuoted 2 lines · Randy Dunlap
Thanks. I look forward to the explanation of Reviewed-by, what it means, and how it differs from Acked-by.
This was proposed by Andrew and discussed at the Kernel Summit; the basic idea is that it is a formal indication that the person has done a *full* review of the patch (a few random comments from the local whitespace police don't count), and is willing to vouch that the patch is correct, safe, extremely unlikely to cause regressions, etc. If the patch does need to be reverted or fixed because it was buggy, then both the original submitter and the reviewer would bear responsibility and subsystem maintainers might take that into account when assessing the reputations of the submitter and reviewer in the future when deciding whether or not to accept a patch.
Basically, some people seem to be using "Acked-by" to mean, "seems good to me", without necessarily doing a full review of the patch, and instead of trying to change the meaning of "Acked-by", to have a new sign off which is a bit more explicitly about what it means. (Hmmm, thinking about it afterwards, maybe "Vouched-by:" would be even better....)
There was some thought about negative attention (i.e., "public mockery") given to people who sign off on a patch via Reviewed-by:
that subsequently turns out to be buggy or cause a regression, but the concern with that is that we have enough trouble finding people to review patches, and we wouldn't want to scare off reviewers. But it would be fair to say that the consequences of reviewing patches successfully or unsuccessfully would naturally impact people's reputations.
There was also some discussion about whether or not patches would not be accepted at all without a Reviewed-by, but that probably won't happen initially. The general consensus was to gently ease into it and see how well it works first.
- Ted
Re: [patch 1/6] Linux Kernel Markers - Architecture Independent Code
Quoted 4 lines · Theodore Tso
This was proposed by Andrew and discussed at the Kernel Summit; the basic idea is that it is a formal indication that the person has done a *full* review of the patch (a few random comments from the local whitespace police don't count),
Anybody got a proposed scheme for the case where somebody like myself who is *not* a member of the Maintainer Cabal has looked at a patch, and found a valid show-stopper that's bigger than just whitespace (breaks on 64-bit, locking issues, etc), or other commentary that *should* be addressed before it gets merged? I'd like *some* way to tag a patch with "I had an issue with V1, but the author addressed it to my satisfaction in V2"....
(Note that includes "the author convinced me the patch was right and I was wrong"...)
Re: [patch 1/6] Linux Kernel Markers - Architecture Independent Code
Quoted 9 lines · On Fri, Sep 07, 2007 at 01:10:54PM -0400, [email protected] wrote:
Anybody got a proposed scheme for the case where somebody like myself who is *not* a member of the Maintainer Cabal has looked at a patch, and found a valid show-stopper that's bigger than just whitespace (breaks on 64-bit, locking issues, etc), or other commentary that *should* be addressed before it gets merged? I'd like *some* way to tag a patch with "I had an issue with V1, but the author addressed it to my satisfaction in V2"....
(Note that includes "the author convinced me the patch was right and I was wrong"...)
I think that'd be Reviewed-By. While you are not part of the smokey room cabal you have shown technical expertise in various areas so it seems perfectly fine to have reviewed-by from you. The fix vs a previous version should probably be just in the text with a paragraph ala:
Issue blah in a previous version as found by Valdis Kletnieks has been fixed by doing foo.
Re: [patch 1/6] Linux Kernel Markers - Architecture Independent Code
Quoted 7 lines
Quoted 6 lines
Anybody got a proposed scheme for the case where somebody like myself who is *not* a member of the Maintainer Cabal has looked at a patch, and found a valid show-stopper that's bigger than just whitespace (breaks on 64-bit, locking issues, etc), or other commentary that *should* be addressed before it gets merged? I'd like *some* way to tag a patch with "I had an issue with V1, but the author addressed it to my satisfaction in V2"....
Quoted 7 lines
I think that'd be Reviewed-By. While you are not part of the smokey room cabal you have shown technical expertise in various areas so it seems perfectly fine to have reviewed-by from you. The fix vs a previous version should probably be just in the text with a paragraph ala:
Issue blah in a previous version as found by Valdis Kletnieks has been fixed by doing foo.
At ksummit Andrew also mentioned including a link to the relevant mailing list discussion too, and I think this would be a good example of when that would be useful.
- R.
Re: [patch 6/6] Linux Kernel Markers - Port SPU to markers
In reply to Mathieu DesnoyersQuoted 10 lines · Mathieu Desnoyers
Andrew, any chance to get this into -mm ASAP so we can have it in 2.6.24?
Just in case anyone wonders what this is usefulfor I've ported my hacking spu tracing code to it, and if markers get in I'd push a cleaned up version of this in the tree of the benefit of everyone trying to follow what's going on in the spufs code. Similarly I'd like to port the xfs tracing code over to it which is very helpful in trying to debug filesystem issues.
Quoted 8 lines
Note that in this patch the actual logging code is rather nasty hand-crafted code lifted from the tcp probe in tree which would benefit of going away in favour of more general tracing code aswell.
Changelog:
- Porting to 2.6.23-rc4-mm1 gave a reject (a trace point location disappeared) fromspufs_ps_nopfn():spufs_ps_nopfn__sleepandspufs_ps_nopfn__wake.Signed-off-by Mathieu Desnoyers <[email protected]>
Where are Christoph's attributions?
Re: [patch 6/6] Linux Kernel Markers - Port SPU to markers
Quoted 15 lines · * Alexey Dobriyan ([email protected]) wrote:
Quoted 14 lines · Mathieu Desnoyers
Andrew, any chance to get this into -mm ASAP so we can have it in 2.6.24?
Just in case anyone wonders what this is usefulfor I've ported my hacking spu tracing code to it, and if markers get in I'd push a cleaned up version of this in the tree of the benefit of everyone trying to follow what's going on in the spufs code. Similarly I'd like to port the xfs tracing code over to it which is very helpful in trying to debug filesystem issues.
Note that in this patch the actual logging code is rather nasty hand-crafted code lifted from the tcp probe in tree which would benefit of going away in favour of more general tracing code aswell.
Quoted 6 lines
Quoted 4 lines
Changelog:
- Porting to 2.6.23-rc4-mm1 gave a reject (a trace point location disappeared) fromspufs_ps_nopfn():spufs_ps_nopfn__sleepandspufs_ps_nopfn__wake.Signed-off-by Mathieu Desnoyers <[email protected]>Where are Christoph's attributions?
I realized only after sending this patch set that the
From: Christoph Hellwig <[email protected]>
Has somehow been stripped off from the patch header.
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Re: [patch 6/6] Linux Kernel Markers - Port SPU to markers
In reply to Mathieu DesnoyersQuoted 10 lines · Mathieu Desnoyers
Andrew, any chance to get this into -mm ASAP so we can have it in 2.6.24?
Just in case anyone wonders what this is usefulfor I've ported my hacking spu tracing code to it, and if markers get in I'd push a cleaned up version of this in the tree of the benefit of everyone trying to follow what's going on in the spufs code. Similarly I'd like to port the xfs tracing code over to it which is very helpful in trying to debug filesystem issues.
Quoted 7 lines
Note that in this patch the actual logging code is rather nasty hand-crafted code lifted from the tcp probe in tree which would benefit of going away in favour of more general tracing code aswell.
Changelog:
- Porting to 2.6.23-rc4-mm1 gave a reject (a trace point location disappeared) fromspufs_ps_nopfn():spufs_ps_nopfn__sleepandspufs_ps_nopfn__wake.
The subject is rather confusing. What I ported to markers is the spu _tracing_ support. And given it's never been public before adding the port part to the commit doesn't make much sense.
Nevermind, I have updated version of this and would prefer to submit it myself through the spufs maintainer once markers make mainline (hopefully soon!)
I'll also need more cleanups like adding a config option for it.
Re: [patch 2/6] Linux Kernel Markers - Add kconfig menus for the marker code
In reply to Randy DunlapQuoted 96 lines · * Randy Dunlap ([email protected]) wrote:
On Thu, 06 Sep 2007 16:07:35 -0400 Mathieu Desnoyers wrote:
[snip]
Quoted 79 lines
This patch:
Add
Kconfigmenus for the marker code.[[email protected]: Never ever select MODULES]Signed-off-by Mathieu Desnoyers <[email protected]>Reviewed-by Christoph Hellwig <[email protected]>Reviewed-by "Frank Ch. Eigler" <[email protected]>CC Adrian Bunk <[email protected]>---
arch/alpha/Kconfig | 2 ++ arch/arm/Kconfig | 2 ++ arch/avr32/Kconfig.debug | 7 +++++++ arch/cris/Kconfig | 2 ++ arch/frv/Kconfig | 2 ++ arch/h8300/Kconfig | 2 ++ arch/i386/Kconfig | 2 ++ arch/ia64/Kconfig | 2 ++ arch/m32r/Kconfig | 2 ++ arch/m68k/Kconfig | 2 ++ arch/m68knommu/Kconfig | 2 ++ arch/mips/Kconfig | 2 ++ arch/parisc/Kconfig | 2 ++ arch/powerpc/Kconfig | 2 ++ arch/ppc/Kconfig | 2 ++ arch/s390/Kconfig | 2 ++ arch/sh/Kconfig | 2 ++ arch/sh64/Kconfig | 2 ++ arch/sparc/Kconfig | 2 ++ arch/sparc64/Kconfig | 2 ++ arch/um/Kconfig | 2 ++ arch/v850/Kconfig | 2 ++ arch/x86_64/Kconfig | 2 ++ arch/xtensa/Kconfig | 2 ++ kernel/Kconfig.marker | 7 +++++++ kernel/Makefile | 1 + 26 files changed, 61 insertions(+)Index: linux-2.6-lttng/arch/alpha/Kconfig
===================================================================arch/alpha/Kconfig +2
-0@@ -646,6 +646,8 @@ config SRM_ENV source "fs/Kconfig.binfmt" +source "kernel/Kconfig.marker" + endmenu source "net/Kconfig"Index: linux-2.6-lttng/kernel/Kconfig.marker
===================================================================kernel/Kconfig.marker new file +7
-0@@ -0,0 +1,7 @@ +# Code markers configuration + +config MARKERS + bool "Activate markers" + help + Place an empty function call at each marker site. Can be + dynamically changed for a probe function.Index: linux-2.6-lttng/arch/avr32/Kconfig.debug
===================================================================arch/avr32/Kconfig.debug +3
-0@@ -6,6 +6,9 @@ config TRACE_IRQFLAGS_SUPPORT source "lib/Kconfig.debug" +menu "Instrumentation Support" + depends on EXPERIMENTAL + config KPROBES bool "Kprobes" depends on DEBUG_KERNELarch/avr32/Kconfig.debug config KPROBES · line 26
Quoted 8 lines
arch/avr32/Kconfig.debug +4
-0@@ -16,4 +19,8 @@ config KPROBES for kernel debugging, non-intrusive instrumentation and testing. If in doubt, say "N". +source "kernel/Kconfig.marker" + +endmenu + endmenuIt seems sad that this patch sources
Kconfig.marker, a 7-line file, 20-something times. Yes, you (we) don't want to put those 7 lines into 20-something different files, so sourcing is the right thing.
Quoted 5 lines
However, what you did for avr32 seems more on the right track to me:
make _one_ Instrumentation support menu that includes PROFILING, OPROFILE, KPROBES, and MARKERS and then use (source) that in all of the arches.
Ok, it will be in my next post.
Mathieu
Quoted 3 lines
---
~Randy
*** Remember to useDocumentation/SubmitChecklistwhen testing your code ***
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68