linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Kprobes: Add kprobes smoke tests that run on boot
@ 2008-01-08  6:33 Ananth N Mavinakayanahalli
  2008-01-08  9:15 ` Ingo Molnar
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Ananth N Mavinakayanahalli @ 2008-01-08  6:33 UTC (permalink / raw)
  To: akpm; +Cc: lkml, mingo, Jim Keniston, mhiramat, davem, hskinnemoen

From: Ananth N Mavinakayanahalli <ananth@in.ibm.com>

Here is a quick and naive smoke test for kprobes. This is intended to
just verify if some unrelated change broke the *probes subsystem. It is
self contained, architecture agnostic and isn't of any great use by itself.

This needs to be built in the kernel and runs a basic set of tests to
verify if kprobes, jprobes and kretprobes run fine on the kernel. In case
of an error, it'll print out a message with a "BUG" prefix.

This is a start; we intend to add more tests to this bucket over time.

Thanks to Jim Keniston and Masami Hiramatsu for comments and suggestions.

Tested on x86 (32/64) and powerpc.

Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Acked-by: Masami Hiramatsu <mhiramat@redhat.com>
---
 include/linux/kprobes.h |   10 ++
 kernel/Makefile         |    1 
 kernel/kprobes.c        |    2 
 kernel/test_kprobes.c   |  216 ++++++++++++++++++++++++++++++++++++++++++++++++
 lib/Kconfig.debug       |   12 ++
 5 files changed, 241 insertions(+)

Index: linux-2.6.24-rc6/kernel/Makefile
===================================================================
--- linux-2.6.24-rc6.orig/kernel/Makefile
+++ linux-2.6.24-rc6/kernel/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
 obj-$(CONFIG_SECCOMP) += seccomp.o
 obj-$(CONFIG_DEBUG_SYNCHRO_TEST) += synchro-test.o
 obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
+obj-$(CONFIG_KPROBES_SANITY_TEST) += test_kprobes.o
 obj-$(CONFIG_CLASSIC_RCU) += rcuclassic.o
 obj-$(CONFIG_PREEMPT_RCU) += rcupreempt.o
 ifeq ($(CONFIG_PREEMPT_RCU),y)
Index: linux-2.6.24-rc6/kernel/test_kprobes.c
===================================================================
--- /dev/null
+++ linux-2.6.24-rc6/kernel/test_kprobes.c
@@ -0,0 +1,216 @@
+/*
+ * test_kprobes.c - simple sanity test for *probes
+ *
+ * Copyright IBM Corp. 2008
+ *
+ * This program is free software;  you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/kprobes.h>
+#include <linux/random.h>
+
+#define div_factor 3
+
+static u32 rand1, preh_val, posth_val, jph_val;
+static int errors, handler_errors, num_tests;
+
+static noinline u32 kprobe_target(u32 value)
+{
+	/*
+	 * gcc ignores noinline on some architectures unless we stuff
+	 * sufficient lard into the function. The get_kprobe() here is
+	 * just for that.
+	 *
+	 * NOTE: We aren't concerned about the correctness of get_kprobe()
+	 * here; hence, this call is neither under !preempt nor with the
+	 * kprobe_mutex held. This is fine(tm)
+	 */
+	if (get_kprobe((void *)0xdeadbeef))
+		printk(KERN_INFO "Kprobe smoke test: probe on 0xdeadbeef!\n");
+
+	return (value / div_factor);
+}
+
+static int kp_pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
+	preh_val = (rand1 / div_factor);
+	return 0;
+}
+
+static void kp_post_handler(struct kprobe *p, struct pt_regs *regs,
+		unsigned long flags)
+{
+	if (preh_val != (rand1 / div_factor)) {
+		handler_errors++;
+		printk(KERN_ERR "Kprobe smoke test failed: "
+				"incorrect value in post_handler\n");
+	}
+	posth_val = preh_val + div_factor;
+}
+
+static struct kprobe kp = {
+	.symbol_name = "kprobe_target",
+	.pre_handler = kp_pre_handler,
+	.post_handler = kp_post_handler
+};
+
+static int test_kprobe(void)
+{
+	int ret;
+
+	ret = register_kprobe(&kp);
+	if (ret < 0) {
+		printk(KERN_ERR "Kprobe smoke test failed: "
+				"register_kprobe returned %d\n", ret);
+		return ret;
+	}
+
+	ret = kprobe_target(rand1);
+	unregister_kprobe(&kp);
+
+	if (preh_val == 0) {
+		printk(KERN_ERR "Kprobe smoke test failed: "
+				"kprobe pre_handler not called\n");
+		handler_errors++;
+	}
+
+	if (posth_val == 0) {
+		printk(KERN_ERR "Kprobe smoke test failed: "
+				"kprobe post_handler not called\n");
+		handler_errors++;
+	}
+
+	return 0;
+}
+
+static u32 j_kprobe_target(u32 value)
+{
+	if (value != rand1) {
+		handler_errors++;
+		printk(KERN_ERR "Kprobe smoke test failed: "
+				"incorrect value in jprobe handler\n");
+	}
+
+	jph_val = rand1;
+	jprobe_return();
+	return 0;
+}
+
+static struct jprobe jp = {
+	.entry		= j_kprobe_target,
+	.kp.symbol_name = "kprobe_target"
+};
+
+static int test_jprobe(void)
+{
+	int ret;
+
+	ret = register_jprobe(&jp);
+	if (ret < 0) {
+		printk(KERN_ERR "Kprobe smoke test failed: "
+				"register_jprobe returned %d\n", ret);
+		return ret;
+	}
+
+	ret = kprobe_target(rand1);
+	unregister_jprobe(&jp);
+	if (jph_val == 0) {
+		printk(KERN_ERR "Kprobe smoke test failed: "
+				"jprobe handler not called\n");
+		handler_errors++;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_KRETPROBES
+static u32 krph_val;
+
+static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+	unsigned long ret = regs_return_value(regs);
+
+	if (ret != (rand1 / div_factor)) {
+		handler_errors++;
+		printk(KERN_ERR "Kprobe smoke test failed: "
+				"incorrect value in kretprobe handler\n");
+	}
+
+	krph_val = (rand1 / div_factor);
+	return 0;
+}
+
+static struct kretprobe rp = {
+	.handler	= return_handler,
+	.kp.symbol_name = "kprobe_target"
+};
+
+static int test_kretprobe(void)
+{
+	int ret;
+
+	ret = register_kretprobe(&rp);
+	if (ret < 0) {
+		printk(KERN_ERR "Kprobe smoke test failed: "
+				"register_kretprobe returned %d\n", ret);
+		return ret;
+	}
+
+	ret = kprobe_target(rand1);
+	unregister_kretprobe(&rp);
+	if (krph_val == 0) {
+		printk(KERN_ERR "Kprobe smoke test failed: "
+				"kretprobe handler not called\n");
+		handler_errors++;
+	}
+
+	return 0;
+}
+#endif /* CONFIG_KRETPROBES */
+
+int init_test_probes(void)
+{
+	int ret;
+
+	do {
+		rand1 = random32();
+	} while (rand1 <= div_factor);
+
+	printk(KERN_INFO "Kprobe smoke test started\n");
+	num_tests++;
+	ret = test_kprobe();
+	if (ret < 0)
+		errors++;
+
+	num_tests++;
+	ret = test_jprobe();
+	if (ret < 0)
+		errors++;
+
+#ifdef CONFIG_KRETPROBES
+	num_tests++;
+	ret = test_kretprobe();
+	if (ret < 0)
+		errors++;
+#endif /* CONFIG_KRETPROBES */
+
+	if (errors)
+		printk(KERN_ERR "BUG: Kprobe smoke test: %d out of "
+				"%d tests failed\n", errors, num_tests);
+	else if (handler_errors)
+		printk(KERN_ERR "BUG: Kprobe smoke test: %d error(s) "
+				"running handlers\n", handler_errors);
+	else
+		printk(KERN_INFO "Kprobe smoke test passed successfully\n");
+
+	return 0;
+}
Index: linux-2.6.24-rc6/lib/Kconfig.debug
===================================================================
--- linux-2.6.24-rc6.orig/lib/Kconfig.debug
+++ linux-2.6.24-rc6/lib/Kconfig.debug
@@ -511,6 +511,18 @@ config RCU_TORTURE_TEST
 	  Say M if you want the RCU torture tests to build as a module.
 	  Say N if you are unsure.
 
+config KPROBES_SANITY_TEST
+	bool "Kprobes sanity tests"
+	depends on DEBUG_KERNEL
+	depends on KPROBES
+	default n
+	help
+	  This option provides for testing basic kprobes functionality on
+	  boot. A sample kprobe, jprobe and kretprobe are inserted and
+	  verified for functionality.
+
+	  Say N if you are unsure.
+
 config LKDTM
 	tristate "Linux Kernel Dump Test Tool Module"
 	depends on DEBUG_KERNEL
Index: linux-2.6.24-rc6/include/linux/kprobes.h
===================================================================
--- linux-2.6.24-rc6.orig/include/linux/kprobes.h
+++ linux-2.6.24-rc6/include/linux/kprobes.h
@@ -182,6 +182,15 @@ static inline void kretprobe_assert(stru
 	}
 }
 
+#ifdef CONFIG_KPROBES_SANITY_TEST
+extern int init_test_probes(void);
+#else
+static inline int init_test_probes(void)
+{
+	return 0;
+}
+#endif /* CONFIG_KPROBES_SANITY_TEST */
+
 extern spinlock_t kretprobe_lock;
 extern struct mutex kprobe_mutex;
 extern int arch_prepare_kprobe(struct kprobe *p);
@@ -227,6 +236,7 @@ void unregister_kretprobe(struct kretpro
 
 void kprobe_flush_task(struct task_struct *tk);
 void recycle_rp_inst(struct kretprobe_instance *ri, struct hlist_head *head);
+
 #else /* CONFIG_KPROBES */
 
 #define __kprobes	/**/
Index: linux-2.6.24-rc6/kernel/kprobes.c
===================================================================
--- linux-2.6.24-rc6.orig/kernel/kprobes.c
+++ linux-2.6.24-rc6/kernel/kprobes.c
@@ -821,6 +821,8 @@ static int __init init_kprobes(void)
 	if (!err)
 		err = register_die_notifier(&kprobe_exceptions_nb);
 
+	if (!err)
+		init_test_probes();
 	return err;
 }
 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Kprobes: Add kprobes smoke tests that run on boot
  2008-01-08  6:33 [PATCH] Kprobes: Add kprobes smoke tests that run on boot Ananth N Mavinakayanahalli
@ 2008-01-08  9:15 ` Ingo Molnar
  2008-01-08 21:00 ` Andi Kleen
  2008-01-09  7:43 ` David Miller
  2 siblings, 0 replies; 14+ messages in thread
