Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp2856375pxb; Tue, 9 Mar 2021 12:41:03 -0800 (PST) X-Google-Smtp-Source: ABdhPJwdq4ITZdicRE5kDDLMf3xr2VSc9ANXaDPchLMUxCe9dbTl+9Shl51kuC6Bh1RcH19M7X1x X-Received: by 2002:aa7:d347:: with SMTP id m7mr445936edr.260.1615322463442; Tue, 09 Mar 2021 12:41:03 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1615322463; cv=none; d=google.com; s=arc-20160816; b=fOdi0jdbdsNR/vdxga86GO/c0cTVjcXQm9uYq+M3adO/BeF30WQMnoo+X1fDwuky/k KFnSBivl1mxor35uJq4yLuR08Cy0vUq1E88KmG+8dM2eHBcbs/8bP2OCPeJCUFbfboZ1 qSyxa77eoIswomsoyZ8Nx+t4Xx4129OK1/gIYihQeFTu4Zl0wxAmpuwY74TxY9iC8zge 68A0+KmkpcMzHAYR+/gD4cM3DGfTQyOmHLPc3+vstlS+w1mUGdGIOZRRVFTYe+hO+J6P +SqOzX9KGgeV4HmmD/wvtLHZB0Hr7PADG/bRqRzc2Q2FM7s7G72AMwN3dUyUJOFOwPx4 UXsQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from; bh=LNPOMXgY0Zl+f4+WT7vh2VexLKa6wvoTR8qUw695xcY=; b=0XdWrzMiCzTVruSn4DFv7Gic4iSNUyYny1zeR/M2tLKjULuesjIczTrX5AVvMXVzEN m8Q38goUT2WY3F05uFd6vKAk/wQk0NCV1N7iBeDDlMQOnxK9gwJDXjpCo9ajeKYBCAGw JsMhpj+Pdoq/FYkpD7cDBeN6pSSC0IBXgOGZcpxjYxW8dpghBTeFTiTowo8+IjY7EkKu vUBzRIAk7tKtfQxBytk+6J1kzPplnyr3FRLhFLI+v2S51KvI5atWaFODssu530HO44hu R6xVwsFzBapy4kF7WlN6gWJYXBolzSMvXd1BhsrABS4/DZjHXchyt+DZgN6DroCQEyey OlLQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id s10si10577180edj.416.2021.03.09.12.40.39; Tue, 09 Mar 2021 12:41:03 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231657AbhCIUjn (ORCPT + 99 others); Tue, 9 Mar 2021 15:39:43 -0500 Received: from mx1.riseup.net ([198.252.153.129]:42002 "EHLO mx1.riseup.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231808AbhCIUjk (ORCPT ); Tue, 9 Mar 2021 15:39:40 -0500 Received: from fews1.riseup.net (fews1-pn.riseup.net [10.0.1.83]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (Client CN "*.riseup.net", Issuer "Sectigo RSA Domain Validation Secure Server CA" (not verified)) by mx1.riseup.net (Postfix) with ESMTPS id 4Dw6Ws4dPBzDsZK; Tue, 9 Mar 2021 12:39:37 -0800 (PST) X-Riseup-User-ID: AE255FD18F480507363915D2831290FBD05F26D3B88E602C6B93B21A0BF6B213 Received: from [127.0.0.1] (localhost [127.0.0.1]) by fews1.riseup.net (Postfix) with ESMTPSA id 4Dw6Wr570mz5vNG; Tue, 9 Mar 2021 12:39:36 -0800 (PST) From: Jim Newsome To: Andrew Morton Cc: Oleg Nesterov , "Eric W . Biederman" , Christian Brauner , linux-kernel@vger.kernel.org, Jim Newsome Subject: [PATCH v3] do_wait: make PIDTYPE_PID case O(1) instead of O(n) Date: Tue, 9 Mar 2021 14:39:19 -0600 Message-Id: <20210309203919.15920-1-jnewsome@torproject.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org do_wait is an internal function used to implement waitpid, waitid, wait4, etc. To handle the general case, it does an O(n) linear scan of the thread group's children and tracees. This patch adds a special-case when waiting on a pid to skip these scans and instead do an O(1) lookup. This improves performance when waiting on a pid from a thread group with many children and/or tracees. Signed-off-by: James Newsome --- kernel/exit.c | 53 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/kernel/exit.c b/kernel/exit.c index 04029e35e69a..c2438d4ba262 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -1439,9 +1439,34 @@ void __wake_up_parent(struct task_struct *p, struct task_struct *parent) TASK_INTERRUPTIBLE, p); } +// Optimization for waiting on PIDTYPE_PID. No need to iterate through child +// and tracee lists to find the target task. +static int do_wait_pid(struct wait_opts *wo) +{ + struct task_struct *target = pid_task(wo->wo_pid, PIDTYPE_PID); + int retval; + + if (!target) + return 0; + if (current == target->real_parent || + (!(wo->wo_flags & __WNOTHREAD) && + same_thread_group(current, target->real_parent))) { + retval = wait_consider_task(wo, /* ptrace= */ 0, target); + if (retval) + return retval; + } + if (target->ptrace && (current == target->parent || + (!(wo->wo_flags & __WNOTHREAD) && + same_thread_group(current, target->parent)))) { + retval = wait_consider_task(wo, /* ptrace= */ 1, target); + if (retval) + return retval; + } + return 0; +} + static long do_wait(struct wait_opts *wo) { - struct task_struct *tsk; int retval; trace_sched_process_wait(wo->wo_pid); @@ -1463,19 +1488,27 @@ static long do_wait(struct wait_opts *wo) set_current_state(TASK_INTERRUPTIBLE); read_lock(&tasklist_lock); - tsk = current; - do { - retval = do_wait_thread(wo, tsk); - if (retval) - goto end; - retval = ptrace_do_wait(wo, tsk); + if (wo->wo_type == PIDTYPE_PID) { + retval = do_wait_pid(wo); if (retval) goto end; + } else { + struct task_struct *tsk = current; - if (wo->wo_flags & __WNOTHREAD) - break; - } while_each_thread(current, tsk); + do { + retval = do_wait_thread(wo, tsk); + if (retval) + goto end; + + retval = ptrace_do_wait(wo, tsk); + if (retval) + goto end; + + if (wo->wo_flags & __WNOTHREAD) + break; + } while_each_thread(current, tsk); + } read_unlock(&tasklist_lock); notask: -- 2.30.1