diff options
author | Srikar Dronamraju <srikar@linux.vnet.ibm.com> | 2012-03-30 14:26:46 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2012-03-31 05:50:02 -0400 |
commit | 682968e0c425c60f0dde37977e5beb2b12ddc4cc (patch) | |
tree | 875eb289aa0e08189b2cf7dc99ee522f91e647e7 /include/linux/uprobes.h | |
parent | d4b3b6384f98f8692ad0209891ccdbc7e78bbefe (diff) |
uprobes/core: Optimize probe hits with the help of a counter
Maintain a per-mm counter: number of uprobes that are inserted
on this process address space.
This counter can be used at probe hit time to determine if we
need a lookup in the uprobes rbtree. Everytime a probe gets
inserted successfully, the probe count is incremented and
everytime a probe gets removed, the probe count is decremented.
The new uprobe_munmap hook ensures the count is correct on a
unmap or remap of a region. We expect that once a
uprobe_munmap() is called, the vma goes away. So
uprobe_unregister() finding a probe to unregister would either
mean unmap event hasnt occurred yet or a mmap event on the same
executable file occured after a unmap event.
Additionally, uprobe_mmap hook now also gets called:
a. on every executable vma that is COWed at fork.
b. a vma of interest is newly mapped; breakpoint insertion also
happens at the required address.
On process creation, make sure the probes count in the child is
set correctly.
Special cases that are taken care include:
a. mremap
b. VM_DONTCOPY vmas on fork()
c. insertion/removal races in the parent during fork().
Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com>
Cc: Linux-mm <linux-mm@kvack.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Anton Arapov <anton@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20120330182646.10018.85805.sendpatchset@srdronam.in.ibm.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'include/linux/uprobes.h')
-rw-r--r-- | include/linux/uprobes.h | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h index a111460c07d5..d594d3b3ad4c 100644 --- a/include/linux/uprobes.h +++ b/include/linux/uprobes.h | |||
@@ -99,6 +99,7 @@ struct xol_area { | |||
99 | 99 | ||
100 | struct uprobes_state { | 100 | struct uprobes_state { |
101 | struct xol_area *xol_area; | 101 | struct xol_area *xol_area; |
102 | atomic_t count; | ||
102 | }; | 103 | }; |
103 | extern int __weak set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); | 104 | extern int __weak set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); |
104 | extern int __weak set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr, bool verify); | 105 | extern int __weak set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr, bool verify); |
@@ -106,6 +107,7 @@ extern bool __weak is_swbp_insn(uprobe_opcode_t *insn); | |||
106 | extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); | 107 | extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); |
107 | extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); | 108 | extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); |
108 | extern int uprobe_mmap(struct vm_area_struct *vma); | 109 | extern int uprobe_mmap(struct vm_area_struct *vma); |
110 | extern void uprobe_munmap(struct vm_area_struct *vma); | ||
109 | extern void uprobe_free_utask(struct task_struct *t); | 111 | extern void uprobe_free_utask(struct task_struct *t); |
110 | extern void uprobe_copy_process(struct task_struct *t); | 112 | extern void uprobe_copy_process(struct task_struct *t); |
111 | extern unsigned long __weak uprobe_get_swbp_addr(struct pt_regs *regs); | 113 | extern unsigned long __weak uprobe_get_swbp_addr(struct pt_regs *regs); |
@@ -132,6 +134,9 @@ static inline int uprobe_mmap(struct vm_area_struct *vma) | |||
132 | { | 134 | { |
133 | return 0; | 135 | return 0; |
134 | } | 136 | } |
137 | static inline void uprobe_munmap(struct vm_area_struct *vma) | ||
138 | { | ||
139 | } | ||
135 | static inline void uprobe_notify_resume(struct pt_regs *regs) | 140 | static inline void uprobe_notify_resume(struct pt_regs *regs) |
136 | { | 141 | { |
137 | } | 142 | } |