From: Ingo Molnar @ 2008-01-08  9:15 UTC (permalink / raw)
  To: Ananth N Mavinakayanahalli
  Cc: akpm, lkml, Jim Keniston, mhiramat, davem, hskinnemoen


* Ananth N Mavinakayanahalli <ananth@in.ibm.com> wrote:

> From: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
> 
> Here is a quick and naive smoke test for kprobes. This is intended to 
> just verify if some unrelated change broke the *probes subsystem. It 
> is self contained, architecture agnostic and isn't of any great use by 
> itself.
> 
> This needs to be built in the kernel and runs a basic set of tests to 
> verify if kprobes, jprobes and kretprobes run fine on the kernel. In 
> case of an error, it'll print out a message with a "BUG" prefix.

yay! Picked this up into x86.git for testing.

small detail: i moved the kernel/Makefile change to another spot (see 
below), this way it integrates without rejects with rcu-preempt and with 
the kgdb changes.

	Ingo

Index: linux-x86.q/kernel/Makefile
===================================================================
--- linux-x86.q.orig/kernel/Makefile
+++ linux-x86.q/kernel/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_CPUSETS) += cpuset.o
 obj-$(CONFIG_CGROUP_NS) += ns_cgroup.o
 obj-$(CONFIG_IKCONFIG) += configs.o
 obj-$(CONFIG_STOP_MACHINE) += stop_machine.o
