From: Jonathan Lebon Date: Tue, 17 Jun 2014 20:54:47 +0000 (-0400) Subject: kprobes.c: refactor stapkp_register_probe() X-Git-Tag: release-2.6~54^2~28 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=0d0ba9f874b383dbdc1d64eefd099ad3353a3d10;p=systemtap.git kprobes.c: refactor stapkp_register_probe() 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. --- diff --git a/runtime/linux/kprobes.c b/runtime/linux/kprobes.c index c4d29bdf4..871c964fc 100644 --- a/runtime/linux/kprobes.c +++ b/runtime/linux/kprobes.c @@ -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); }