diff options
| author | Ingo Molnar <mingo@kernel.org> | 2013-02-11 04:41:53 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2013-02-11 04:41:53 -0500 |
| commit | a3d4fd7a2d81604fedfa270d29c824b8d3380c2e (patch) | |
| tree | 1bd1defbfe3f285dfa7c77f94bc5523ac4a82679 /include/linux | |
| parent | 661e591525ffbb0439270bf2a4d165c04f87543d (diff) | |
| parent | b2fe8ba674e8acbb9e8e63510b802c6d054d88a3 (diff) | |
Merge branch 'uprobes/core' of git://git.kernel.org/pub/scm/linux/kernel/git/oleg/misc into perf/core
Improve uprobes performance by adding 'pre-filtering' support,
by Oleg Nesterov:
# time perl -e 'syscall -1 for 1..100_000'
real 0m0.040s
user 0m0.027s
sys 0m0.010s
# perf probe -x /lib/libc.so.6 syscall
# perf record -e probe_libc:syscall sleep 100 &
Before this series:
# time perl -e 'syscall -1 for 1..100_000'
real 0m1.714s
user 0m0.103s
sys 0m1.607s
After:
# time perl -e 'syscall -1 for 1..100_000'
real 0m0.037s
user 0m0.013s
sys 0m0.023s
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/perf_event.h | 9 | ||||
| -rw-r--r-- | include/linux/uprobes.h | 23 |
2 files changed, 25 insertions, 7 deletions
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 42adf012145d..e47ee462c2f2 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
| @@ -135,16 +135,21 @@ struct hw_perf_event { | |||
| 135 | struct { /* software */ | 135 | struct { /* software */ |
| 136 | struct hrtimer hrtimer; | 136 | struct hrtimer hrtimer; |
| 137 | }; | 137 | }; |
| 138 | struct { /* tracepoint */ | ||
| 139 | struct task_struct *tp_target; | ||
| 140 | /* for tp_event->class */ | ||
| 141 | struct list_head tp_list; | ||
| 142 | }; | ||
| 138 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | 143 | #ifdef CONFIG_HAVE_HW_BREAKPOINT |
| 139 | struct { /* breakpoint */ | 144 | struct { /* breakpoint */ |
| 140 | struct arch_hw_breakpoint info; | ||
| 141 | struct list_head bp_list; | ||
| 142 | /* | 145 | /* |
| 143 | * Crufty hack to avoid the chicken and egg | 146 | * Crufty hack to avoid the chicken and egg |
| 144 | * problem hw_breakpoint has with context | 147 | * problem hw_breakpoint has with context |
| 145 | * creation and event initalization. | 148 | * creation and event initalization. |
| 146 | */ | 149 | */ |
| 147 | struct task_struct *bp_target; | 150 | struct task_struct *bp_target; |
| 151 | struct arch_hw_breakpoint info; | ||
| 152 | struct list_head bp_list; | ||
| 148 | }; | 153 | }; |
| 149 | #endif | 154 | #endif |
| 150 | }; | 155 | }; |
diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h index 4f628a6fc5b4..02b83db8e2c5 100644 --- a/include/linux/uprobes.h +++ b/include/linux/uprobes.h | |||
| @@ -35,13 +35,20 @@ struct inode; | |||
| 35 | # include <asm/uprobes.h> | 35 | # include <asm/uprobes.h> |
| 36 | #endif | 36 | #endif |
| 37 | 37 | ||
| 38 | #define UPROBE_HANDLER_REMOVE 1 | ||
| 39 | #define UPROBE_HANDLER_MASK 1 | ||
| 40 | |||
| 41 | enum uprobe_filter_ctx { | ||
| 42 | UPROBE_FILTER_REGISTER, | ||
| 43 | UPROBE_FILTER_UNREGISTER, | ||
| 44 | UPROBE_FILTER_MMAP, | ||
| 45 | }; | ||
| 46 | |||
| 38 | struct uprobe_consumer { | 47 | struct uprobe_consumer { |
| 39 | int (*handler)(struct uprobe_consumer *self, struct pt_regs *regs); | 48 | int (*handler)(struct uprobe_consumer *self, struct pt_regs *regs); |
| 40 | /* | 49 | bool (*filter)(struct uprobe_consumer *self, |
| 41 | * filter is optional; If a filter exists, handler is run | 50 | enum uprobe_filter_ctx ctx, |
| 42 | * if and only if filter returns true. | 51 | struct mm_struct *mm); |
| 43 | */ | ||
| 44 | bool (*filter)(struct uprobe_consumer *self, struct task_struct *task); | ||
| 45 | 52 | ||
| 46 | struct uprobe_consumer *next; | 53 | struct uprobe_consumer *next; |
| 47 | }; | 54 | }; |
| @@ -94,6 +101,7 @@ extern int __weak set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsign | |||
| 94 | extern int __weak set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); | 101 | extern int __weak set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); |
| 95 | extern bool __weak is_swbp_insn(uprobe_opcode_t *insn); | 102 | extern bool __weak is_swbp_insn(uprobe_opcode_t *insn); |
| 96 | extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); | 103 | extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); |
| 104 | extern int uprobe_apply(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, bool); | ||
| 97 | extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); | 105 | extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); |
| 98 | extern int uprobe_mmap(struct vm_area_struct *vma); | 106 | extern int uprobe_mmap(struct vm_area_struct *vma); |
| 99 | extern void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end); | 107 | extern void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end); |
| @@ -117,6 +125,11 @@ uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc) | |||
| 117 | { | 125 | { |
| 118 | return -ENOSYS; | 126 | return -ENOSYS; |
| 119 | } | 127 | } |
| 128 | static inline int | ||
| 129 | uprobe_apply(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, bool add) | ||
| 130 | { | ||
| 131 | return -ENOSYS; | ||
| 132 | } | ||
| 120 | static inline void | 133 | static inline void |
| 121 | uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc) | 134 | uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc) |
| 122 | { | 135 | { |