+obj-$(CONFIG_KPROBES_SANITY_TEST) += test_kprobes.o
 obj-$(CONFIG_AUDIT) += audit.o auditfilter.o
 obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
 obj-$(CONFIG_AUDIT_TREE) += audit_tree.o

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Kprobes: Add kprobes smoke tests that run on boot
  2008-01-08  6:33 [PATCH] Kprobes: Add kprobes smoke tests that run on boot Ananth N Mavinakayanahalli
  2008-01-08  9:15 ` Ingo Molnar
@ 2008-01-08 21:00 ` Andi Kleen
  2008-01-08 22:18   ` Ingo Molnar
  2008-01-08 23:10   ` Jim Keniston
  2008-01-09  7:43 ` David Miller
  2 siblings, 2 replies; 14+ messages in thread
From: Andi Kleen @ 2008-01-08 21:00 UTC (permalink / raw)
  To: ananth; +Cc: akpm, lkml, mingo, Jim Keniston, mhiramat, davem, hskinnemoen

Ananth N Mavinakayanahalli <ananth@in.ibm.com> writes:
>  kernel/kprobes.c        |    2 
>  kernel/test_kprobes.c   |  216 ++++++++++++++++++++++++++++++++++++++++++++++++

Can you put this somewhere else please? I know there are already some
test files in kernel/* but imho they all belong into some other directory.

+	if (!err)
+		init_test_probes();
 	return err;

Couldn't this be just a normal initcall? Perhaps even a module_init(),
then it would be possible to use as a module too.

-Andi

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Kprobes: Add kprobes smoke tests that run on boot
  2008-01-08 21:00 ` Andi Kleen
