From: Vasiliy Ulyanov Date: Wed, 26 Aug 2015 11:32:29 +0000 (+0300) Subject: [FIX] Use stop_machine to disarm kretprobe_instance X-Git-Tag: submit/tizen_2.4/20150912.103527~20 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F58%2F46858%2F4;p=kernel%2Fswap-modules.git [FIX] Use stop_machine to disarm kretprobe_instance Change-Id: Id1fb5f1ad1a13dc76b465bb08d42f55a4886b713 Signed-off-by: Vyacheslav Cherkashin --- diff --git a/kprobe/swap_kprobes.c b/kprobe/swap_kprobes.c index 1a08278..ce18b00 100644 --- a/kprobe/swap_kprobes.c +++ b/kprobe/swap_kprobes.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -930,6 +931,33 @@ static void swap_disarm_krp(struct kretprobe *rp) } } + +struct unreg_krp_args { + struct kretprobe **rps; + size_t size; + int rp_disarm; +}; + +static int __swap_unregister_kretprobes_top(void *data) +{ + struct unreg_krp_args *args = data; + struct kretprobe **rps = args->rps; + size_t size = args->size; + int rp_disarm = args->rp_disarm; + unsigned long flags; + const size_t end = ((size_t) 0) - 1; + + spin_lock_irqsave(&kretprobe_lock, flags); + for (--size; size != end; --size) { + swap_unregister_kprobe(&rps[size]->kp); + if (rp_disarm) + swap_disarm_krp(rps[size]); + } + spin_unlock_irqrestore(&kretprobe_lock, flags); + + return 0; +} + /** * @brief Kretprobes unregister top. Unregisters kprobes. * @@ -941,16 +969,22 @@ static void swap_disarm_krp(struct kretprobe *rp) void swap_unregister_kretprobes_top(struct kretprobe **rps, size_t size, int rp_disarm) { - unsigned long flags; - const size_t end = ((size_t) 0) - 1; - - spin_lock_irqsave(&kretprobe_lock, flags); - for (--size; size != end; --size) { - swap_unregister_kprobe(&rps[size]->kp); - if (rp_disarm) - swap_disarm_krp(rps[size]); + struct unreg_krp_args args = { + .rps = rps, + .size = size, + .rp_disarm = rp_disarm, + }; + + if (rp_disarm) { + int ret; + + ret = stop_machine(__swap_unregister_kretprobes_top, + &args, NULL); + if (ret) + pr_err("%s failed (%d)\n", __func__, ret); + } else { + __swap_unregister_kretprobes_top(&args); } - spin_unlock_irqrestore(&kretprobe_lock, flags); } EXPORT_SYMBOL_GPL(swap_unregister_kretprobes_top); diff --git a/task_data/task_data.c b/task_data/task_data.c index 51f1578..085e016 100644 --- a/task_data/task_data.c +++ b/task_data/task_data.c @@ -161,7 +161,6 @@ static int __task_data_exit(void *data) struct task_data *td; swap_unregister_kprobe(&do_exit_probe); - swap_unregister_kretprobe(©_process_rp); do_each_thread(g, t) { td = __td(t); @@ -185,14 +184,15 @@ static void task_data_stop(void) { int ret; + swap_unregister_kretprobe(©_process_rp); + /* stop_machine: the same here */ - ret = stop_machine(__task_data_exit, ©_process_rp, NULL); + ret = stop_machine(__task_data_exit, NULL, NULL); if (ret) { printk(TD_PREFIX "task data cleanup failed: %d\n", ret); /* something went wrong: at least make sure we unregister * all the installed probes */ swap_unregister_kprobe(&do_exit_probe); - swap_unregister_kretprobe(©_process_rp); } }