linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
	Oleg Nesterov <oleg@redhat.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Linux-mm <linux-mm@kvack.org>, Ingo Molnar <mingo@elte.hu>,
	Andi Kleen <andi@firstfloor.org>,
	Christoph Hellwig <hch@infradead.org>,
	Steven Rostedt <rostedt@goodmis.org>,
	Roland McGrath <roland@hack.frob.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>,
	Arnaldo Carvalho de Melo <acme@infradead.org>,
	Anton Arapov <anton@redhat.com>,
	Ananth N Mavinakayanahalli <ananth@in.ibm.com>,
	Jim Keniston <jkenisto@linux.vnet.ibm.com>,
	Stephen Wilson <wilsons@start.ca>
Subject: Re: [PATCH v7 3.2-rc2 3/30] uprobes: register/unregister probes.
Date: Thu, 01 Dec 2011 14:20:59 +0100	[thread overview]
Message-ID: <1322745659.4699.17.camel@twins> (raw)
In-Reply-To: <20111118110713.10512.9461.sendpatchset@srdronam.in.ibm.com>

On Fri, 2011-11-18 at 16:37 +0530, Srikar Dronamraju wrote:
> +static int __register_uprobe(struct inode *inode, loff_t offset,
> +                               struct uprobe *uprobe)
> +{
> +       struct list_head try_list;
> +       struct vm_area_struct *vma;
> +       struct address_space *mapping;
> +       struct vma_info *vi, *tmpvi;
> +       struct mm_struct *mm;
> +       loff_t vaddr;
> +       int ret = 0;
> +
> +       mapping = inode->i_mapping;
> +       INIT_LIST_HEAD(&try_list);
> +       while ((vi = find_next_vma_info(&try_list, offset,
> +                                               mapping, true)) != NULL) {
> +               if (IS_ERR(vi)) {
> +                       ret = -ENOMEM;
> +                       break;
> +               }
> +               mm = vi->mm;
> +               down_read(&mm->mmap_sem);
> +               vma = find_vma(mm, (unsigned long)vi->vaddr);
> +               if (!vma || !valid_vma(vma, true)) {
> +                       list_del(&vi->probe_list);
> +                       kfree(vi);
> +                       up_read(&mm->mmap_sem);
> +                       mmput(mm);
> +                       continue;
> +               }
> +               vaddr = vma->vm_start + offset;
> +               vaddr -= vma->vm_pgoff << PAGE_SHIFT;
> +               if (vma->vm_file->f_mapping->host != inode ||
> +                                               vaddr != vi->vaddr) {
> +                       list_del(&vi->probe_list);
> +                       kfree(vi);
> +                       up_read(&mm->mmap_sem);
> +                       mmput(mm);
> +                       continue;
> +               }
> +               ret = install_breakpoint(mm);
> +               up_read(&mm->mmap_sem);
> +               mmput(mm);
> +               if (ret && ret == -EEXIST)
> +                       ret = 0;
> +               if (!ret)
> +                       break;
> +       }
> +       list_for_each_entry_safe(vi, tmpvi, &try_list, probe_list) {
> +               list_del(&vi->probe_list);
> +               kfree(vi);
> +       }
> +       return ret;
> +}
> +
> +static void __unregister_uprobe(struct inode *inode, loff_t offset,
> +                                               struct uprobe *uprobe)
> +{
> +       struct list_head try_list;
> +       struct address_space *mapping;
> +       struct vma_info *vi, *tmpvi;
> +       struct vm_area_struct *vma;
> +       struct mm_struct *mm;
> +       loff_t vaddr;
> +
> +       mapping = inode->i_mapping;
> +       INIT_LIST_HEAD(&try_list);
> +       while ((vi = find_next_vma_info(&try_list, offset,
> +                                               mapping, false)) != NULL) {
> +               if (IS_ERR(vi))
> +                       break;
> +               mm = vi->mm;
> +               down_read(&mm->mmap_sem);
> +               vma = find_vma(mm, (unsigned long)vi->vaddr);
> +               if (!vma || !valid_vma(vma, false)) {
> +                       list_del(&vi->probe_list);
> +                       kfree(vi);
> +                       up_read(&mm->mmap_sem);
> +                       mmput(mm);
> +                       continue;
> +               }
> +               vaddr = vma->vm_start + offset;
> +               vaddr -= vma->vm_pgoff << PAGE_SHIFT;
> +               if (vma->vm_file->f_mapping->host != inode ||
> +                                               vaddr != vi->vaddr) {
> +                       list_del(&vi->probe_list);
> +                       kfree(vi);
> +                       up_read(&mm->mmap_sem);
> +                       mmput(mm);
> +                       continue;
> +               }
> +               remove_breakpoint(mm);
> +               up_read(&mm->mmap_sem);
> +               mmput(mm);
> +       }
> +
> +       list_for_each_entry_safe(vi, tmpvi, &try_list, probe_list) {
> +               list_del(&vi->probe_list);
> +               kfree(vi);
> +       }
> +       delete_uprobe(uprobe);
> +} 