@ 2008-01-08 22:18   ` Ingo Molnar
  2008-01-08 22:49     ` Andi Kleen
  2008-01-09  8:00     ` Christoph Hellwig
  2008-01-08 23:10   ` Jim Keniston
  1 sibling, 2 replies; 14+ messages in thread
From: Ingo Molnar @ 2008-01-08 22:18 UTC (permalink / raw)
  To: Andi Kleen; +Cc: ananth, akpm, lkml, Jim Keniston, mhiramat, davem, hskinnemoen


* Andi Kleen <andi@firstfloor.org> wrote:

> Ananth N Mavinakayanahalli <ananth@in.ibm.com> writes:
> >  kernel/kprobes.c        |    2 
> >  kernel/test_kprobes.c   |  216 ++++++++++++++++++++++++++++++++++++++++++++++++
> 
> Can you put this somewhere else please? I know there are already some 
> test files in kernel/* but imho they all belong into some other 
> directory.

agreed - lib/* would be the right place i think - we've got 
lib/locking-selftest.c already.

	Ingo

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Kprobes: Add kprobes smoke tests that run on boot
  2008-01-08 22:18   ` Ingo Molnar
@ 2008-01-08 22:49     ` Andi Kleen
  2008-01-08 22:50       ` Ingo Molnar
  2008-01-09  8:00     ` Christoph Hellwig
  1 sibling, 1 reply; 14+ messages in thread
From: Andi Kleen @ 2008-01-08 22:49 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Andi Kleen, ananth, akpm, lkml, Jim Keniston, mhiramat, davem,
	hskinnemoen

On Tue, Jan 08, 2008 at 11:18:02PM +0100, Ingo Molnar wrote:
> 
> * Andi Kleen <andi@firstfloor.org> wrote:
> 
> > Ananth N Mavinakayanahalli <ananth@in.ibm.com> writes:
> > >  kernel/kprobes.c        |    2 
> > >  kernel/test_kprobes.c   |  216 ++++++++++++++++++++++++++++++++++++++++++++++++
> > 
> > Can you put this somewhere else please? I know there are already some 
> > test files in kernel/* but imho they all belong into some other 
> > directory.
> 
> agreed - lib/* would be the right place i think - we've got 
> lib/locking-selftest.c already.

Why not test/       ?

I felt a little bad about not introducing arch/x86/test/ for pageattr-test.c either.

-Andi

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Kprobes: Add kprobes smoke tests that run on boot
  2008-01-08 22:49     ` Andi Kleen
@ 2008-01-08 22:50       ` Ingo Molnar
  0 siblings, 0 replies; 14+ messages in thread
From: Ingo Molnar @ 2008-01-08 22:50 UTC (permalink / raw)
  To: Andi Kleen; +Cc: ananth, akpm, lkml, Jim Keniston, mhiramat, davem, hskinnemoen


* Andi Kleen <andi@firstfloor.org> wrote:

> > agreed - lib/* would be the right place i think - we've got 
> > lib/locking-selftest.c already.
> 
> Why not test/ ?
> 
> I felt a little bad about not introducing arch/x86/test/ for 
> pageattr-test.c either.

yeah, test/ would be even better, and then move locking-selftest over 
there too, plus the rt-mutex tester as well i suspect, and rcutorture.

	Ingo

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Kprobes: Add kprobes smoke tests that run on boot
  2008-01-08 21:00 ` Andi Kleen
  2008-01-08 22:18   ` Ingo Molnar
@ 2008-01-08 23:10   ` Jim Keniston
  2008-01-08 23:28     ` Andi Kleen
  1 sibling, 1 reply; 14+ messages in thread
From: Jim Keniston @ 2008-01-08 23:10 UTC (permalink / raw)
  To: Andi Kleen; +Cc: ananth, akpm, lkml, mingo, mhiramat, davem, hskinnemoen

On Tue, 2008-01-08 at 22:00 +0100, Andi Kleen wrote:
> Ananth N Mavinakayanahalli <ananth@in.ibm.com> writes:
> >  kernel/kprobes.c        |    2 
> >  kernel/test_kprobes.c   |  216 ++++++++++++++++++++++++++++++++++++++++++++++++
> 
> Can you put this somewhere else please? I know there are already some
> test files in kernel/* but imho they all belong into some other directory.
> 
> +	if (!err)
> +		init_test_probes();
>  	return err;
> 
> Couldn't this be just a normal initcall? Perhaps even a module_init(),
> then it would be possible to use as a module too.
> 
> -Andi

I have no problem with that, but if we want to make it buildable as a
module, the call to get_kprobe() needs to be replaced with some other
gcc-inline-defeating mechanism, or we need to export get_probe().  I
much prefer the former, since get_kprobe() is a kprobes-internal
function.

Anybody know an architecture-independent way (other than noinline, which
doesn't always work) of making gcc decide not to inline a function?
E.g., does taking (and using) the function's address do it?

Jim Keniston

>From Ananth's patch:
+static noinline u32 kprobe_target(u32 value)
+{
+       /*
+        * gcc ignores noinline on some architectures unless we stuff
+        * sufficient lard into the function. The get_kprobe() here is
+        * just for that.
+        *
+        * NOTE: We aren't concerned about the correctness of
get_kprobe()
+        * here; hence, this call is neither under !preempt nor with the
+        * kprobe_mutex held. This is fine(tm)
+        */
+       if (get_kprobe((void *)0xdeadbeef))
+               printk(KERN_INFO "Kprobe smoke test: probe on
0xdeadbeef!\n");
+
+       return (value / div_factor);
+}


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Kprobes: Add kprobes smoke tests that run on boot
  2008-01-08 23:10   ` Jim Keniston
@ 2008-01-08 23:28     ` Andi Kleen
  2008-01-09 20:24       ` Jim Keniston
  0 siblings, 1 reply; 14+ messages in thread
From: Andi Kleen @ 2008-01-08 23:28 UTC (permalink / raw)
  To: Jim Keniston
  Cc: Andi Kleen, ananth, akpm, lkml, mingo, mhiramat, davem, hskinnemoen

> I have no problem with that, but if we want to make it buildable as a
> module, the call to get_kprobe() needs to be replaced with some other
> gcc-inline-defeating mechanism, or we need to export get_probe().  I

It's still unclear where noinline does not work (do you have details on that? 
It sounds a little dubious) but there are lots of different other ways to prevent gcc 
from inlining anything.

e.g. you can use stdarg or computed goto or a variable length local array 


> much prefer the former, since get_kprobe() is a kprobes-internal
> function.
> 
> Anybody know an architecture-independent way (other than noinline, which
> doesn't always work) of making gcc decide not to inline a function?

Details?

> E.g., does taking (and using) the function's address do it?

No, that just creates another out of line copy.

-Andi

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Kprobes: Add kprobes smoke tests that run on boot
  2008-01-08  6:33 [PATCH] Kprobes: Add kprobes smoke tests that run on boot Ananth N Mavinakayanahalli
  2008-01-08  9:15 ` Ingo Molnar
  2008-01-08 21:00 ` Andi Kleen
@ 2008-01-09  7:43 ` David Miller
  2 siblings, 0 replies; 14+ messages in thread
