This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC][PATCH 4/4][kprobe](djprobe) delayed invoking commit_kprobes()


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, &registering_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 */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]