This is the mail archive of the systemtap@sources.redhat.com 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 1/6] kprobes: use per_cpu data areas - base kprobes changes


Arch agnostic changes for using per_cpu infrastructure

Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>

 include/linux/kprobes.h |   11 ++---------
 kernel/kprobes.c        |   43 ++++++++++++++++++++++++++++---------------
 2 files changed, 30 insertions(+), 24 deletions(-)

Index: linux-2.6.13-rc3/include/linux/kprobes.h
===================================================================
--- linux-2.6.13-rc3.orig/include/linux/kprobes.h	2005-07-29 12:45:03.000000000 -0400
+++ linux-2.6.13-rc3/include/linux/kprobes.h	2005-07-29 12:49:50.000000000 -0400
@@ -146,13 +146,6 @@ struct kretprobe_instance {
 void lock_kprobes(void);
 void unlock_kprobes(void);
 
-/* kprobe running now on this CPU? */
-static inline int kprobe_running(void)
-{
-	extern unsigned int kprobe_cpu;
-	return kprobe_cpu == smp_processor_id();
-}
-
 extern int arch_prepare_kprobe(struct kprobe *p);
 extern void arch_copy_kprobe(struct kprobe *p);
 extern void arch_arm_kprobe(struct kprobe *p);
@@ -183,9 +176,9 @@ void add_rp_inst(struct kretprobe_instan
 void kprobe_flush_task(struct task_struct *tk);
 void recycle_rp_inst(struct kretprobe_instance *ri);
 #else /* CONFIG_KPROBES */
-static inline int kprobe_running(void)
+static inline struct kprobe *kprobe_running(void)
 {
-	return 0;
+	return NULL;
 }
 static inline int register_kprobe(struct kprobe *p)
 {
Index: linux-2.6.13-rc3/kernel/kprobes.c
===================================================================
--- linux-2.6.13-rc3.orig/kernel/kprobes.c	2005-07-29 12:45:03.000000000 -0400
+++ linux-2.6.13-rc3/kernel/kprobes.c	2005-07-29 12:49:50.000000000 -0400
@@ -50,7 +50,7 @@ static struct hlist_head kretprobe_inst_
 
 unsigned int kprobe_cpu = NR_CPUS;
 static DEFINE_SPINLOCK(kprobe_lock);
-static struct kprobe *curr_kprobe;
+static DEFINE_PER_CPU(struct kprobe *, curr_kprobe) = NULL;
 
 /*
  * kprobe->ainsn.insn points to the copy of the instruction to be
@@ -165,6 +165,17 @@ void __kprobes unlock_kprobes(void)
 	spin_unlock(&kprobe_lock);
 }
 
+/* We have preemption disabled.. so it is safe to use __ versions */
+static inline void set_curr_kprobe(struct kprobe *kp)
+{
+	__get_cpu_var(curr_kprobe) = kp;
+}
+
+static inline void reset_curr_kprobe(void)
+{
+	__get_cpu_var(curr_kprobe) = NULL;
+}
+
 /* You have to be holding the kprobe_lock */
 struct kprobe __kprobes *get_kprobe(void *addr)
 {
@@ -190,11 +201,11 @@ static int __kprobes aggr_pre_handler(st
 
 	list_for_each_entry(kp, &p->list, list) {
 		if (kp->pre_handler) {
-			curr_kprobe = kp;
+			set_curr_kprobe(kp);
 			if (kp->pre_handler(kp, regs))
 				return 1;
 		}
-		curr_kprobe = NULL;
+		reset_curr_kprobe();
 	}
 	return 0;
 }
@@ -206,9 +217,9 @@ static void __kprobes aggr_post_handler(
 
 	list_for_each_entry(kp, &p->list, list) {
 		if (kp->post_handler) {
-			curr_kprobe = kp;
+			set_curr_kprobe(kp);
 			kp->post_handler(kp, regs, flags);
-			curr_kprobe = NULL;
+			reset_curr_kprobe();
 		}
 	}
 	return;
@@ -217,12 +228,14 @@ static void __kprobes aggr_post_handler(
 static int __kprobes aggr_fault_handler(struct kprobe *p, struct pt_regs *regs,
 					int trapnr)
 {
+	struct kprobe *cur = __get_cpu_var(curr_kprobe);
+
 	/*
 	 * if we faulted "during" the execution of a user specified
 	 * probe handler, invoke just that probe's fault handler
 	 */
-	if (curr_kprobe && curr_kprobe->fault_handler) {
-		if (curr_kprobe->fault_handler(curr_kprobe, regs, trapnr))
+	if (cur && cur->fault_handler) {
+		if (cur->fault_handler(cur, regs, trapnr))
 			return 1;
 	}
 	return 0;
@@ -230,15 +243,15 @@ static int __kprobes aggr_fault_handler(
 
 static int __kprobes aggr_break_handler(struct kprobe *p, struct pt_regs *regs)
 {
-	struct kprobe *kp = curr_kprobe;
-	if (curr_kprobe && kp->break_handler) {
-		if (kp->break_handler(kp, regs)) {
-			curr_kprobe = NULL;
-			return 1;
-		}
+	struct kprobe *cur = __get_cpu_var(curr_kprobe);
+	int ret = 0;
+
+	if (cur && cur->break_handler) {
+		if (cur->break_handler(cur, regs))
+			ret = 1;
 	}
-	curr_kprobe = NULL;
-	return 0;
+	reset_curr_kprobe();
+	return ret;
 }
 
 struct kretprobe_instance __kprobes *get_free_rp_inst(struct kretprobe *rp)


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