From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751515AbdFFTQE (ORCPT ); Tue, 6 Jun 2017 15:16:04 -0400 Received: from out03.mta.xmission.com ([166.70.13.233]:58118 "EHLO out03.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751950AbdFFTOl (ORCPT ); Tue, 6 Jun 2017 15:14:41 -0400 From: "Eric W. Biederman" To: linux-kernel@vger.kernel.org Cc: linux-api@vger.kernel.org, Linus Torvalds , Oleg Nesterov , Ingo Molnar , Thomas Gleixner , Kees Cook , Roland McGrath , Al Viro , David Howells , "Michael Kerrisk (man-pages)" , "Eric W. Biederman" Date: Tue, 6 Jun 2017 14:03:33 -0500 Message-Id: <20170606190338.28347-21-ebiederm@xmission.com> X-Mailer: git-send-email 2.10.1 In-Reply-To: <20170606190338.28347-1-ebiederm@xmission.com> References: <877f0pym71.fsf@xmission.com> <20170606190338.28347-1-ebiederm@xmission.com> X-XM-SPF: eid=1dIJvM-0006wd-Gj;;;mid=<20170606190338.28347-21-ebiederm@xmission.com>;;;hst=in02.mta.xmission.com;;;ip=97.121.81.159;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX1+4L9D82sWnhW1iGiWtHDPAcOFvbkwbuio= X-SA-Exim-Connect-IP: 97.121.81.159 X-SA-Exim-Mail-From: ebiederm@xmission.com X-Spam-Report: * -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP * 1.5 XMNoVowels Alpha-numberic number with no vowels * 0.0 TVD_RCVD_IP Message was received from an IP address * 0.8 BAYES_50 BODY: Bayes spam probability is 40 to 60% * [score: 0.5000] * -0.0 DCC_CHECK_NEGATIVE Not listed in DCC * [sa02 1397; Body=1 Fuz1=1 Fuz2=1] X-Spam-DCC: XMission; sa02 1397; Body=1 Fuz1=1 Fuz2=1 X-Spam-Combo: *;linux-kernel@vger.kernel.org X-Spam-Relay-Country: X-Spam-Timing: total 5558 ms - load_scoreonly_sql: 0.06 (0.0%), signal_user_changed: 2.9 (0.1%), b_tie_ro: 1.93 (0.0%), parse: 1.28 (0.0%), extract_message_metadata: 25 (0.5%), get_uri_detail_list: 2.5 (0.0%), tests_pri_-1000: 11 (0.2%), tests_pri_-950: 2.1 (0.0%), tests_pri_-900: 1.73 (0.0%), tests_pri_-400: 28 (0.5%), check_bayes: 26 (0.5%), b_tokenize: 11 (0.2%), b_tok_get_all: 7 (0.1%), b_comp_prob: 3.5 (0.1%), b_tok_touch_all: 1.85 (0.0%), b_finish: 0.80 (0.0%), tests_pri_0: 406 (7.3%), check_dkim_signature: 0.88 (0.0%), check_dkim_adsp: 4.6 (0.1%), tests_pri_500: 5074 (91.3%), poll_dns_idle: 5065 (91.1%), rewrite_mail: 0.00 (0.0%) Subject: [PATCH 21/26] wait: Optmize waitpid X-Spam-Flag: No X-SA-Exim-Version: 4.2.1 (built Thu, 05 May 2016 13:38:54 -0600) X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Now that which list a task is found on does not matter there is no reason to walk the child lists for waitpid when task_pid can directly find the child. Add a new helper do_wait_pid that finds the target task via pid_task and verifies it is on one of the lists for the thread we are reaping. This is more efficient in two ways. It skips the list traversal so uninteresting tasks don't slow things down. It guarantees a task will only be visited once if p->parent == p->real_parent. Except for the increase in efficiency this results in no user visible behavioral differences. Signed-off-by: "Eric W. Biederman" --- kernel/exit.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/kernel/exit.c b/kernel/exit.c index c783d5fb5ab3..2f01b75e3b2e 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -1438,6 +1438,18 @@ static int ptrace_do_wait(struct wait_opts *wo, struct task_struct *tsk) return 0; } +static int do_wait_pid(struct wait_opts *wo, struct task_struct *tsk) +{ + struct task_struct *p = pid_task(wo->wo_pid, wo->wo_type); + + /* Not on one of this tasks child lists? */ + if ((tsk != p->parent) && + ((tsk != p->real_parent) || !thread_group_leader(p))) + return 0; + + return wait_consider_task(wo, p); +} + static int child_wait_callback(wait_queue_t *wait, unsigned mode, int sync, void *key) { @@ -1486,11 +1498,15 @@ static long do_wait(struct wait_opts *wo) read_lock(&tasklist_lock); tsk = current; do { - retval = do_wait_thread(wo, tsk); - if (retval) - goto end; + if (wo->wo_type == PIDTYPE_PID) { + retval = do_wait_pid(wo, tsk); + } else { + retval = do_wait_thread(wo, tsk); + if (retval) + goto end; - retval = ptrace_do_wait(wo, tsk); + retval = ptrace_do_wait(wo, tsk); + } if (retval) goto end; -- 2.10.1