diff options
author | Masami Hiramatsu <mhiramat@redhat.com> | 2010-02-25 08:34:07 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-02-25 11:49:24 -0500 |
commit | afd66255b9a48f5851326ddae50e2203fbf71dc9 (patch) | |
tree | 32c7a36a8e2c740b989f16b3e2878f8c565d57f8 /include/linux/kprobes.h | |
parent | 4610ee1d3638fa05ba8e87ccfa971db8e4033ae7 (diff) |
kprobes: Introduce kprobes jump optimization
Introduce kprobes jump optimization arch-independent parts.
Kprobes uses breakpoint instruction for interrupting execution
flow, on some architectures, it can be replaced by a jump
instruction and interruption emulation code. This gains kprobs'
performance drastically.
To enable this feature, set CONFIG_OPTPROBES=y (default y if the
arch supports OPTPROBE).
Changes in v9:
- Fix a bug to optimize probe when enabling.
- Check nearby probes can be optimize/unoptimize when disarming/arming
kprobes, instead of registering/unregistering. This will help
kprobe-tracer because most of probes on it are usually disabled.
Changes in v6:
- Cleanup coding style for readability.
- Add comments around get/put_online_cpus().
Changes in v5:
- Use get_online_cpus()/put_online_cpus() for avoiding text_mutex
deadlock.
Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
Cc: systemtap <systemtap@sources.redhat.com>
Cc: DLE <dle-develop@lists.sourceforge.net>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Jim Keniston <jkenisto@us.ibm.com>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Anders Kaseorg <andersk@ksplice.com>
Cc: Tim Abbott <tabbott@ksplice.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Jason Baron <jbaron@redhat.com>
Cc: Mathieu Desnoyers <compudj@krystal.dyndns.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
LKML-Reference: <20100225133407.6725.81992.stgit@localhost6.localdomain6>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'include/linux/kprobes.h')
-rw-r--r-- | include/linux/kprobes.h | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h index 1b672f74a32f..aed1f95c582f 100644 --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h | |||
@@ -122,6 +122,11 @@ struct kprobe { | |||
122 | /* Kprobe status flags */ | 122 | /* Kprobe status flags */ |
123 | #define KPROBE_FLAG_GONE 1 /* breakpoint has already gone */ | 123 | #define KPROBE_FLAG_GONE 1 /* breakpoint has already gone */ |
124 | #define KPROBE_FLAG_DISABLED 2 /* probe is temporarily disabled */ | 124 | #define KPROBE_FLAG_DISABLED 2 /* probe is temporarily disabled */ |
125 | #define KPROBE_FLAG_OPTIMIZED 4 /* | ||
126 | * probe is really optimized. | ||
127 | * NOTE: | ||
128 | * this flag is only for optimized_kprobe. | ||
129 | */ | ||
125 | 130 | ||
126 | /* Has this kprobe gone ? */ | 131 | /* Has this kprobe gone ? */ |
127 | static inline int kprobe_gone(struct kprobe *p) | 132 | static inline int kprobe_gone(struct kprobe *p) |
@@ -134,6 +139,12 @@ static inline int kprobe_disabled(struct kprobe *p) | |||
134 | { | 139 | { |
135 | return p->flags & (KPROBE_FLAG_DISABLED | KPROBE_FLAG_GONE); | 140 | return p->flags & (KPROBE_FLAG_DISABLED | KPROBE_FLAG_GONE); |
136 | } | 141 | } |
142 | |||
143 | /* Is this kprobe really running optimized path ? */ | ||
144 | static inline int kprobe_optimized(struct kprobe *p) | ||
145 | { | ||
146 | return p->flags & KPROBE_FLAG_OPTIMIZED; | ||
147 | } | ||
137 | /* | 148 | /* |
138 | * Special probe type that uses setjmp-longjmp type tricks to resume | 149 | * Special probe type that uses setjmp-longjmp type tricks to resume |
139 | * execution at a specified entry with a matching prototype corresponding | 150 | * execution at a specified entry with a matching prototype corresponding |
@@ -249,6 +260,31 @@ extern kprobe_opcode_t *get_insn_slot(void); | |||
249 | extern void free_insn_slot(kprobe_opcode_t *slot, int dirty); | 260 | extern void free_insn_slot(kprobe_opcode_t *slot, int dirty); |
250 | extern void kprobes_inc_nmissed_count(struct kprobe *p); | 261 | extern void kprobes_inc_nmissed_count(struct kprobe *p); |
251 | 262 | ||
263 | #ifdef CONFIG_OPTPROBES | ||
264 | /* | ||
265 | * Internal structure for direct jump optimized probe | ||
266 | */ | ||
267 | struct optimized_kprobe { | ||
268 | struct kprobe kp; | ||
269 | struct list_head list; /* list for optimizing queue */ | ||
270 | struct arch_optimized_insn optinsn; | ||
271 | }; | ||
272 | |||
273 | /* Architecture dependent functions for direct jump optimization */ | ||
274 | extern int arch_prepared_optinsn(struct arch_optimized_insn *optinsn); | ||
275 | extern int arch_check_optimized_kprobe(struct optimized_kprobe *op); | ||
276 | extern int arch_prepare_optimized_kprobe(struct optimized_kprobe *op); | ||
277 | extern void arch_remove_optimized_kprobe(struct optimized_kprobe *op); | ||
278 | extern int arch_optimize_kprobe(struct optimized_kprobe *op); | ||
279 | extern void arch_unoptimize_kprobe(struct optimized_kprobe *op); | ||
280 | extern kprobe_opcode_t *get_optinsn_slot(void); | ||
281 | extern void free_optinsn_slot(kprobe_opcode_t *slot, int dirty); | ||
282 | extern int arch_within_optimized_kprobe(struct optimized_kprobe *op, | ||
283 | unsigned long addr); | ||
284 | |||
285 | extern void opt_pre_handler(struct kprobe *p, struct pt_regs *regs); | ||
286 | #endif /* CONFIG_OPTPROBES */ | ||
287 | |||
252 | /* Get the kprobe at this addr (if any) - called with preemption disabled */ | 288 | /* Get the kprobe at this addr (if any) - called with preemption disabled */ |
253 | struct kprobe *get_kprobe(void *addr); | 289 | struct kprobe *get_kprobe(void *addr); |
254 | void kretprobe_hash_lock(struct task_struct *tsk, | 290 | void kretprobe_hash_lock(struct task_struct *tsk, |