From: Vyacheslav Cherkashin Date: Wed, 26 Aug 2015 11:19:55 +0000 (+0300) Subject: [FIX] Move call_mm_release invocation out of atomic context X-Git-Tag: submit/tizen_2.4/20150912.103527~21 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F57%2F46857%2F4;p=kernel%2Fswap-modules.git [FIX] Move call_mm_release invocation out of atomic context Change-Id: I2f3016c08a6e8c027681beb9c629e27b4f688b4f Signed-off-by: Vyacheslav Cherkashin --- diff --git a/us_manager/helper.c b/us_manager/helper.c index 3ba5c4f..37e4882 100644 --- a/us_manager/helper.c +++ b/us_manager/helper.c @@ -280,15 +280,41 @@ static void rm_uprobes_child(struct kretprobe_instance *ri, } +/* FIXME: sync with stop */ +static unsigned long cp_cb(void *data) +{ + if (atomic_read(&stop_flag)) + call_mm_release(current); + + return 0; +} + +static int pre_handler_cp(struct kprobe *p, struct pt_regs *regs) +{ + int ret = 0; + + if (is_kthread(current)) + goto out; + + if (!atomic_read(&stop_flag)) + goto out; + + ret = set_kjump_cb(regs, cp_cb, NULL, 0); + if (ret < 0) { + pr_err("set_kjump_cp, ret=%d\n", ret); + ret = 0; + } +out: + return ret; +} + + static atomic_t copy_process_cnt = ATOMIC_INIT(0); static int entry_handler_cp(struct kretprobe_instance *ri, struct pt_regs *regs) { atomic_inc(©_process_cnt); - if (atomic_read(&stop_flag)) - call_mm_release(current); - return 0; } @@ -315,14 +341,24 @@ static struct kretprobe cp_kretprobe = { .handler = ret_handler_cp, }; +static struct kprobe cp_kprobe = { + .pre_handler = pre_handler_cp +}; + static int register_cp(void) { int ret; - ret = swap_register_kretprobe(&cp_kretprobe); + + ret = swap_register_kprobe(&cp_kprobe); if (ret) - printk(KERN_INFO - "swap_register_kretprobe(copy_process) ret=%d!\n", ret); + pr_err("swap_register_kprobe(copy_process) ret=%d!\n", ret); + + ret = swap_register_kretprobe(&cp_kretprobe); + if (ret) { + pr_err("swap_register_kretprobe(copy_process) ret=%d!\n", ret); + swap_unregister_kprobe(&cp_kprobe); + } return ret; } @@ -334,6 +370,7 @@ static void unregister_cp(void) synchronize_sched(); } while (atomic_read(©_process_cnt)); swap_unregister_kretprobe_bottom(&cp_kretprobe); + swap_unregister_kprobe(&cp_kprobe); } @@ -811,6 +848,7 @@ int once_helper(void) cp_kretprobe.kp.addr = (kprobe_opcode_t *)swap_ksyms_substr(sym); if (cp_kretprobe.kp.addr == NULL) goto not_found; + cp_kprobe.addr = cp_kretprobe.kp.addr; sym = "mm_release"; mr_kprobe.addr = (kprobe_opcode_t *)swap_ksyms(sym); diff --git a/us_manager/pf/pf_group.c b/us_manager/pf/pf_group.c index 898ad7e..0057636 100644 --- a/us_manager/pf/pf_group.c +++ b/us_manager/pf/pf_group.c @@ -592,13 +592,13 @@ void call_mm_release(struct task_struct *task) struct sspt_proc *proc; sspt_proc_write_lock(); - proc = sspt_proc_get_by_task(task); if (proc) - /* TODO: uninstall_proc - is not atomic context */ - uninstall_proc(proc); - + list_del(&proc->list); sspt_proc_write_unlock(); + + if (proc) + uninstall_proc(proc); } /**