From: David Miller @ 2008-01-09  7:43 UTC (permalink / raw)
  To: ananth; +Cc: akpm, linux-kernel, mingo, jkenisto, mhiramat, hskinnemoen

From: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Date: Tue, 8 Jan 2008 12:03:34 +0530

> Here is a quick and naive smoke test for kprobes.

Thanks very much for writing this.

It will come in handy for me when I work on sparc64
kretprobe support.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Kprobes: Add kprobes smoke tests that run on boot
  2008-01-08 22:18   ` Ingo Molnar
  2008-01-08 22:49     ` Andi Kleen
@ 2008-01-09  8:00     ` Christoph Hellwig
  2008-01-09  8:08       ` Sam Ravnborg
  1 sibling, 1 reply; 14+ messages in thread
From: Christoph Hellwig @ 2008-01-09  8:00 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Andi Kleen, ananth, akpm, lkml, Jim Keniston, mhiramat, davem,
	hskinnemoen

On Tue, Jan 08, 2008 at 11:18:02PM +0100, Ingo Molnar wrote:
> 
> * Andi Kleen <andi@firstfloor.org> wrote:
> 
> > Ananth N Mavinakayanahalli <ananth@in.ibm.com> writes:
> > >  kernel/kprobes.c        |    2 
> > >  kernel/test_kprobes.c   |  216 ++++++++++++++++++++++++++++++++++++++++++++++++
> > 
> > Can you put this somewhere else please? I know there are already some 
> > test files in kernel/* but imho they all belong into some other 
> > directory.
> 
> agreed - lib/* would be the right place i think - we've got 
> lib/locking-selftest.c already.

Actually the right place would be to have a separate toplevel directory
I think, and a separate menu in the kernel config machinery.  Thay way
tests are in one place and easily spottable.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Kprobes: Add kprobes smoke tests that run on boot
  2008-01-09  8:00     ` Christoph Hellwig
@ 2008-01-09  8:08       ` Sam Ravnborg
  0 siblings, 0 replies; 14+ messages in thread
From: Sam Ravnborg @ 2008-01-09  8:08 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Ingo Molnar, Andi Kleen, ananth, akpm, lkml, Jim Keniston,
	mhiramat, davem, hskinnemoen

On Wed, Jan 09, 2008 at 08:00:03AM +0000, Christoph Hellwig wrote:
> On Tue, Jan 08, 2008 at 11:18:02PM +0100, Ingo Molnar wrote:
> > 
> > * Andi Kleen <andi@firstfloor.org> wrote:
> > 
> > > Ananth N Mavinakayanahalli <ananth@in.ibm.com> writes:
> > > >  kernel/kprobes.c        |    2 
> > > >  kernel/test_kprobes.c   |  216 ++++++++++++++++++++++++++++++++++++++++++++++++
> > > 
> > > Can you put this somewhere else please? I know there are already some 
> > > test files in kernel/* but imho they all belong into some other 
> > > directory.
> > 
> > agreed - lib/* would be the right place i think - we've got 
> > lib/locking-selftest.c already.
> 
> Actually the right place would be to have a separate toplevel directory
> I think, and a separate menu in the kernel config machinery.  Thay way
> tests are in one place and easily spottable.

Seconded...

	Sam

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Kprobes: Add kprobes smoke tests that run on boot
  2008-01-08 23:28     ` Andi Kleen
@ 2008-01-09 20:24       ` Jim Keniston
  2008-01-09 21:21         ` Andi Kleen
  0 siblings, 1 reply; 14+ messages in thread
From: Jim Keniston @ 2008-01-09 20:24 UTC (permalink / raw)
  To: Andi Kleen; +Cc: ananth, akpm, lkml, mingo, mhiramat, davem, hskinnemoen

On Wed, 2008-01-09 at 00:28 +0100, Andi Kleen wrote:
> > I have no problem with that, but if we want to make it buildable as a
> > module, the call to get_kprobe() needs to be replaced with some other
> > gcc-inline-defeating mechanism, or we need to export get_probe().  I
> 
> It's still unclear where noinline does not work (do you have details on that? 
> It sounds a little dubious) ...

Here's a simplified version of a module we've used to gauge kprobes
performance.  On my system (i386, 2.6.23-rc8 at the moment, gcc version
4.1.2), the module calls the (empty) probed function (probeme) niter
times, but reports zero probe hits -- indicating probeme was inlined
even though it was declared noinline.

If I change probeme to a varargs function, per your suggestion -- see
diffs below -- the proper number of probe hits are reported.
----- noinline.c -----
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/jiffies.h>
#include <linux/kprobes.h>

/*
 * Sample usage: insmod noinline.ko niter=5000000
 * printk should report 5000000 calls.
 */

