[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1199910240.4162.31.camel@dyn9047018096.beaverton.ibm.com>
Date: Wed, 09 Jan 2008 12:24:00 -0800
From: Jim Keniston <jkenisto@...ibm.com>
To: Andi Kleen <andi@...stfloor.org>
Cc: ananth@...ibm.com, akpm@...ux-foundation.org,
lkml <linux-kernel@...r.kernel.org>, mingo@...e.hu,
mhiramat@...hat.com, davem@...emloft.net, hskinnemoen@...el.com
Subject: Re: [PATCH] Kprobes: Add kprobes smoke tests that run on boot
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
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists