From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757268AbbGGMyr (ORCPT ); Tue, 7 Jul 2015 08:54:47 -0400 Received: from mail-wi0-f180.google.com ([209.85.212.180]:35189 "EHLO mail-wi0-f180.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754408AbbGGMyi (ORCPT ); Tue, 7 Jul 2015 08:54:38 -0400 Date: Tue, 7 Jul 2015 14:54:33 +0200 From: Anton Arapov To: Oleg Nesterov Cc: Ananth Mavinakayanahalli , David Long , Denys Vlasenko , "Frank Ch. Eigler" , Ingo Molnar , Jan Willeke , Jim Keniston , Mark Wielaard , Pratyush Anand , Srikar Dronamraju , linux-kernel@vger.kernel.org Subject: Re: [PATCH v2 05/11] uprobes: Change handle_trampoline() to find the next chain beforehand Message-ID: <20150707125433.GE5946@troglodyte.intinfra.com> References: <20150707012210.GA7466@redhat.com> <20150707012250.GA7523@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20150707012250.GA7523@redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 > Acked-by: Srikar Dronamraju Acked-by: Anton Arapov > --- > 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 >