From: Vyacheslav Cherkashin Date: Sun, 30 Aug 2015 13:21:52 +0000 (+0300) Subject: [FIX] Move urp disarming from atomic context on mm_release X-Git-Tag: submit/tizen_2.4/20150912.103527~9 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F09%2F47309%2F3;p=kernel%2Fswap-modules.git [FIX] Move urp disarming from atomic context on mm_release Change-Id: Ia8ff37235b5dfe4d43f8d1578459bb4df444468b Signed-off-by: Vyacheslav Cherkashin --- diff --git a/uprobe/swap_uprobes.c b/uprobe/swap_uprobes.c index c5daf1c..f7573d4 100644 --- a/uprobe/swap_uprobes.c +++ b/uprobe/swap_uprobes.c @@ -894,37 +894,6 @@ int swap_register_uretprobe(struct uretprobe *rp) EXPORT_SYMBOL_GPL(swap_register_uretprobe); /** - * @brief Disarms uretprobes for specified task. - * - * @param task Pointer to the task_struct. - * @return Void. - */ -void swap_discard_pending_uretprobes(struct task_struct *task) -{ - unsigned long flags; - struct uretprobe_instance *ri; - struct hlist_head *head; - struct hlist_node *tmp; - DECLARE_NODE_PTR_FOR_HLIST(node); - - spin_lock_irqsave(&uretprobe_lock, flags); - - head = uretprobe_inst_table_head(task->mm); - swap_hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { - if (ri->task == task) { - printk(KERN_INFO "%s (%d/%d): pending urp inst: %08lx\n", - task->comm, task->tgid, task->pid, - (unsigned long)ri->rp->up.kp.addr); - arch_disarm_urp_inst(ri, task, 0); - recycle_urp_inst(ri); - } - } - - spin_unlock_irqrestore(&uretprobe_lock, flags); -} -EXPORT_SYMBOL_GPL(swap_discard_pending_uretprobes); - -/** * @brief Unregisters uretprobe. * * @param rp Pointer to the ureprobe. @@ -1050,7 +1019,7 @@ static void urinst_info_disarm(struct urinst_info *urinst, struct task_struct *t arch_disarm_urp_inst(&ri, task, tramp); } -void urinst_info_get_current_hlist(struct hlist_head *head) +void urinst_info_get_current_hlist(struct hlist_head *head, bool recycle) { unsigned long flags; struct task_struct *task = current; @@ -1076,6 +1045,8 @@ void urinst_info_get_current_hlist(struct hlist_head *head) last = &urinst->hlist; } + if (recycle) + recycle_urp_inst(ri); } } spin_unlock_irqrestore(&uretprobe_lock, flags); diff --git a/uprobe/swap_uprobes.h b/uprobe/swap_uprobes.h index cbee706..66f165f 100644 --- a/uprobe/swap_uprobes.h +++ b/uprobe/swap_uprobes.h @@ -72,7 +72,7 @@ void uinst_info_destroy(struct uinst_info *uinst); void uinst_info_disarm(struct uinst_info *uinst, struct task_struct *task); -void urinst_info_get_current_hlist(struct hlist_head *head); +void urinst_info_get_current_hlist(struct hlist_head *head, bool recycle); void urinst_info_put_current_hlist(struct hlist_head *head, struct task_struct *task); @@ -167,7 +167,6 @@ void swap_unregister_uretprobe(struct uretprobe *rp); void __swap_unregister_uretprobe(struct uretprobe *rp, int disarm); void swap_unregister_all_uprobes(struct task_struct *task); -void swap_discard_pending_uretprobes(struct task_struct *task); void swap_ujprobe_return(void); struct kprobe *get_ukprobe(void *addr, pid_t tgid); diff --git a/us_manager/helper.c b/us_manager/helper.c index 2e71afd..e5eeb2c 100644 --- a/us_manager/helper.c +++ b/us_manager/helper.c @@ -265,7 +265,7 @@ static void rm_uprobes_child(struct kretprobe_instance *ri, proc = sspt_proc_get_by_task(current); if (proc) { sspt_proc_on_each_ip(proc, func_uinst_creare, (void *)&cdata.head); - urinst_info_get_current_hlist(&cdata.rhead); + urinst_info_get_current_hlist(&cdata.rhead, false); } sspt_proc_write_unlock(); @@ -390,9 +390,27 @@ static unsigned long mr_cb(void *data) struct task_struct *task = *(struct task_struct **)data; if (task->tgid != task->pid) { + struct sspt_proc *proc; + struct hlist_head head = HLIST_HEAD_INIT; + + if (task != current) { + pr_err("call mm_release in isn't current context\n"); + return 0; + } + /* if the thread is killed we need to discard pending * uretprobe instances which have not triggered yet */ - swap_discard_pending_uretprobes(task); + sspt_proc_write_lock(); + proc = sspt_proc_get_by_task(task); + if (proc) { + urinst_info_get_current_hlist(&head, true); + } + sspt_proc_write_unlock(); + + if (proc) { + /* disarm urp for task */ + urinst_info_put_current_hlist(&head, task); + } } else { call_mm_release(task); }