From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753403AbbGaN7u (ORCPT ); Fri, 31 Jul 2015 09:59:50 -0400 Received: from terminus.zytor.com ([198.137.202.10]:57365 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751553AbbGaN7r (ORCPT ); Fri, 31 Jul 2015 09:59:47 -0400 Date: Fri, 31 Jul 2015 06:59:11 -0700 From: tip-bot for Oleg Nesterov Message-ID: Cc: arapov@gmail.com, torvalds@linux-foundation.org, linux-kernel@vger.kernel.org, srikar@linux.vnet.ibm.com, oleg@redhat.com, peterz@infradead.org, mingo@kernel.org, tglx@linutronix.de, hpa@zytor.com, luto@amacapital.net, panand@redhat.com Reply-To: mingo@kernel.org, tglx@linutronix.de, panand@redhat.com, luto@amacapital.net, hpa@zytor.com, arapov@gmail.com, linux-kernel@vger.kernel.org, torvalds@linux-foundation.org, srikar@linux.vnet.ibm.com, peterz@infradead.org, oleg@redhat.com In-Reply-To: <20150721134013.GA4755@redhat.com> References: <20150721134013.GA4755@redhat.com> To: linux-tip-commits@vger.kernel.org Subject: [tip:perf/core] uprobes: Change handle_trampoline() to find the next chain beforehand Git-Commit-ID: a83cfeb92132c279b20bbc8ed3cef833b0fe417e X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: a83cfeb92132c279b20bbc8ed3cef833b0fe417e Gitweb: http://git.kernel.org/tip/a83cfeb92132c279b20bbc8ed3cef833b0fe417e Author: Oleg Nesterov AuthorDate: Tue, 21 Jul 2015 15:40:13 +0200 Committer: Ingo Molnar CommitDate: Fri, 31 Jul 2015 10:38:04 +0200 uprobes: Change handle_trampoline() to find the next chain beforehand 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. Tested-by: Pratyush Anand Signed-off-by: Oleg Nesterov Acked-by: Srikar Dronamraju Acked-by: Anton Arapov Cc: Andy Lutomirski Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/20150721134013.GA4755@redhat.com Signed-off-by: Ingo Molnar --- kernel/events/uprobes.c | 27 ++++++++++++++++----------- 1 file 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;