I already mentioned on IRC that there's a lot of duplication here and
how to 'solve that'...

Something like the below, it lost the delete_uprobe() bit, and it adds a
few XXX marks where we have to deal with -ENOMEM. Also its not been near
a compiler.

---
 kernel/uprobes.c |   78 ++++++++++++++---------------------------------------
 1 files changed, 21 insertions(+), 57 deletions(-)

diff --git a/kernel/uprobes.c b/kernel/uprobes.c
index 2493191..c57284a 100644
--- a/kernel/uprobes.c
+++ b/kernel/uprobes.c
@@ -622,7 +622,7 @@ static int install_breakpoint(struct mm_struct *mm, struct uprobe *uprobe,
 }
 
 static void remove_breakpoint(struct mm_struct *mm, struct uprobe *uprobe,
-							loff_t vaddr)
+			      struct vm_area_struct *vma, loff_t vaddr)
 {
 	if (!set_orig_insn(mm, uprobe, (unsigned long)vaddr, true))
 		atomic_dec(&mm->mm_uprobes_count);
@@ -713,8 +713,10 @@ static struct vma_info *find_next_vma_info(struct list_head *head,
 	return retvi;
 }
 
-static int __register_uprobe(struct inode *inode, loff_t offset,
-				struct uprobe *uprobe)
+typedef int (*vma_func_t)(struct mm_struct *mm, struct uprobe *uprobe,
+			  struct vm_area_struct *vma, unsigned long addr);
+
+static int __for_each_vma(struct uprobe *uprobe, vma_func_t func)
 {
 	struct list_head try_list;
 	struct vm_area_struct *vma;
@@ -724,12 +726,12 @@ static int __register_uprobe(struct inode *inode, loff_t offset,
 	loff_t vaddr;
 	int ret = 0;
 
-	mapping = inode->i_mapping;
+	mapping = uprobe->inode->i_mapping;
 	INIT_LIST_HEAD(&try_list);
-	while ((vi = find_next_vma_info(&try_list, offset,
+	while ((vi = find_next_vma_info(&try_list, uprobe->offset,
 						mapping, true)) != NULL) {
 		if (IS_ERR(vi)) {
-			ret = -ENOMEM;
+			ret = PTR_ERR(vi);
 			break;
 		}
 		mm = vi->mm;
@@ -742,9 +744,9 @@ static int __register_uprobe(struct inode *inode, loff_t offset,
 			mmput(mm);
 			continue;
 		}
-		vaddr = vma->vm_start + offset;
+		vaddr = vma->vm_start + uprobe->offset;
 		vaddr -= vma->vm_pgoff << PAGE_SHIFT;
-		if (vma->vm_file->f_mapping->host != inode ||
+		if (vma->vm_file->f_mapping->host != uprobe->inode ||
 						vaddr != vi->vaddr) {
 			list_del(&vi->probe_list);
 			kfree(vi);
@@ -752,12 +754,12 @@ static int __register_uprobe(struct inode *inode, loff_t offset,
 			mmput(mm);
 			continue;
 		}
-		ret = install_breakpoint(mm, uprobe, vma, vi->vaddr);
+		ret = func(mm, uprobe, vma, vi->vaddr);
 		up_read(&mm->mmap_sem);
 		mmput(mm);
 		if (ret && ret == -EEXIST)
 			ret = 0;
-		if (!ret)
+		if (ret)
 			break;
 	}
 	list_for_each_entry_safe(vi, tmpvi, &try_list, probe_list) {
@@ -767,52 +769,14 @@ static int __register_uprobe(struct inode *inode, loff_t offset,
 	return ret;
 }
 
-static void __unregister_uprobe(struct inode *inode, loff_t offset,
-						struct uprobe *uprobe)
+static int __register_uprobe(struct uprobe *uprobe)
 {
-	struct list_head try_list;
-	struct address_space *mapping;
-	struct vma_info *vi, *tmpvi;
-	struct vm_area_struct *vma;
-	struct mm_struct *mm;
-	loff_t vaddr;
-
-	mapping = inode->i_mapping;
-	INIT_LIST_HEAD(&try_list);
-	while ((vi = find_next_vma_info(&try_list, offset,
-						mapping, false)) != NULL) {
-		if (IS_ERR(vi))
-			break;
-		mm = vi->mm;
-		down_read(&mm->mmap_sem);
-		vma = find_vma(mm, (unsigned long)vi->vaddr);
-		if (!vma || !valid_vma(vma, false)) {
-			list_del(&vi->probe_list);
-			kfree(vi);
-			up_read(&mm->mmap_sem);
-			mmput(mm);
-			continue;
-		}
-		vaddr = vma->vm_start + offset;
-		vaddr -= vma->vm_pgoff << PAGE_SHIFT;
-		if (vma->vm_file->f_mapping->host != inode ||
-						vaddr != vi->vaddr) {
-			list_del(&vi->probe_list);
-			kfree(vi);
-			up_read(&mm->mmap_sem);
-			mmput(mm);
-			continue;
-		}
-		remove_breakpoint(mm, uprobe, vi->vaddr);
-		up_read(&mm->mmap_sem);
-		mmput(mm);
-	}
+	return __for_each_vma(uprobe, install_breakpoint);
+}
 
-	list_for_each_entry_safe(vi, tmpvi, &try_list, probe_list) {
-		list_del(&vi->probe_list);
-		kfree(vi);
-	}
-	delete_uprobe(uprobe);
+static int __unregister_uprobe(struct uprobe *uprobe)
+{
+	return __for_each_vma(uprobe, remove_breakpoint);
 }
 
 /*
@@ -852,10 +816,10 @@ int register_uprobe(struct inode *inode, loff_t offset,
 	mutex_lock(uprobes_hash(inode));
 	uprobe = alloc_uprobe(inode, offset);
 	if (uprobe && !add_consumer(uprobe, consumer)) {
-		ret = __register_uprobe(inode, offset, uprobe);
+		ret = __register_uprobe(uprobe);
 		if (ret) {
 			uprobe->consumers = NULL;
-			__unregister_uprobe(inode, offset, uprobe);
+			__unregister_uprobe(uprobe); // -ENOMEM
 		} else
 			uprobe->flags |= UPROBES_RUN_HANDLER;
 	}
@@ -894,7 +858,7 @@ void unregister_uprobe(struct inode *inode, loff_t offset,
 	}
 
 	if (!uprobe->consumers) {
-		__unregister_uprobe(inode, offset, uprobe);
+		__unregister_uprobe(uprobe); // XXX -ENOMEM
 		uprobe->flags &= ~UPROBES_RUN_HANDLER;
 	}
 	mutex_unlock(uprobes_hash(inode));

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

  parent reply	other threads:[~2011-12-01 13:21 UTC|newest]

Thread overview: 106+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-11-18 11:06 [PATCH v7 3.2-rc2 0/30] uprobes patchset with perf probe support Srikar Dronamraju
2011-11-18 11:06 ` [PATCH v7 3.2-rc2 1/30] uprobes: Auxillary routines to insert, find, delete uprobes Srikar Dronamraju
2011-11-23 18:23   ` Peter Zijlstra
2011-11-18 11:07 ` [PATCH v7 3.2-rc2 2/30] uprobes: Allow multiple consumers for an uprobe Srikar Dronamraju
2011-11-18 11:07 ` [PATCH v7 3.2-rc2 3/30] uprobes: register/unregister probes Srikar Dronamraju
2011-11-23 16:09   ` Peter Zijlstra
2011-11-23 16:11     ` Peter Zijlstra
2011-11-24 14:39     ` Srikar Dronamraju
2011-11-23 16:22   ` Peter Zijlstra
2011-11-23 16:27   ` Peter Zijlstra
2011-11-23 16:35   ` Peter Zijlstra
2011-11-28 15:29   ` Peter Zijlstra
2011-11-29  7:48     ` Srikar Dronamraju
2011-11-29 10:52       ` Peter Zijlstra
2011-12-01 13:41         ` Srikar Dronamraju
2011-12-01 13:20   ` Peter Zijlstra [this message]
2011-11-18 11:07 ` [PATCH v7 3.2-rc2 4/30] uprobes: Define hooks for mmap/munmap Srikar Dronamraju
2011-11-23 17:13   ` Peter Zijlstra
2011-11-23 18:10   ` Peter Zijlstra
2011-11-24 13:47     ` Srikar Dronamraju
2011-11-24 14:13       ` Peter Zijlstra
2011-11-24 14:25         ` Srikar Dronamraju
2011-11-28 14:59       ` Peter Zijlstra
2011-11-29  8:33         ` Srikar Dronamraju
2011-11-29 11:48           ` Peter Zijlstra
2011-11-29 15:05             ` Peter Zijlstra
2011-11-30  5:50               ` Srikar Dronamraju
2011-11-29 16:22             ` Srikar Dronamraju
2011-11-30 12:25               ` Peter Zijlstra
2011-12-01  5:40                 ` Srikar Dronamraju
2011-12-01 11:36                   ` Peter Zijlstra
2011-12-01 13:24                     ` Srikar Dronamraju
2011-11-30  5:30           ` Srikar Dronamraju
2011-11-23 18:15   ` Peter Zijlstra
2011-11-23 19:50     ` Steven Rostedt
2011-11-24 13:37     ` Srikar Dronamraju
2011-11-24 13:47       ` Peter Zijlstra
2011-11-18 11:07 ` [PATCH v7 3.2-rc2 5/30] uprobes: copy of the original instruction Srikar Dronamraju
2011-11-23 18:26   ` Peter Zijlstra
2011-11-23 18:40   ` Peter Zijlstra
2011-11-23 19:49     ` Steven Rostedt
2011-11-23 20:52       ` Peter Zijlstra
2011-11-24 12:50     ` Srikar Dronamraju
2011-11-28 14:23   ` Peter Zijlstra
2011-11-18 11:07 ` [PATCH v7 3.2-rc2 6/30] uprobes: define fixups Srikar Dronamraju
2011-11-18 11:07 ` [PATCH v7 3.2-rc2 7/30] uprobes: uprobes arch info Srikar Dronamraju
2011-11-18 11:08 ` [PATCH v7 3.2-rc2 8/30] x86: analyze instruction and determine fixups Srikar Dronamraju
2011-11-30 18:57   ` Oleg Nesterov
2011-12-01  5:52     ` Srikar Dronamraju
2011-11-18 11:08 ` [PATCH v7 3.2-rc2 9/30] uprobes: Background page replacement Srikar Dronamraju
2011-11-25 14:29   ` Peter Zijlstra
2011-11-25 14:54   ` Peter Zijlstra
2011-11-26  2:25     ` Srikar Dronamraju
2011-11-28 14:13   ` Peter Zijlstra
2011-11-29  7:49     ` Srikar Dronamraju
2011-11-28 15:01   ` Peter Zijlstra
2011-11-18 11:08 ` [PATCH v7 3.2-rc2 10/30] x86: Set instruction pointer Srikar Dronamraju
2011-11-18 11:08 ` [PATCH v7 3.2-rc2 11/30] x86: Introduce TIF_UPROBE FLAG Srikar Dronamraju
2011-11-18 11:09 ` [PATCH v7 3.2-rc2 12/30] uprobes: Handle breakpoint and Singlestep Srikar Dronamraju
2011-11-25 15:24   ` Peter Zijlstra
2011-11-26  2:22     ` Srikar Dronamraju
2011-11-18 11:09 ` [PATCH v7 3.2-rc2 13/30] x86: define a x86 specific exception notifier Srikar Dronamraju
2011-11-18 11:09 ` [PATCH v7 3.2-rc2 14/30] uprobe: register " Srikar Dronamraju
2011-11-18 11:09 ` [PATCH v7 3.2-rc2 15/30] x86: Define x86_64 specific uprobe_task_arch_info structure Srikar Dronamraju
2011-11-18 11:09 ` [PATCH v7 3.2-rc2 16/30] uprobes: Introduce " Srikar Dronamraju
2011-11-18 11:09 ` [PATCH v7 3.2-rc2 17/30] x86: arch specific hooks for pre/post singlestep handling Srikar Dronamraju
2011-11-18 11:10 ` [PATCH v7 3.2-rc2 18/30] uprobes: slot allocation Srikar Dronamraju
2011-11-18 11:10 ` [PATCH v7 3.2-rc2 19/30] tracing: modify is_delete, is_return from ints to bool Srikar Dronamraju
2011-11-23 19:24   ` Steven Rostedt
2011-11-18 11:10 ` [PATCH v7 3.2-rc2 20/30] tracing: Extract out common code for kprobes/uprobes traceevents Srikar Dronamraju
2011-11-23 19:32   ` Steven Rostedt
2011-11-24 13:12     ` Srikar Dronamraju
2011-11-18 11:10 ` [PATCH v7 3.2-rc2 21/30] tracing: uprobes trace_event interface Srikar Dronamraju
2011-11-18 11:10 ` [PATCH v7 3.2-rc2 22/30] perf: rename target_module to target Srikar Dronamraju
2011-11-18 11:11 ` [PATCH v7 3.2-rc2 23/30] perf: perf interface for uprobes Srikar Dronamraju
2011-11-18 11:11 ` [PATCH v7 3.2-rc2 24/30] perf: show possible probes in a given executable file or library Srikar Dronamraju
2011-11-18 11:11 ` [PATCH v7 3.2-rc2 25/30] uprobes: call post_xol() unconditionally Srikar Dronamraju
2011-11-18 11:11 ` [PATCH v7 3.2-rc2 26/30] uprobes: introduce uprobe_deny_signal() Srikar Dronamraju
2011-11-18 11:12 ` [PATCH v7 3.2-rc2 27/30] uprobes: x86: introduce xol_was_trapped() Srikar Dronamraju
2011-11-18 11:12 ` [PATCH v7 3.2-rc2 28/30] uprobes: introduce UTASK_SSTEP_TRAPPED logic Srikar Dronamraju
2011-11-18 11:12 ` [PATCH v7 3.2-rc2 29/30] uprobes: Introduce uprobe flags Srikar Dronamraju
2011-11-18 11:12 ` [PATCH v7 3.2-rc2 30/30] x86: skip singlestep where possible Srikar Dronamraju
2011-11-22  5:03 ` [PATCH v7 3.2-rc2 0/30] uprobes patchset with perf probe support Srikar Dronamraju
2011-11-22 14:49   ` Stephen Rothwell
2011-11-23 13:20     ` Srikar Dronamraju
2011-11-23 13:38       ` Stephen Rothwell
2011-11-28 19:06 ` [PATCH RFC 0/5] uprobes: kill xol vma Oleg Nesterov
2011-11-28 19:06   ` [PATCH 1/5] uprobes: kill pre_ssout(), introduce set_xol_ip() Oleg Nesterov
2011-11-28 19:06   ` [PATCH 2/5] uprobes: introduce uprobe_switch_to() Oleg Nesterov
2011-11-28 19:53     ` Peter Zijlstra
2011-11-29 17:18       ` Oleg Nesterov
2011-11-30 12:11         ` Peter Zijlstra
2011-11-30 17:10           ` Oleg Nesterov
2011-11-28 19:07   ` [PATCH 3/5] uprobes: introduce uprobe_xol_slots[NR_CPUS] Oleg Nesterov
2011-11-28 19:48     ` Peter Zijlstra
2011-11-28 19:52       ` Peter Zijlstra
2011-11-29 18:24     ` Oleg Nesterov
2011-11-28 19:07   ` [PATCH 4/5] uprobes: teach set_xol_ip() to use uprobe_xol_slots[] Oleg Nesterov
2011-11-28 19:07   ` [PATCH 5/5] uprobes: remove the uprobes_xol_area code Oleg Nesterov
2011-11-28 19:57   ` [PATCH RFC 0/5] uprobes: kill xol vma Peter Zijlstra
2011-11-29 10:30   ` Srikar Dronamraju
2011-11-29 18:26     ` Oleg Nesterov
2011-11-30 16:15       ` Andi Kleen
2011-11-30 16:20         ` Peter Zijlstra
2011-11-30 18:47           ` Oleg Nesterov
2011-12-12 17:30   ` Oleg Nesterov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1322745659.4699.17.camel@twins \
    --to=peterz@infradead.org \
    --cc=acme@infradead.org \
    --cc=akpm@linux-foundation.org \
    --cc=ananth@in.ibm.com \
    --cc=andi@firstfloor.org \
    --cc=anton@redhat.com \
    --cc=hch@infradead.org \
    --cc=jkenisto@linux.vnet.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=masami.hiramatsu.pt@hitachi.com \
    --cc=mingo@elte.hu \
    --cc=oleg@redhat.com \
    --cc=roland@hack.frob.com \
    --cc=rostedt@goodmis.org \
    --cc=srikar@linux.vnet.ibm.com \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    --cc=wilsons@start.ca \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).