* [PATCH 3/3] kprobes: kretprobes simplifcations
@ 2007-03-31 13:59 Christoph Hellwig
2007-04-02 4:39 ` Ananth N Mavinakayanahalli
0 siblings, 1 reply; 2+ messages in thread
From: Christoph Hellwig @ 2007-03-31 13:59 UTC (permalink / raw)
To: akpm; +Cc: linux-kernel
- consolidate duplicate code in all arch_prepare_kretprobe instances
into common code
- replace various odd helpers that use hlist_for_each_entry to get
the first elemenet of a list with either a hlist_for_each_entry_save
or an opencoded access to the first element in the caller
- inline add_rp_inst into it's only remaining caller
- use kretprobe_inst_table_head instead of opencoding it
Signed-off-by: Christoph Hellwig <hch@lst.de>
Index: linux-2.6/arch/i386/kernel/kprobes.c
===================================================================
--- linux-2.6.orig/arch/i386/kernel/kprobes.c 2007-03-31 14:31:24.000000000 +0200
+++ linux-2.6/arch/i386/kernel/kprobes.c 2007-03-31 14:47:40.000000000 +0200
@@ -226,24 +226,15 @@ static void __kprobes prepare_singlestep
}
/* Called with kretprobe_lock held */
-void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
+void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
unsigned long *sara = (unsigned long *)®s->esp;
- struct kretprobe_instance *ri;
+ ri->ret_addr = (kprobe_opcode_t *) *sara;
- if ((ri = get_free_rp_inst(rp)) != NULL) {
- ri->rp = rp;
- ri->task = current;
- ri->ret_addr = (kprobe_opcode_t *) *sara;
-
- /* Replace the return addr with trampoline addr */
- *sara = (unsigned long) &kretprobe_trampoline;
- add_rp_inst(ri);
- } else {
- rp->nmissed++;
- }
+ /* Replace the return addr with trampoline addr */
+ *sara = (unsigned long) &kretprobe_trampoline;
}
/*
Index: linux-2.6/arch/ia64/kernel/kprobes.c
===================================================================
--- linux-2.6.orig/arch/ia64/kernel/kprobes.c 2007-03-31 14:31:24.000000000 +0200
+++ linux-2.6/arch/ia64/kernel/kprobes.c 2007-03-31 14:35:39.000000000 +0200
@@ -464,23 +464,13 @@ int __kprobes trampoline_probe_handler(s
}
/* Called with kretprobe_lock held */
-void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
+void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
- struct kretprobe_instance *ri;
+ ri->ret_addr = (kprobe_opcode_t *)regs->b0;
- if ((ri = get_free_rp_inst(rp)) != NULL) {
- ri->rp = rp;
- ri->task = current;
- ri->ret_addr = (kprobe_opcode_t *)regs->b0;
-
- /* Replace the return addr with trampoline addr */
- regs->b0 = ((struct fnptr *)kretprobe_trampoline)->ip;
-
- add_rp_inst(ri);
- } else {
- rp->nmissed++;
- }
+ /* Replace the return addr with trampoline addr */
+ regs->b0 = ((struct fnptr *)kretprobe_trampoline)->ip;
}
int __kprobes arch_prepare_kprobe(struct kprobe *p)
Index: linux-2.6/arch/powerpc/kernel/kprobes.c
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/kprobes.c 2007-03-31 14:31:24.000000000 +0200
+++ linux-2.6/arch/powerpc/kernel/kprobes.c 2007-03-31 14:35:21.000000000 +0200
@@ -124,22 +124,13 @@ static void __kprobes set_current_kprobe
}
/* Called with kretprobe_lock held */
-void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
+void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
- struct kretprobe_instance *ri;
+ ri->ret_addr = (kprobe_opcode_t *)regs->link;
- if ((ri = get_free_rp_inst(rp)) != NULL) {
- ri->rp = rp;
- ri->task = current;
- ri->ret_addr = (kprobe_opcode_t *)regs->link;
-
- /* Replace the return addr with trampoline addr */
- regs->link = (unsigned long)kretprobe_trampoline;
- add_rp_inst(ri);
- } else {
- rp->nmissed++;
- }
+ /* Replace the return addr with trampoline addr */
+ regs->link = (unsigned long)kretprobe_trampoline;
}
static int __kprobes kprobe_handler(struct pt_regs *regs)
Index: linux-2.6/arch/s390/kernel/kprobes.c
===================================================================
--- linux-2.6.orig/arch/s390/kernel/kprobes.c 2007-03-31 14:31:24.000000000 +0200
+++ linux-2.6/arch/s390/kernel/kprobes.c 2007-03-31 14:35:09.000000000 +0200
@@ -271,23 +271,13 @@ static void __kprobes set_current_kprobe
}
/* Called with kretprobe_lock held */
-void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
+void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
- struct kretprobe_instance *ri;
+ ri->ret_addr = (kprobe_opcode_t *) regs->gprs[14];
- if ((ri = get_free_rp_inst(rp)) != NULL) {
- ri->rp = rp;
- ri->task = current;
- ri->ret_addr = (kprobe_opcode_t *) regs->gprs[14];
-
- /* Replace the return addr with trampoline addr */
- regs->gprs[14] = (unsigned long)&kretprobe_trampoline;
-
- add_rp_inst(ri);
- } else {
- rp->nmissed++;
- }
+ /* Replace the return addr with trampoline addr */
+ regs->gprs[14] = (unsigned long)&kretprobe_trampoline;
}
static int __kprobes kprobe_handler(struct pt_regs *regs)
Index: linux-2.6/arch/x86_64/kernel/kprobes.c
===================================================================
--- linux-2.6.orig/arch/x86_64/kernel/kprobes.c 2007-03-31 14:31:24.000000000 +0200
+++ linux-2.6/arch/x86_64/kernel/kprobes.c 2007-03-31 14:34:46.000000000 +0200
@@ -266,23 +266,14 @@ static void __kprobes prepare_singlestep
}
/* Called with kretprobe_lock held */
-void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
+void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
unsigned long *sara = (unsigned long *)regs->rsp;
- struct kretprobe_instance *ri;
- if ((ri = get_free_rp_inst(rp)) != NULL) {
- ri->rp = rp;
- ri->task = current;
- ri->ret_addr = (kprobe_opcode_t *) *sara;
-
- /* Replace the return addr with trampoline addr */
- *sara = (unsigned long) &kretprobe_trampoline;
- add_rp_inst(ri);
- } else {
- rp->nmissed++;
- }
+ ri->ret_addr = (kprobe_opcode_t *) *sara;
+ /* Replace the return addr with trampoline addr */
+ *sara = (unsigned long) &kretprobe_trampoline;
}
int __kprobes kprobe_handler(struct pt_regs *regs)
Index: linux-2.6/include/linux/kprobes.h
===================================================================
--- linux-2.6.orig/include/linux/kprobes.h 2007-03-31 14:36:00.000000000 +0200
+++ linux-2.6/include/linux/kprobes.h 2007-03-31 14:41:13.000000000 +0200
@@ -123,7 +123,8 @@ DECLARE_PER_CPU(struct kprobe *, current
DECLARE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
#ifdef ARCH_SUPPORTS_KRETPROBES
-extern void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs);
+extern void arch_prepare_kretprobe(struct kretprobe_instance *ri,
+ struct pt_regs *regs);
#else /* ARCH_SUPPORTS_KRETPROBES */
static inline void arch_prepare_kretprobe(struct kretprobe *rp,
struct pt_regs *regs)
@@ -199,8 +200,6 @@ void jprobe_return(void);
int register_kretprobe(struct kretprobe *rp);
void unregister_kretprobe(struct kretprobe *rp);
-struct kretprobe_instance *get_free_rp_inst(struct kretprobe *rp);
-void add_rp_inst(struct kretprobe_instance *ri);
void kprobe_flush_task(struct task_struct *tk);
void recycle_rp_inst(struct kretprobe_instance *ri, struct hlist_head *head);
#else /* CONFIG_KPROBES */
Index: linux-2.6/kernel/kprobes.c
===================================================================
--- linux-2.6.orig/kernel/kprobes.c 2007-03-31 14:26:22.000000000 +0200
+++ linux-2.6/kernel/kprobes.c 2007-03-31 14:46:54.000000000 +0200
@@ -357,46 +357,6 @@ void __kprobes kprobes_inc_nmissed_count
}
/* Called with kretprobe_lock held */
-struct kretprobe_instance __kprobes *get_free_rp_inst(struct kretprobe *rp)
-{
- struct hlist_node *node;
- struct kretprobe_instance *ri;
- hlist_for_each_entry(ri, node, &rp->free_instances, uflist)
- return ri;
- return NULL;
-}
-
-/* Called with kretprobe_lock held */
-static struct kretprobe_instance __kprobes *get_used_rp_inst(struct kretprobe
- *rp)
-{
- struct hlist_node *node;
- struct kretprobe_instance *ri;
- hlist_for_each_entry(ri, node, &rp->used_instances, uflist)
- return ri;
- return NULL;
-}
-
-/* Called with kretprobe_lock held */
-void __kprobes add_rp_inst(struct kretprobe_instance *ri)
-{
- /*
- * Remove rp inst off the free list -
- * Add it back when probed function returns
- */
- hlist_del(&ri->uflist);
-
- /* Add rp inst onto table */
- INIT_HLIST_NODE(&ri->hlist);
- hlist_add_head(&ri->hlist,
- &kretprobe_inst_table[hash_ptr(ri->task, KPROBE_HASH_BITS)]);
-
- /* Also add this rp inst to the used list. */
- INIT_HLIST_NODE(&ri->uflist);
- hlist_add_head(&ri->uflist, &ri->rp->used_instances);
-}
-
-/* Called with kretprobe_lock held */
void __kprobes recycle_rp_inst(struct kretprobe_instance *ri,
struct hlist_head *head)
{
@@ -449,7 +409,9 @@ void __kprobes kprobe_flush_task(struct
static inline void free_rp_inst(struct kretprobe *rp)
{
struct kretprobe_instance *ri;
- while ((ri = get_free_rp_inst(rp)) != NULL) {
+ struct hlist_node *pos, *next;
+
+ hlist_for_each_entry_safe(ri, pos, next, &rp->free_instances, uflist) {
hlist_del(&ri->uflist);
kfree(ri);
}
@@ -731,7 +693,21 @@ static int __kprobes pre_handler_kretpro
/*TODO: consider to only swap the RA after the last pre_handler fired */
spin_lock_irqsave(&kretprobe_lock, flags);
- arch_prepare_kretprobe(rp, regs);
+ if (!hlist_empty(&rp->free_instances)) {
+ struct kretprobe_instance *ri;
+
+ ri = hlist_entry(rp->free_instances.first,
+ struct kretprobe_instance, uflist);
+ ri->rp = rp;
+ ri->task = current;
+ arch_prepare_kretprobe(ri, regs);
+
+ /* XXX(hch): why is there no hlist_move_head? */
+ hlist_del(&ri->uflist);
+ hlist_add_head(&ri->uflist, &ri->rp->used_instances);
+ hlist_add_head(&ri->hlist, kretprobe_inst_table_head(ri->task));
+ } else
+ rp->nmissed++;
spin_unlock_irqrestore(&kretprobe_lock, flags);
return 0;
}
@@ -794,11 +770,13 @@ void __kprobes unregister_kretprobe(stru
{
unsigned long flags;
struct kretprobe_instance *ri;
+ struct hlist_node *pos, *next;
unregister_kprobe(&rp->kp);
+
/* No race here */
spin_lock_irqsave(&kretprobe_lock, flags);
- while ((ri = get_used_rp_inst(rp)) != NULL) {
+ hlist_for_each_entry_safe(ri, pos, next, &rp->used_instances, uflist) {
ri->rp = NULL;
hlist_del(&ri->uflist);
}
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: [PATCH 3/3] kprobes: kretprobes simplifcations
2007-03-31 13:59 [PATCH 3/3] kprobes: kretprobes simplifcations Christoph Hellwig
@ 2007-04-02 4:39 ` Ananth N Mavinakayanahalli
0 siblings, 0 replies; 2+ messages in thread
From: Ananth N Mavinakayanahalli @ 2007-04-02 4:39 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: akpm, linux-kernel
On Sat, Mar 31, 2007 at 03:59:29PM +0200, Christoph Hellwig wrote:
> - consolidate duplicate code in all arch_prepare_kretprobe instances
> into common code
> - replace various odd helpers that use hlist_for_each_entry to get
> the first elemenet of a list with either a hlist_for_each_entry_save
> or an opencoded access to the first element in the caller
> - inline add_rp_inst into it's only remaining caller
> - use kretprobe_inst_table_head instead of opencoding it
This certainly looks better... Thanks Christoph
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
>
> Index: linux-2.6/arch/i386/kernel/kprobes.c
> ===================================================================
> --- linux-2.6.orig/arch/i386/kernel/kprobes.c 2007-03-31 14:31:24.000000000 +0200
> +++ linux-2.6/arch/i386/kernel/kprobes.c 2007-03-31 14:47:40.000000000 +0200
> @@ -226,24 +226,15 @@ static void __kprobes prepare_singlestep
> }
>
> /* Called with kretprobe_lock held */
> -void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
> +void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
> struct pt_regs *regs)
> {
> unsigned long *sara = (unsigned long *)®s->esp;
>
> - struct kretprobe_instance *ri;
> + ri->ret_addr = (kprobe_opcode_t *) *sara;
>
> - if ((ri = get_free_rp_inst(rp)) != NULL) {
> - ri->rp = rp;
> - ri->task = current;
> - ri->ret_addr = (kprobe_opcode_t *) *sara;
> -
> - /* Replace the return addr with trampoline addr */
> - *sara = (unsigned long) &kretprobe_trampoline;
> - add_rp_inst(ri);
> - } else {
> - rp->nmissed++;
> - }
> + /* Replace the return addr with trampoline addr */
> + *sara = (unsigned long) &kretprobe_trampoline;
> }
>
> /*
> Index: linux-2.6/arch/ia64/kernel/kprobes.c
> ===================================================================
> --- linux-2.6.orig/arch/ia64/kernel/kprobes.c 2007-03-31 14:31:24.000000000 +0200
> +++ linux-2.6/arch/ia64/kernel/kprobes.c 2007-03-31 14:35:39.000000000 +0200
> @@ -464,23 +464,13 @@ int __kprobes trampoline_probe_handler(s
> }
>
> /* Called with kretprobe_lock held */
> -void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
> +void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
> struct pt_regs *regs)
> {
> - struct kretprobe_instance *ri;
> + ri->ret_addr = (kprobe_opcode_t *)regs->b0;
>
> - if ((ri = get_free_rp_inst(rp)) != NULL) {
> - ri->rp = rp;
> - ri->task = current;
> - ri->ret_addr = (kprobe_opcode_t *)regs->b0;
> -
> - /* Replace the return addr with trampoline addr */
> - regs->b0 = ((struct fnptr *)kretprobe_trampoline)->ip;
> -
> - add_rp_inst(ri);
> - } else {
> - rp->nmissed++;
> - }
> + /* Replace the return addr with trampoline addr */
> + regs->b0 = ((struct fnptr *)kretprobe_trampoline)->ip;
> }
>
> int __kprobes arch_prepare_kprobe(struct kprobe *p)
> Index: linux-2.6/arch/powerpc/kernel/kprobes.c
> ===================================================================
> --- linux-2.6.orig/arch/powerpc/kernel/kprobes.c 2007-03-31 14:31:24.000000000 +0200
> +++ linux-2.6/arch/powerpc/kernel/kprobes.c 2007-03-31 14:35:21.000000000 +0200
> @@ -124,22 +124,13 @@ static void __kprobes set_current_kprobe
> }
>
> /* Called with kretprobe_lock held */
> -void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
> +void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
> struct pt_regs *regs)
> {
> - struct kretprobe_instance *ri;
> + ri->ret_addr = (kprobe_opcode_t *)regs->link;
>
> - if ((ri = get_free_rp_inst(rp)) != NULL) {
> - ri->rp = rp;
> - ri->task = current;
> - ri->ret_addr = (kprobe_opcode_t *)regs->link;
> -
> - /* Replace the return addr with trampoline addr */
> - regs->link = (unsigned long)kretprobe_trampoline;
> - add_rp_inst(ri);
> - } else {
> - rp->nmissed++;
> - }
> + /* Replace the return addr with trampoline addr */
> + regs->link = (unsigned long)kretprobe_trampoline;
> }
>
> static int __kprobes kprobe_handler(struct pt_regs *regs)
> Index: linux-2.6/arch/s390/kernel/kprobes.c
> ===================================================================
> --- linux-2.6.orig/arch/s390/kernel/kprobes.c 2007-03-31 14:31:24.000000000 +0200
> +++ linux-2.6/arch/s390/kernel/kprobes.c 2007-03-31 14:35:09.000000000 +0200
> @@ -271,23 +271,13 @@ static void __kprobes set_current_kprobe
> }
>
> /* Called with kretprobe_lock held */
> -void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
> +void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
> struct pt_regs *regs)
> {
> - struct kretprobe_instance *ri;
> + ri->ret_addr = (kprobe_opcode_t *) regs->gprs[14];
>
> - if ((ri = get_free_rp_inst(rp)) != NULL) {
> - ri->rp = rp;
> - ri->task = current;
> - ri->ret_addr = (kprobe_opcode_t *) regs->gprs[14];
> -
> - /* Replace the return addr with trampoline addr */
> - regs->gprs[14] = (unsigned long)&kretprobe_trampoline;
> -
> - add_rp_inst(ri);
> - } else {
> - rp->nmissed++;
> - }
> + /* Replace the return addr with trampoline addr */
> + regs->gprs[14] = (unsigned long)&kretprobe_trampoline;
> }
>
> static int __kprobes kprobe_handler(struct pt_regs *regs)
> Index: linux-2.6/arch/x86_64/kernel/kprobes.c
> ===================================================================
> --- linux-2.6.orig/arch/x86_64/kernel/kprobes.c 2007-03-31 14:31:24.000000000 +0200
> +++ linux-2.6/arch/x86_64/kernel/kprobes.c 2007-03-31 14:34:46.000000000 +0200
> @@ -266,23 +266,14 @@ static void __kprobes prepare_singlestep
> }
>
> /* Called with kretprobe_lock held */
> -void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
> +void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
> struct pt_regs *regs)
> {
> unsigned long *sara = (unsigned long *)regs->rsp;
> - struct kretprobe_instance *ri;
>
> - if ((ri = get_free_rp_inst(rp)) != NULL) {
> - ri->rp = rp;
> - ri->task = current;
> - ri->ret_addr = (kprobe_opcode_t *) *sara;
> -
> - /* Replace the return addr with trampoline addr */
> - *sara = (unsigned long) &kretprobe_trampoline;
> - add_rp_inst(ri);
> - } else {
> - rp->nmissed++;
> - }
> + ri->ret_addr = (kprobe_opcode_t *) *sara;
> + /* Replace the return addr with trampoline addr */
> + *sara = (unsigned long) &kretprobe_trampoline;
> }
>
> int __kprobes kprobe_handler(struct pt_regs *regs)
> Index: linux-2.6/include/linux/kprobes.h
> ===================================================================
> --- linux-2.6.orig/include/linux/kprobes.h 2007-03-31 14:36:00.000000000 +0200
> +++ linux-2.6/include/linux/kprobes.h 2007-03-31 14:41:13.000000000 +0200
> @@ -123,7 +123,8 @@ DECLARE_PER_CPU(struct kprobe *, current
> DECLARE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
>
> #ifdef ARCH_SUPPORTS_KRETPROBES
> -extern void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs);
> +extern void arch_prepare_kretprobe(struct kretprobe_instance *ri,
> + struct pt_regs *regs);
> #else /* ARCH_SUPPORTS_KRETPROBES */
> static inline void arch_prepare_kretprobe(struct kretprobe *rp,
> struct pt_regs *regs)
> @@ -199,8 +200,6 @@ void jprobe_return(void);
> int register_kretprobe(struct kretprobe *rp);
> void unregister_kretprobe(struct kretprobe *rp);
>
> -struct kretprobe_instance *get_free_rp_inst(struct kretprobe *rp);
> -void add_rp_inst(struct kretprobe_instance *ri);
> void kprobe_flush_task(struct task_struct *tk);
> void recycle_rp_inst(struct kretprobe_instance *ri, struct hlist_head *head);
> #else /* CONFIG_KPROBES */
> Index: linux-2.6/kernel/kprobes.c
> ===================================================================
> --- linux-2.6.orig/kernel/kprobes.c 2007-03-31 14:26:22.000000000 +0200
> +++ linux-2.6/kernel/kprobes.c 2007-03-31 14:46:54.000000000 +0200
> @@ -357,46 +357,6 @@ void __kprobes kprobes_inc_nmissed_count
> }
>
> /* Called with kretprobe_lock held */
> -struct kretprobe_instance __kprobes *get_free_rp_inst(struct kretprobe *rp)
> -{
> - struct hlist_node *node;
> - struct kretprobe_instance *ri;
> - hlist_for_each_entry(ri, node, &rp->free_instances, uflist)
> - return ri;
> - return NULL;
> -}
> -
> -/* Called with kretprobe_lock held */
> -static struct kretprobe_instance __kprobes *get_used_rp_inst(struct kretprobe
> - *rp)
> -{
> - struct hlist_node *node;
> - struct kretprobe_instance *ri;
> - hlist_for_each_entry(ri, node, &rp->used_instances, uflist)
> - return ri;
> - return NULL;
> -}
> -
> -/* Called with kretprobe_lock held */
> -void __kprobes add_rp_inst(struct kretprobe_instance *ri)
> -{
> - /*
> - * Remove rp inst off the free list -
> - * Add it back when probed function returns
> - */
> - hlist_del(&ri->uflist);
> -
> - /* Add rp inst onto table */
> - INIT_HLIST_NODE(&ri->hlist);
> - hlist_add_head(&ri->hlist,
> - &kretprobe_inst_table[hash_ptr(ri->task, KPROBE_HASH_BITS)]);
> -
> - /* Also add this rp inst to the used list. */
> - INIT_HLIST_NODE(&ri->uflist);
> - hlist_add_head(&ri->uflist, &ri->rp->used_instances);
> -}
> -
> -/* Called with kretprobe_lock held */
> void __kprobes recycle_rp_inst(struct kretprobe_instance *ri,
> struct hlist_head *head)
> {
> @@ -449,7 +409,9 @@ void __kprobes kprobe_flush_task(struct
> static inline void free_rp_inst(struct kretprobe *rp)
> {
> struct kretprobe_instance *ri;
> - while ((ri = get_free_rp_inst(rp)) != NULL) {
> + struct hlist_node *pos, *next;
> +
> + hlist_for_each_entry_safe(ri, pos, next, &rp->free_instances, uflist) {
> hlist_del(&ri->uflist);
> kfree(ri);
> }
> @@ -731,7 +693,21 @@ static int __kprobes pre_handler_kretpro
>
> /*TODO: consider to only swap the RA after the last pre_handler fired */
> spin_lock_irqsave(&kretprobe_lock, flags);
> - arch_prepare_kretprobe(rp, regs);
> + if (!hlist_empty(&rp->free_instances)) {
> + struct kretprobe_instance *ri;
> +
> + ri = hlist_entry(rp->free_instances.first,
> + struct kretprobe_instance, uflist);
> + ri->rp = rp;
> + ri->task = current;
> + arch_prepare_kretprobe(ri, regs);
> +
> + /* XXX(hch): why is there no hlist_move_head? */
> + hlist_del(&ri->uflist);
> + hlist_add_head(&ri->uflist, &ri->rp->used_instances);
> + hlist_add_head(&ri->hlist, kretprobe_inst_table_head(ri->task));
> + } else
> + rp->nmissed++;
> spin_unlock_irqrestore(&kretprobe_lock, flags);
> return 0;
> }
> @@ -794,11 +770,13 @@ void __kprobes unregister_kretprobe(stru
> {
> unsigned long flags;
> struct kretprobe_instance *ri;
> + struct hlist_node *pos, *next;
>
> unregister_kprobe(&rp->kp);
> +
> /* No race here */
> spin_lock_irqsave(&kretprobe_lock, flags);
> - while ((ri = get_used_rp_inst(rp)) != NULL) {
> + hlist_for_each_entry_safe(ri, pos, next, &rp->used_instances, uflist) {
> ri->rp = NULL;
> hlist_del(&ri->uflist);
> }
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2007-04-02 4:35 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-03-31 13:59 [PATCH 3/3] kprobes: kretprobes simplifcations Christoph Hellwig
2007-04-02 4:39 ` Ananth N Mavinakayanahalli
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox