aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2012-08-06 08:49:56 -0400
committerOleg Nesterov <oleg@redhat.com>2012-08-28 12:21:17 -0400
commit5e5be71ab3fd8bd2076606923791ece1634c199c (patch)
tree3bfa62096792ec812d8b4e3aa3caa6b5662384da /kernel
parentf1a45d023193f7d8e55e384090b645d609325393 (diff)
uprobes: Change uprobe_mmap() to ignore the errors but check fatal_signal_pending()
Once install_breakpoint() fails uprobe_mmap() "ignores" all other uprobes and returns the error. It was never really needed to to stop after the first error, and in fact it was always wrong at least in -ENOTSUPP case. Change uprobe_mmap() to ignore the errors and always return 0. This is not what we want in the long term, but until we teach the callers to handle the failure it would be better to remove the pointless complications. And this doesn't look too bad, the only "reasonable" error is ENOMEM but in this case the caller should be oom-killed in the likely case or the system has more serious problems. However it makes sense to stop if fatal_signal_pending() == T. In particular this helps if the task was oom-killed. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/events/uprobes.c27
1 files changed, 6 insertions, 21 deletions
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index ce59c100d65f..298fbbdf57e6 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -994,23 +994,16 @@ static void build_probe_list(struct inode *inode,
994} 994}
995 995
996/* 996/*
997 * Called from mmap_region. 997 * Called from mmap_region/vma_adjust with mm->mmap_sem acquired.
998 * called with mm->mmap_sem acquired.
999 * 998 *
1000 * Return -ve no if we fail to insert probes and we cannot 999 * Currently we ignore all errors and always return 0, the callers
1001 * bail-out. 1000 * can't handle the failure anyway.
1002 * Return 0 otherwise. i.e:
1003 *
1004 * - successful insertion of probes
1005 * - (or) no possible probes to be inserted.
1006 * - (or) insertion of probes failed but we can bail-out.
1007 */ 1001 */
1008int uprobe_mmap(struct vm_area_struct *vma) 1002int uprobe_mmap(struct vm_area_struct *vma)
1009{ 1003{
1010 struct list_head tmp_list; 1004 struct list_head tmp_list;
1011 struct uprobe *uprobe, *u; 1005 struct uprobe *uprobe, *u;
1012 struct inode *inode; 1006 struct inode *inode;
1013 int ret;
1014 1007
1015 if (!atomic_read(&uprobe_events) || !valid_vma(vma, true)) 1008 if (!atomic_read(&uprobe_events) || !valid_vma(vma, true))
1016 return 0; 1009 return 0;
@@ -1022,24 +1015,16 @@ int uprobe_mmap(struct vm_area_struct *vma)
1022 mutex_lock(uprobes_mmap_hash(inode)); 1015 mutex_lock(uprobes_mmap_hash(inode));
1023 build_probe_list(inode, vma, vma->vm_start, vma->vm_end, &tmp_list); 1016 build_probe_list(inode, vma, vma->vm_start, vma->vm_end, &tmp_list);
1024 1017
1025 ret = 0;
1026 list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) { 1018 list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) {
1027 if (!ret) { 1019 if (!fatal_signal_pending(current)) {
1028 unsigned long vaddr = offset_to_vaddr(vma, uprobe->offset); 1020 unsigned long vaddr = offset_to_vaddr(vma, uprobe->offset);
1029 1021 install_breakpoint(uprobe, vma->vm_mm, vma, vaddr);
1030 ret = install_breakpoint(uprobe, vma->vm_mm, vma, vaddr);
1031 /*
1032 * We can race against uprobe_register(), see the
1033 * comment near uprobe_hash().
1034 */
1035 if (ret == -EEXIST)
1036 ret = 0;
1037 } 1022 }
1038 put_uprobe(uprobe); 1023 put_uprobe(uprobe);
1039 } 1024 }
1040 mutex_unlock(uprobes_mmap_hash(inode)); 1025 mutex_unlock(uprobes_mmap_hash(inode));
1041 1026
1042 return ret; 1027 return 0;
1043} 1028}
1044 1029
1045/* 1030/*