From: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
To: Martin Bligh <mbligh@google.com>,
"Frank Ch. Eigler" <fche@redhat.com>,
Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>,
prasanna@in.ibm.com, Andrew Morton <akpm@osdl.org>,
Ingo Molnar <mingo@elte.hu>,
Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>,
Paul Mundt <lethal@linux-sh.org>,
linux-kernel <linux-kernel@vger.kernel.org>,
Jes Sorensen <jes@sgi.com>, Tom Zanussi <zanussi@us.ibm.com>,
Richard J Moore <richardj_moore@uk.ibm.com>,
Michel Dagenais <michel.dagenais@polymtl.ca>,
Christoph Hellwig <hch@infradead.org>,
Greg Kroah-Hartman <gregkh@suse.de>,
Thomas Gleixner <tglx@linutronix.de>,
William Cohen <wcohen@redhat.com>,
ltt-dev@shafik.org, systemtap@sources.redhat.com,
Alan Cox <alan@lxorguk.ukuu.org.uk>,
Jeremy Fitzhardinge <jeremy@goop.org>
Subject: [PATCH] Linux Kernel Markers 0.8 for 2.6.17 (with near jump for i386)
Date: Fri, 22 Sep 2006 17:42:40 -0400 [thread overview]
Message-ID: <20060922214239.GA28625@Krystal> (raw)
Hi,
Here is a new version of the LKM. I added support for a near jump as an
optimisation for i386. I guess that changing the one byte offset of the near
jump instruction won't have any effect on the i386 erratas, anyone can confirm
this ?
With this optimisation, the cost of this inactive marker shrinks from a memory
load+far jump to a near jump.
Feel free to implement similar optimisations for other architectures.
Mathieu
---BEGIN---
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -1082,6 +1082,8 @@ config KPROBES
for kernel debugging, non-intrusive instrumentation and testing.
If in doubt, say "N".
+source "kernel/Kconfig.marker"
+
source "ltt/Kconfig"
endmenu
--- /dev/null
+++ b/include/asm-alpha/marker.h
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. Architecture specific
+ * optimisations.
+ *
+ * No optimisation implemented.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
--- /dev/null
+++ b/include/asm-arm/marker.h
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. Architecture specific
+ * optimisations.
+ *
+ * No optimisation implemented.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
--- /dev/null
+++ b/include/asm-arm26/marker.h
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. Architecture specific
+ * optimisations.
+ *
+ * No optimisation implemented.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
--- /dev/null
+++ b/include/asm-cris/marker.h
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. Architecture specific
+ * optimisations.
+ *
+ * No optimisation implemented.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
--- /dev/null
+++ b/include/asm-frv/marker.h
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. Architecture specific
+ * optimisations.
+ *
+ * No optimisation implemented.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
--- /dev/null
+++ b/include/asm-generic/marker.h
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. Architecture specific
+ * optimisations.
+ *
+ * No optimisation implemented.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
--- /dev/null
+++ b/include/asm-h8300/marker.h
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. Architecture specific
+ * optimisations.
+ *
+ * No optimisation implemented.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
--- /dev/null
+++ b/include/asm-i386/marker.h
@@ -0,0 +1,29 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. i386 architecture optimisations.
+ *
+ * (C) Copyright 2006 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
+#define ARCH_HAS_MARK_NEAR_JUMP
+
+/* Note : max 256 bytes between over_label and near_jump */
+#define MARK_DO_JUMP(name) \
+ do { \
+ __label__ near_jump_select; \
+ volatile static void *__mark_jump_select_##name \
+ asm (MARK_JUMP_SELECT_PREFIX#name) \
+ __attribute__((unused)) = &&near_jump_select; \
+ asm volatile ( ".align 16;\n\t" : : ); \
+ asm volatile ( ".byte 0xeb;\n\t" : : ); \
+near_jump_select: \
+ asm volatile ( ".byte %0-%1;\n\t" : : \
+ "m" (*&&over_label), \
+ "m" (*&&call_label)); \
+call_label: \
+ asm volatile ( "" : : ); \
+ } while(0)
--- /dev/null
+++ b/include/asm-ia64/marker.h
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. Architecture specific
+ * optimisations.
+ *
+ * No optimisation implemented.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
--- /dev/null
+++ b/include/asm-m32r/marker.h
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. Architecture specific
+ * optimisations.
+ *
+ * No optimisation implemented.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
--- /dev/null
+++ b/include/asm-m68k/marker.h
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. Architecture specific
+ * optimisations.
+ *
+ * No optimisation implemented.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
--- /dev/null
+++ b/include/asm-m68knommu/marker.h
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. Architecture specific
+ * optimisations.
+ *
+ * No optimisation implemented.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
--- /dev/null
+++ b/include/asm-mips/marker.h
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. Architecture specific
+ * optimisations.
+ *
+ * No optimisation implemented.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
--- /dev/null
+++ b/include/asm-parisc/marker.h
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. Architecture specific
+ * optimisations.
+ *
+ * No optimisation implemented.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
--- /dev/null
+++ b/include/asm-powerpc/marker.h
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. Architecture specific
+ * optimisations.
+ *
+ * No optimisation implemented.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
--- /dev/null
+++ b/include/asm-ppc/marker.h
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. Architecture specific
+ * optimisations.
+ *
+ * No optimisation implemented.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
--- /dev/null
+++ b/include/asm-ppc64/marker.h
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. Architecture specific
+ * optimisations.
+ *
+ * No optimisation implemented.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
--- /dev/null
+++ b/include/asm-s390/marker.h
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. Architecture specific
+ * optimisations.
+ *
+ * No optimisation implemented.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
--- /dev/null
+++ b/include/asm-sh/marker.h
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. Architecture specific
+ * optimisations.
+ *
+ * No optimisation implemented.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
--- /dev/null
+++ b/include/asm-sh64/marker.h
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. Architecture specific
+ * optimisations.
+ *
+ * No optimisation implemented.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
--- /dev/null
+++ b/include/asm-sparc/marker.h
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. Architecture specific
+ * optimisations.
+ *
+ * No optimisation implemented.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
--- /dev/null
+++ b/include/asm-sparc64/marker.h
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. Architecture specific
+ * optimisations.
+ *
+ * No optimisation implemented.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
--- /dev/null
+++ b/include/asm-um/marker.h
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. Architecture specific
+ * optimisations.
+ *
+ * No optimisation implemented.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
--- /dev/null
+++ b/include/asm-v850/marker.h
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. Architecture specific
+ * optimisations.
+ *
+ * No optimisation implemented.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
--- /dev/null
+++ b/include/asm-x86_64/marker.h
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. Architecture specific
+ * optimisations.
+ *
+ * No optimisation implemented.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
--- /dev/null
+++ b/include/asm-xtensa/marker.h
@@ -0,0 +1,12 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing. Architecture specific
+ * optimisations.
+ *
+ * No optimisation implemented.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
--- /dev/null
+++ b/include/linux/marker.h
@@ -0,0 +1,132 @@
+/*****************************************************************************
+ * marker.h
+ *
+ * Code markup for dynamic and static tracing.
+ *
+ * Example :
+ *
+ * MARK(subsystem_event, "%d %s", someint, somestring);
+ * Where :
+ * - Subsystem is the name of your subsystem.
+ * - event is the name of the event to mark.
+ * - "%d %s" is the formatted string for printk.
+ * - someint is an integer.
+ * - somestring is a char *.
+ * - subsystem_event must be unique thorough the kernel!
+ *
+ * Dynamically overridable function call based on marker mechanism
+ * from Frank Ch. Eigler <fche@redhat.com>.
+ *
+ * (C) Copyright 2006 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
+#include <linux/linkage.h>
+
+#define MARK_KPROBE_PREFIX "__mark_kprobe_"
+#define MARK_CALL_PREFIX "__mark_call_"
+#define MARK_JUMP_SELECT_PREFIX "__mark_jump_select_"
+#define MARK_JUMP_CALL_PREFIX "__mark_jump_call_"
+#define MARK_JUMP_OVER_PREFIX "__mark_jump_over_"
+#define MARK_FORMAT_PREFIX "__mark_format_"
+
+#include <asm/marker.h>
+
+#define MARK_MAX_FORMAT_LEN 1024
+
+
+struct __mark_kprobe_marker {
+ const char *name;
+ const void *location;
+};
+
+#ifdef CONFIG_MARK_SYMBOL
+#define MARK_SYM(name, format, args...) \
+ do { \
+ __label__ here; \
+here: asm volatile(".section \".markers\"; .long %0, %1;\n\t" \
+ ".previous\n\t" : : "m" (*(MARK_KPROBE_PREFIX#name)), \
+ "m" (*&&here)); \
+ } while(0)
+#else
+#define MARK_SYM(name, format, args...)
+#endif
+
+#ifdef CONFIG_MARK_JUMP_CALL
+#define MARK_JUMP_CALL_PROTOTYPE(name) \
+ static marker_probe_func *__mark_call_##name \
+ asm (MARK_CALL_PREFIX#name) = \
+ __mark_empty_function
+#define MARK_JUMP_CALL(name, format, args...) \
+ do { \
+ preempt_disable(); \
+ (*__mark_call_##name)(format, ## args); \
+ preempt_enable_no_resched(); \
+ } while(0)
+#else
+#define MARK_JUMP_CALL_PROTOTYPE(name)
+#define MARK_JUMP_CALL(name, format, args...)
+#endif
+
+#ifndef ARCH_HAS_MARK_NEAR_JUMP
+#define MARK_DO_JUMP(name) \
+ goto *__mark_jump_select_##name; \
+call_label:
+#define MARK_JUMP_SELECT_DECLARE(name) \
+ volatile static void *__mark_jump_select_##name \
+ asm (MARK_JUMP_SELECT_PREFIX#name) \
+ __attribute__((unused)) = \
+ &&over_label
+#else
+#define MARK_JUMP_SELECT_DECLARE(name)
+#endif
+
+#ifndef FORCE_MARK_JUMP_INLINE
+#define MARK_JUMP(name, format, args...) \
+ do { \
+ __label__ over_label, call_label; \
+ volatile static void *__mark_jump_call_##name \
+ asm (MARK_JUMP_CALL_PREFIX#name) \
+ __attribute__((unused)) = \
+ &&call_label; \
+ volatile static void *__mark_jump_over_##name \
+ asm (MARK_JUMP_OVER_PREFIX#name) \
+ __attribute__((unused)) = \
+ &&over_label; \
+ static const char *__mark_format_##name \
+ asm (MARK_FORMAT_PREFIX#name) \
+ __attribute__((unused)) = \
+ format; \
+ MARK_JUMP_CALL_PROTOTYPE(name); \
+ MARK_JUMP_SELECT_DECLARE(name); \
+ MARK_DO_JUMP(name); \
+ MARK_JUMP_CALL(name, format, ## args); \
+over_label: \
+ do {} while(0); \
+ } while(0)
+#else
+#define MARK_JUMP(name, format, args...) \
+ (void) (__mark_inline_##name(format, ## args))
+#endif
+
+#define MARK(name, format, args...) \
+ do { \
+ __mark_check_format(format, ## args); \
+ MARK_SYM(name, format, ## args); \
+ MARK_JUMP(name, format, ## args); \
+ } while(0)
+
+typedef asmlinkage void marker_probe_func(const char *fmt, ...);
+
+static inline __attribute__ ((format (printf, 1, 2)))
+void __mark_check_format(const char *fmt, ...)
+{ }
+
+extern marker_probe_func __mark_empty_function;
+
+int marker_set_probe(const char *name, const char *format,
+ marker_probe_func *probe);
+
+void marker_disable_probe(const char *name, marker_probe_func *probe);
--- /dev/null
+++ b/kernel/Kconfig.marker
@@ -0,0 +1,25 @@
+# Code markers configuration
+
+menu "Marker configuration"
+
+
+config MARK_SYMBOL
+ bool "Replace markers with symbols"
+ default n
+ help
+ Put symbols in place of markers, useful for kprobe.
+
+config MARK_JUMP_CALL
+ bool "Replace markers with a jump over an inactive function call"
+ default n
+ help
+ Put a jump over a call in place of markers.
+
+config MARK_JUMP
+ bool "Jump marker probes set/disable infrastructure"
+ select KALLSYMS
+ default n
+ help
+ Install or remove probes from markers.
+
+endmenu
index 6844e18..1a01e5d 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
obj-$(CONFIG_SECCOMP) += seccomp.o
obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
obj-$(CONFIG_RELAY) += relay.o
+obj-$(CONFIG_MARK_JUMP) += marker.o
ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
# According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
--- /dev/null
+++ b/kernel/marker.c
@@ -0,0 +1,161 @@
+/*****************************************************************************
+ * marker.c
+ *
+ * Code markup for dynamic and static tracing. Marker control module.
+ *
+ * (C) Copyright 2006 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ *
+ * Design :
+ * kernel/marker.c deals with all marker activation from a centralized,
+ * coherent mechanism. The functions that will be called will simply sit in
+ * modules.
+ *
+ * Before activating a probe, the marker module :
+ * 1 - takes proper locking
+ * 2 - verifies that the function pointer and jmp target are at their default
+ * values, otherwise the "set" operation fails.
+ * 4 - does function pointer and jump setup.
+ *
+ * Setting them back to disabled is :
+ * 1 - setting back the default jmp and call values
+ * 2 - call synchronize_sched()
+ *
+ * A probe module must call marker disable on all its markers before module
+ * unload.
+ */
+
+
+#include <linux/marker.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/kallsyms.h>
+#include <linux/string.h>
+
+static DEFINE_SPINLOCK(marker_lock);
+
+struct marker_pointers {
+ void **call;
+ void **jmpselect;
+ void **jmpcall;
+ void **jmpinline;
+ void **jmpover;
+ void **format;
+};
+
+asmlinkage void __mark_empty_function(const char *fmt, ...)
+{
+}
+EXPORT_SYMBOL(__mark_empty_function);
+
+/* Pointers can be used around preemption disabled */
+static int marker_get_pointers(const char *name,
+ struct marker_pointers *ptrs)
+{
+ char call_sym[KSYM_NAME_LEN] = MARK_CALL_PREFIX;
+ char jmpselect_sym[KSYM_NAME_LEN] = MARK_JUMP_SELECT_PREFIX;
+ char jmpcall_sym[KSYM_NAME_LEN] = MARK_JUMP_CALL_PREFIX;
+ char jmpover_sym[KSYM_NAME_LEN] = MARK_JUMP_OVER_PREFIX;
+ char format_sym[KSYM_NAME_LEN] = MARK_FORMAT_PREFIX;
+ unsigned int call_sym_len = sizeof(MARK_CALL_PREFIX);
+ unsigned int jmpselect_sym_len = sizeof(MARK_JUMP_SELECT_PREFIX);
+ unsigned int jmpcall_sym_len = sizeof(MARK_JUMP_CALL_PREFIX);
+ unsigned int jmpover_sym_len = sizeof(MARK_JUMP_OVER_PREFIX);
+ unsigned int format_sym_len = sizeof(MARK_FORMAT_PREFIX);
+
+ strncat(call_sym, name, KSYM_NAME_LEN-call_sym_len);
+ strncat(jmpselect_sym, name, KSYM_NAME_LEN-jmpselect_sym_len);
+ strncat(jmpcall_sym, name, KSYM_NAME_LEN-jmpcall_sym_len);
+ strncat(jmpover_sym, name, KSYM_NAME_LEN-jmpover_sym_len);
+ strncat(format_sym, name, KSYM_NAME_LEN-format_sym_len);
+
+ ptrs->call = (void**)kallsyms_lookup_name(call_sym);
+ ptrs->jmpselect = (void**)kallsyms_lookup_name(jmpselect_sym);
+ ptrs->jmpcall = (void**)kallsyms_lookup_name(jmpcall_sym);
+ ptrs->jmpover = (void**)kallsyms_lookup_name(jmpover_sym);
+ ptrs->format = (void**)kallsyms_lookup_name(format_sym);
+
+ if (!(ptrs->call && ptrs->jmpselect && ptrs->jmpcall
+ && ptrs->jmpover && ptrs->format)) {
+ return ENOENT;
+ }
+ return 0;
+}
+
+int marker_set_probe(const char *name, const char *format,
+ marker_probe_func *probe)
+{
+ int result = 0;
+ struct marker_pointers ptrs;
+
+ spin_lock(&marker_lock);
+ result = marker_get_pointers(name, &ptrs);
+ if (result) {
+ result = ENODEV;
+ printk(KERN_NOTICE
+ "Unable to find kallsyms for markers in %s\n",
+ name);
+ goto unlock;
+ }
+
+ if (*ptrs.call != __mark_empty_function) {
+ result = EBUSY;
+ printk(KERN_NOTICE
+ "Probe already installed on "
+ "marker in %s\n",
+ name);
+ goto unlock;
+ }
+ /* Check the types if format provided by probe */
+ if (format && strncmp(format, *ptrs.format,
+ MARK_MAX_FORMAT_LEN)) {
+ result = EPERM;
+ printk(KERN_NOTICE
+ "Format mismatch for probe %s "
+ "(%s), marker (%s)\n",
+ name,
+ format,
+ (const char*)*ptrs.format);
+ goto unlock;
+ }
+ /* Setup the call pointer */
+ *ptrs.call = probe;
+ /* Setup the jump */
+#ifndef ARCH_HAS_MARK_NEAR_JUMP
+ *ptrs.jmpselect = *ptrs.jmpcall;
+#else
+ **(char**)ptrs.jmpselect = 0;
+#endif
+unlock:
+ spin_unlock(&marker_lock);
+ return result;
+}
+EXPORT_SYMBOL_GPL(marker_set_probe);
+
+void marker_disable_probe(const char *name, marker_probe_func *probe)
+{
+ int result = 0;
+ struct marker_pointers ptrs;
+
+ spin_lock(&marker_lock);
+ result = marker_get_pointers(name, &ptrs);
+ if (result)
+ goto unlock;
+
+ if (*ptrs.call == probe) {
+#ifndef ARCH_HAS_MARK_NEAR_JUMP
+ *ptrs.jmpselect = *ptrs.jmpover;
+#else
+ **(char**)ptrs.jmpselect =
+ *ptrs.jmpover - *ptrs.jmpcall;
+#endif
+ *ptrs.call = __mark_empty_function;
+ }
+unlock:
+ spin_unlock(&marker_lock);
+ if (!result)
+ synchronize_sched();
+}
+EXPORT_SYMBOL_GPL(marker_disable_probe);
---END---
---BEGIN---
/* probe.c
*
* Loads a function at a marker call site.
*
* (C) Copyright 2006 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
*
* This file is released under the GPLv2.
* See the file COPYING for more details.
*/
#include <linux/marker.h>
#include <linux/module.h>
#include <linux/kallsyms.h>
/* function to install */
#define DO_MARK1_FORMAT "%d"
asmlinkage void do_mark1(const char *format, int value)
{
__mark_check_format(DO_MARK1_FORMAT, value);
printk("value is %d\n", value);
}
#define DO_MARK2_FORMAT "%d %s"
asmlinkage void do_mark2(const char *format, int value, const char *string)
{
__mark_check_format(DO_MARK2_FORMAT, value, string);
printk("value is %d %s\n", value, string);
}
#define DO_MARK3_FORMAT "%d %s %s"
asmlinkage void do_mark3(const char *format, int value, const char *s1,
const char *s2)
{
__mark_check_format(DO_MARK3_FORMAT, value, s1, s2);
printk("value is %d %s %s\n", value, s1, s2);
}
int init_module(void)
{
int result;
result = marker_set_probe("subsys_mark1", DO_MARK1_FORMAT,
(marker_probe_func*)do_mark1);
if(result) goto end;
result = marker_set_probe("subsys_mark2", DO_MARK2_FORMAT,
(marker_probe_func*)do_mark2);
if(result) goto cleanup1;
result = marker_set_probe("subsys_mark3", DO_MARK3_FORMAT,
(marker_probe_func*)do_mark3);
if(result) goto cleanup2;
return -result;
cleanup2:
marker_disable_probe("subsys_mark2", (marker_probe_func*)do_mark2);
cleanup1:
marker_disable_probe("subsys_mark1", (marker_probe_func*)do_mark1);
end:
return -result;
}
void cleanup_module(void)
{
marker_disable_probe("subsys_mark1", (marker_probe_func*)do_mark1);
marker_disable_probe("subsys_mark2", (marker_probe_func*)do_mark2);
marker_disable_probe("subsys_mark3", (marker_probe_func*)do_mark3);
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mathieu Desnoyers");
MODULE_DESCRIPTION("Probe");
---END---
---BEGIN---
/* test-mark.c
*
*/
#include <linux/marker.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/sched.h>
volatile int x=7;
struct proc_dir_entry *pentry = NULL;
static int my_open(struct inode *inode, struct file *file)
{
unsigned int i;
for(i=0; i<2; i++) {
MARK(subsys_mark1, "%d", 1);
x=i;
barrier();
}
MARK(subsys_mark2, "%d %s", 2, "blah2");
MARK(subsys_mark3, "%d %s %s", x, "blah3", "blah5");
return -EPERM;
}
static struct file_operations my_operations = {
.open = my_open,
};
int init_module(void)
{
pentry = create_proc_entry("testmark", 0444, NULL);
if (pentry)
pentry->proc_fops = &my_operations;
return 0;
}
void cleanup_module(void)
{
remove_proc_entry("testmark", NULL);
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mathieu Desnoyers");
MODULE_DESCRIPTION("Marker Test");
---END---
OpenPGP public key: http://krystal.dyndns.org:8080/key/compudj.gpg
Key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
next reply other threads:[~2006-09-22 21:48 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-09-22 21:42 Mathieu Desnoyers [this message]
2006-09-23 19:57 ` [PATCH] Linux Kernel Markers 0.8 for 2.6.17 (with near jump for i386) Karim Yaghmour
2006-09-25 5:39 ` Mathieu Desnoyers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060922214239.GA28625@Krystal \
--to=mathieu.desnoyers@polymtl.ca \
--cc=akpm@osdl.org \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=fche@redhat.com \
--cc=gregkh@suse.de \
--cc=hch@infradead.org \
--cc=jeremy@goop.org \
--cc=jes@sgi.com \
--cc=lethal@linux-sh.org \
--cc=linux-kernel@vger.kernel.org \
--cc=ltt-dev@shafik.org \
--cc=masami.hiramatsu.pt@hitachi.com \
--cc=mbligh@google.com \
--cc=michel.dagenais@polymtl.ca \
--cc=mingo@elte.hu \
--cc=prasanna@in.ibm.com \
--cc=richardj_moore@uk.ibm.com \
--cc=systemtap@sources.redhat.com \
--cc=tglx@linutronix.de \
--cc=wcohen@redhat.com \
--cc=zanussi@us.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.