This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
[RFC][PATCH 4/4][kprobe](djprobe) delayed invoking commit_kprobes()
- From: Masami Hiramatsu <masami dot hiramatsu dot pt at hitachi dot com>
- To: Masami Hiramatsu <masami dot hiramatsu dot pt at hitachi dot com>
- Cc: "Keshavamurthy, Anil S" <anil dot s dot keshavamurthy at intel dot com>, Ingo Molnar <mingo at redhat dot com>, SystemTAP <systemtap at sources dot redhat dot com>, Ananth N Mavinakayanahalli <ananth at in dot ibm dot com>, Prasanna S Panchamukhi <prasanna at in dot ibm dot com>, Satoshi Oshima <soshima at redhat dot com>, Hideo Aoki <haoki at redhat dot com>, Yumiko Sugita <yumiko dot sugita dot yf at hitachi dot com>, Jim Keniston <jkenisto at us dot ibm dot com>, Martin Bligh <mbligh at google dot com>, Greg Kroah-Hartman <gregkh at suse dot de>
- Date: Tue, 21 Nov 2006 15:57:40 +0900
- Subject: [RFC][PATCH 4/4][kprobe](djprobe) delayed invoking commit_kprobes()
- Organization: Systems Development Lab., Hitachi, Ltd., Japan
- References: <4562A150.2030606@hitachi.com>
Hi,
This patch invokes commit_kprobes() function from a worker.
This worker is scheduled automatically by register/
unregister_kprobe() functions (if registered/unregistered
kprobes can be optimized) and is executed in 0.1 second.
If the worker fails freezing processes, it will try again
after 0.1 second. And if it fails 10 times, it will stop trying.
Thanks,
--
Masami HIRAMATSU
Linux Technology Center
Hitachi, Ltd., Systems Development Laboratory
E-mail: masami.hiramatsu.pt@hitachi.com
---
kernel/kprobes.c | 28 +++++++++++++++++++++++++---
1 file changed, 25 insertions(+), 3 deletions(-)
Index: linux-2.6.19-rc5-mm2/kernel/kprobes.c
===================================================================
--- linux-2.6.19-rc5-mm2.orig/kernel/kprobes.c
+++ linux-2.6.19-rc5-mm2/kernel/kprobes.c
@@ -600,6 +600,15 @@ static int __kprobes __register_kprobe_c
#ifdef ARCH_SUPPORTS_DJPROBES
static LIST_HEAD(registering_list);
static LIST_HEAD(unregistering_list);
+static void commit_work_fn(void * data);
+static DECLARE_WORK(commit_work, commit_work_fn, 0);
+#define KPROBE_COMMIT_DELAY (HZ/10)
+#define MAX_COMMIT_RETRY 10
+
+static __always_inline void kick_delayed_commit(void)
+{
+ schedule_delayed_work(&commit_work, KPROBE_COMMIT_DELAY);
+}
/* Switch to stub buffer : this handler is invoked before inserting a jump */
static int __kprobes djprobe_pre_handler(struct kprobe *kp,
@@ -667,6 +676,7 @@ static int __kprobes register_djprobe(st
goto out;
}
list_add(&djpi->list, ®istering_list);
+ kick_delayed_commit();
register_aggr_kprobe(&djpi->kp, p);
out:
@@ -694,6 +704,7 @@ static void __kprobes unregister_djprobe
struct djprobe_instance *djpi;
djpi = container_of(p, struct djprobe_instance, kp);
list_add(&djpi->list, &unregistering_list);
+ kick_delayed_commit();
}
/* Called with kprobe_mutex held */
@@ -733,16 +744,27 @@ static int __kprobes __commit_djprobes(v
return 0;
}
+static atomic_t try_count = ATOMIC_INIT(0);
/*
* Commit to optimize kprobes and remove optimized kprobes.
*/
int __kprobes commit_kprobes(void)
{
- int ret = 0;
+ atomic_set(&try_count, 0);
+ commit_work_fn(NULL);
+ return 0;
+}
+
+static void commit_work_fn(void * data)
+{
+ if (atomic_inc_return(&try_count) > MAX_COMMIT_RETRY) return;
mutex_lock(&kprobe_mutex);
- ret = __commit_djprobes();
+ if (__commit_djprobes() == -EAGAIN) {
+ kick_delayed_commit(); /* try again */
+ } else {
+ atomic_set(&try_count, 0);
+ }
mutex_unlock(&kprobe_mutex);
- return ret;
}
#else /* ARCH_SUPPORTS_DJPROBES */