On Tue, Jul 07, 2015 at 03:22:50AM +0200, Oleg Nesterov wrote: > No functional changes, preparation. > > Add the new helper, find_next_ret_chain(), which finds the first !chained > entry and returns its ->next. Yes, it is suboptimal. We probably want to > turn ->chained into ->start_of_this_chain pointer and avoid another loop. > But this needs the boring changes in dup_utask(), so lets do this later. > > Change the main loop in handle_trampoline() to unwind the stack until ri > is equal to the pointer returned by this new helper. > > Signed-off-by: Oleg Nesterov <o...@redhat.com> > Acked-by: Srikar Dronamraju <sri...@linux.vnet.ibm.com> Acked-by: Anton Arapov <ara...@gmail.com>
> --- > kernel/events/uprobes.c | 27 ++++++++++++++++----------- > 1 files changed, 16 insertions(+), 11 deletions(-) > > diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c > index 4c941fe..98e4d97 100644 > --- a/kernel/events/uprobes.c > +++ b/kernel/events/uprobes.c > @@ -1766,11 +1766,22 @@ handle_uretprobe_chain(struct return_instance *ri, > struct pt_regs *regs) > up_read(&uprobe->register_rwsem); > } > > +static struct return_instance *find_next_ret_chain(struct return_instance > *ri) > +{ > + bool chained; > + > + do { > + chained = ri->chained; > + ri = ri->next; /* can't be NULL if chained */ > + } while (chained); > + > + return ri; > +} > + > static void handle_trampoline(struct pt_regs *regs) > { > struct uprobe_task *utask; > - struct return_instance *ri; > - bool chained; > + struct return_instance *ri, *next; > > utask = current->utask; > if (!utask) > @@ -1780,24 +1791,18 @@ static void handle_trampoline(struct pt_regs *regs) > if (!ri) > goto sigill; > > + next = find_next_ret_chain(ri); > /* > * TODO: we should throw out return_instance's invalidated by > * longjmp(), currently we assume that the probed function always > * returns. > */ > instruction_pointer_set(regs, ri->orig_ret_vaddr); > - > - for (;;) { > + do { > handle_uretprobe_chain(ri, regs); > - > - chained = ri->chained; > ri = free_ret_instance(ri); > utask->depth--; > - > - if (!chained) > - break; > - BUG_ON(!ri); > - } > + } while (ri != next); > > utask->return_instances = ri; > return; > -- > 1.5.5.1 > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/