]> sourceware.org Git - systemtap.git/commitdiff
kprobes.c: refactor stapkp_register_probe()
authorJonathan Lebon <jlebon@redhat.com>
Tue, 17 Jun 2014 20:54:47 +0000 (16:54 -0400)
committerJonathan Lebon <jlebon@redhat.com>
Mon, 11 Aug 2014 19:40:00 +0000 (15:40 -0400)
Here, we split the general stapkp_register_probe into a kprobe and
kretprobe variant, and then further split the work into preparing the
kprobe for registration and actually registering it.

runtime/linux/kprobes.c

index c4d29bdf4151d24e24e6f7dd7cb1e13da2b0555d..871c964fc015c873c4eadddd0f1412c1c6aa2350 100644 (file)
@@ -90,81 +90,146 @@ stapkp_relocate_addr(struct stap_dwarf_probe *sdp)
 
 
 static int
-stapkp_register_probe(struct stap_dwarf_probe *sdp,
+stapkp_prepare_kprobe(struct stap_dwarf_probe *sdp,
                       struct stap_dwarf_kprobe *kp)
 {
-   int rc = 0;
-
    unsigned long addr = stapkp_relocate_addr(sdp);
-
    if (addr == 0)
-      return 0; // quietly; assume module is absent
+      return 1;
 
-   if (sdp->return_p) {
+   kp->u.kp.addr = (void *) addr;
+   kp->u.kp.pre_handler = &enter_kprobe_probe;
 
-      kp->u.krp.kp.addr = (void *) addr;
-      if (sdp->maxactive_p) {
-         kp->u.krp.maxactive = sdp->maxactive_val;
-      } else {
-         kp->u.krp.maxactive = KRETACTIVE;
-      }
+#ifdef __ia64__ // PR6028
+   kp->dummy.addr = kp->u.kp.addr;
+   kp->dummy.pre_handler = NULL;
+#endif
 
-      kp->u.krp.handler = &enter_kretprobe_probe;
+   return 0;
+}
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
-      if (sdp->entry_probe) {
-         kp->u.krp.entry_handler = &enter_kretprobe_entry_probe;
-         kp->u.krp.data_size = sdp->saved_longs * sizeof(int64_t) +
-                               sdp->saved_strings * MAXSTRINGLEN;
-      }
+
+static int
+stapkp_arch_register_kprobe(struct stap_dwarf_probe *sdp,
+                            struct stap_dwarf_kprobe *kp)
+{
+   int ret = 0;
+
+#ifndef __ia64__
+   ret = register_kprobe (& kp->u.kp);
+#else // PR6028
+   ret = register_kprobe (& kp->dummy);
+   if (ret == 0) {
+      ret = register_kprobe (& kp->u.kp);
+      if (ret != 0)
+         unregister_kprobe (& kp->dummy);
+   }
 #endif
 
-      // to ensure safeness of bspcache, always use aggr_kprobe on ia64
-#ifdef __ia64__
-      kp->dummy.addr = kp->u.krp.kp.addr;
-      kp->dummy.pre_handler = NULL;
-      rc = register_kprobe (& kp->dummy);
-      if (rc == 0) {
-         rc = register_kretprobe (& kp->u.krp);
-         if (rc != 0)
-            unregister_kprobe (& kp->dummy);
-      }
-#else
-      rc = register_kretprobe (& kp->u.krp);
+   sdp->registered_p = (ret ? 0 : 1);
+
+#ifdef STP_ON_THE_FLY
+   // kprobes are enabled by default upon registration
+   sdp->enabled_p = sdp->registered_p;
 #endif
 
-   } else { // !sdp->return_p
+   return ret;
+}
 
-      // to ensure safeness of bspcache, always use aggr_kprobe on ia64
-      kp->u.kp.addr = (void *) addr;
-      kp->u.kp.pre_handler = &enter_kprobe_probe;
 
-#ifdef __ia64__
-      kp->dummy.addr = kp->u.kp.addr;
-      kp->dummy.pre_handler = NULL;
-      rc = register_kprobe (& kp->dummy);
-      if (rc == 0) {
-         rc = register_kprobe (& kp->u.kp);
-         if (rc != 0)
-            unregister_kprobe (& kp->dummy);
-      }
-#else
-      rc = register_kprobe (& kp->u.kp);
+static int
+stapkp_register_kprobe(struct stap_dwarf_probe *sdp,
+                       struct stap_dwarf_kprobe *kp)
+{
+   int ret = stapkp_prepare_kprobe(sdp, kp);
+   if (ret == 0)
+      ret = stapkp_arch_register_kprobe(sdp, kp);
+   return ret;
+}
+
+
+static int
+stapkp_prepare_kretprobe(struct stap_dwarf_probe *sdp,
+                         struct stap_dwarf_kprobe *kp)
+{
+   unsigned long addr = stapkp_relocate_addr(sdp);
+   if (addr == 0)
+      return 1;
+
+   kp->u.krp.kp.addr = (void *) addr;
+
+   if (sdp->maxactive_p)
+      kp->u.krp.maxactive = sdp->maxactive_val;
+   else
+      kp->u.krp.maxactive = KRETACTIVE;
+
+   kp->u.krp.handler = &enter_kretprobe_probe;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
+   if (sdp->entry_probe) {
+      kp->u.krp.entry_handler = &enter_kretprobe_entry_probe;
+      kp->u.krp.data_size = sdp->saved_longs * sizeof(int64_t) +
+                            sdp->saved_strings * MAXSTRINGLEN;
+   }
 #endif
 
+#ifdef __ia64__ // PR6028
+   kp->dummy.addr = kp->u.krp.kp.addr;
+   kp->dummy.pre_handler = NULL;
+#endif
+
+   return 0;
+}
+
+
+static int
+stapkp_arch_register_kretprobe(struct stap_dwarf_probe *sdp,
+                               struct stap_dwarf_kprobe *kp)
+{
+   int ret = 0;
+
+#ifndef __ia64__
+   ret = register_kretprobe (& kp->u.krp);
+#else // PR6028
+   ret = register_kprobe (& kp->dummy);
+   if (ret == 0) {
+      ret = register_kretprobe (& kp->u.krp);
+      if (ret != 0)
+         unregister_kprobe (& kp->dummy);
    }
+#endif
 
-   if (rc)
-      sdp->registered_p = 0;
-   else
-      sdp->registered_p = 1;
+   sdp->registered_p = (ret ? 0 : 1);
 
 #ifdef STP_ON_THE_FLY
    // kprobes are enabled by default upon registration
    sdp->enabled_p = sdp->registered_p;
 #endif
 
-   return rc;
+   return ret;
+}
+
+
+static int
+stapkp_register_kretprobe(struct stap_dwarf_probe *sdp,
+                          struct stap_dwarf_kprobe *kp)
+{
+   int ret = stapkp_prepare_kretprobe(sdp, kp);
+   if (ret == 0)
+      ret = stapkp_arch_register_kretprobe(sdp, kp);
+   return ret;
+}
+
+
+static int
+stapkp_register_probe(struct stap_dwarf_probe *sdp,
+                      struct stap_dwarf_kprobe *kp)
+{
+   if (sdp->registered_p)
+      return 0;
+
+   return sdp->return_p ? stapkp_register_kretprobe(sdp, kp)
+                        : stapkp_register_kprobe(sdp, kp);
 }
 
 
This page took 0.035671 seconds and 5 git commands to generate.