static int niter = 0;
module_param(niter, int, 0);
MODULE_PARM_DESC(niter, "iterations");

static int ncalls = 0;

static int counter_hdlr(struct kprobe *p, struct pt_regs *regs)
{
	ncalls++;
	return 0;
}

// #define noinline __attribute__((noinline))
noinline static void probeme(void)
{
}

struct kprobe kp = {
	.addr = (kprobe_opcode_t*) probeme,
	.pre_handler = counter_hdlr
};

static int __init noinline_init(void)
{
	int ret;
	int i;
	u64 start, stop;

	ret = register_kprobe(&kp);
	if (ret != 0) {
		printk(KERN_ERR "register_kprobe returns %d\n", ret);
		return ret;
	}

	start = get_jiffies_64();
	for (i = 1; i <= niter; i++)
		probeme();
	stop = get_jiffies_64();
	printk(KERN_INFO "noinline test: %d iterations in %lld jiffies\n",
		niter, stop-start);
	printk(KERN_INFO "Counted %d calls\n", ncalls);
	return 0;
}

static void __exit noinline_exit(void)
{
	unregister_kprobe(&kp);
	printk(KERN_INFO "noinline test: exiting...\n");
}

module_init(noinline_init);
module_exit(noinline_exit);
MODULE_LICENSE("GPL");
----- Change probeme to a varargs function -----
--- noinline.c	2008-01-09 11:26:09.000000000 -0800
+++ noinline2.c	2008-01-09 11:59:54.000000000 -0800
@@ -22,8 +22,13 @@
 }
 
 // #define noinline __attribute__((noinline))
