lkml.org 
[lkml]   [2015]   [Jul]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH v2 05/11] uprobes: Change handle_trampoline() to find the next chain beforehand
    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 <oleg@redhat.com>
    > Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
    Acked-by: Anton Arapov <arapov@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
    >


    \
     
     \ /
      Last update: 2015-07-07 15:21    [W:8.056 / U:0.052 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site