-noinline static void probeme(void)
+noinline static void probeme(int nargs, ...)
 {
+	va_list args;
+	va_start(args, nargs);
+	while (nargs-- > 0)
+		printk(KERN_INFO "%p\n", va_arg(args, char*));
+	va_end(args);
 }
 
 struct kprobe kp = {
@@ -45,9 +50,9 @@
 
 	start = get_jiffies_64();
 	for (i = 1; i <= niter; i++)
-		probeme();
+		probeme(0);
 	stop = get_jiffies_64();
-	printk(KERN_INFO "noinline test: %d iterations in %lld jiffies\n",
+	printk(KERN_INFO "noinline2 test: %d iterations in %lld jiffies\n",
 		niter, stop-start);
 	printk(KERN_INFO "Counted %d calls\n", ncalls);
 	return 0;
@@ -56,7 +61,7 @@
 static void __exit noinline_exit(void)
 {
 	unregister_kprobe(&kp);
-	printk(KERN_INFO "noinline test: exiting...\n");
+	printk(KERN_INFO "noinline2 test: exiting...\n");
 }
 
 module_init(noinline_init);

...
> -Andi

Thanks for the suggestions.
Jim


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Kprobes: Add kprobes smoke tests that run on boot
  2008-01-09 20:24       ` Jim Keniston
@ 2008-01-09 21:21         ` Andi Kleen
  2008-01-09 22:33           ` Jim Keniston
  0 siblings, 1 reply; 14+ messages in thread
From: Andi Kleen @ 2008-01-09 21:21 UTC (permalink / raw)
  To: Jim Keniston
  Cc: Andi Kleen, ananth, akpm, lkml, mingo, mhiramat, davem, hskinnemoen

On Wed, Jan 09, 2008 at 12:24:00PM -0800, Jim Keniston wrote:
> On Wed, 2008-01-09 at 00:28 +0100, Andi Kleen wrote:
> > > I have no problem with that, but if we want to make it buildable as a
> > > module, the call to get_kprobe() needs to be replaced with some other
> > > gcc-inline-defeating mechanism, or we need to export get_probe().  I
> > 
> > It's still unclear where noinline does not work (do you have details on that? 
> > It sounds a little dubious) ...
> 
> Here's a simplified version of a module we've used to gauge kprobes
> performance.  On my system (i386, 2.6.23-rc8 at the moment, gcc version
> 4.1.2), the module calls the (empty) probed function (probeme) niter
> times, but reports zero probe hits -- indicating probeme was inlined
> even though it was declared noinline.

Yes indeed looks like a gcc bug. Have you reported it?

-Andi

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Kprobes: Add kprobes smoke tests that run on boot
  2008-01-09 21:21         ` Andi Kleen
@ 2008-01-09 22:33           ` Jim Keniston
  0 siblings, 0 replies; 14+ messages in thread
From: Jim Keniston @ 2008-01-09 22:33 UTC (permalink / raw)
  To: Andi Kleen; +Cc: ananth, akpm, lkml, mingo, mhiramat, davem, hskinnemoen

On Wed, 2008-01-09 at 22:21 +0100, Andi Kleen wrote:
> On Wed, Jan 09, 2008 at 12:24:00PM -0800, Jim Keniston wrote:
> > On Wed, 2008-01-09 at 00:28 +0100, Andi Kleen wrote:
> > > > I have no problem with that, but if we want to make it buildable as a
> > > > module, the call to get_kprobe() needs to be replaced with some other
> > > > gcc-inline-defeating mechanism, or we need to export get_probe().  I
> > > 
> > > It's still unclear where noinline does not work (do you have details on that? 
> > > It sounds a little dubious) ...
> > 
> > Here's a simplified version of a module we've used to gauge kprobes
> > performance.  On my system (i386, 2.6.23-rc8 at the moment, gcc version
> > 4.1.2), the module calls the (empty) probed function (probeme) niter
> > times, but reports zero probe hits -- indicating probeme was inlined
> > even though it was declared noinline.
> 
> Yes indeed looks like a gcc bug. Have you reported it?
> 
> -Andi

There's already a gcc bug report that appears to describe the same
problem:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34563
There seems to be some doubt as to whether it's really a bug, so I added
my 2 cents, including a pointer to this thread.

Jim 


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2008-01-09 22:39 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-01-08  6:33 [PATCH] Kprobes: Add kprobes smoke tests that run on boot Ananth N Mavinakayanahalli
2008-01-08  9:15 ` Ingo Molnar
2008-01-08 21:00 ` Andi Kleen
2008-01-08 22:18   ` Ingo Molnar
2008-01-08 22:49     ` Andi Kleen
2008-01-08 22:50       ` Ingo Molnar
2008-01-09  8:00     ` Christoph Hellwig
2008-01-09  8:08       ` Sam Ravnborg
2008-01-08 23:10   ` Jim Keniston
2008-01-08 23:28     ` Andi Kleen
2008-01-09 20:24       ` Jim Keniston
2008-01-09 21:21         ` Andi Kleen
2008-01-09 22:33           ` Jim Keniston
2008-01-09  7:43 ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).