Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp2679994pxb; Tue, 9 Mar 2021 08:20:31 -0800 (PST) X-Google-Smtp-Source: ABdhPJzgS1SM2lleNLgrCHm+rpV9HYj6X0ss5qJHDffxNW7wm5bZR99DHQvoecrzmQ0f0WPY3tD2 X-Received: by 2002:a17:906:543:: with SMTP id k3mr21033247eja.139.1615306831449; Tue, 09 Mar 2021 08:20:31 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1615306831; cv=none; d=google.com; s=arc-20160816; b=TJXM1QAgtkQeNidySHh/+N1Pzra3s6pxVEMYQoMBFHCp0WUfaHkFaKE8+9zlKiA+Wx Bpd1+9SzTfETF49fqKSwW+qSC76Do+WjrSkY9TOUvPU4mW69JwauAlxi940vaGmFsehT PnHcb7BF5Ph31DK0vIlV8O2AdCf8MYl1MRltxEZzPd2qjkKdG2+loYQAuwYl/U9gRDgc TQpsqBDKp+ZZwoa/NP/DJ1KEwBzr8bqnzbSsCWxJ/LyuG1F1YlIND31vDfHs628DQvYx MTlWKh1uS36fin+v+qkpFD8mf0fLNHIALswzLayyb7FXs+P+1ij0GvOqC82KY2wDnxuM Pf/A== 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=z907BfHpIuNxIWjMIigeSQ8vw+XvCizeqqBUtSMoZhA=; b=eBP1unRJ6IFdTR/0FaQUG13Fys8e4AULAORLGsqEvoile1kk/eO7QIQC3pHpPgeVX/ SOCo65kQaN8rRBtDFsl2+NmvHCGlp2HI983tkVUKe9rfN9MwZK5l39TxqwgL4YiyRdJs Az5h+nQZFkBfAT8om/3yqo2J1YrvgwIkzfuBPiwAsvMUEyyvlxGZWvVer9PTyvEbEYUd B09H19Da5RwqhVk73v3SStJBPe1a/1ZTDi6yJ3ZN22YpgrZXMunO/XH/xmZJ53R/uhCt JcMcFmMsSopedRua1AgQOjraPN0IwzkMf6m0UpqCJAYnAl5TNRdgA40jaI0oSxb5m3yq meqg== 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 h23si9134802edw.60.2021.03.09.08.20.08; Tue, 09 Mar 2021 08:20:31 -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 S231496AbhCIQQv (ORCPT + 99 others); Tue, 9 Mar 2021 11:16:51 -0500 Received: from mx1.riseup.net ([198.252.153.129]:40682 "EHLO mx1.riseup.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229790AbhCIQQT (ORCPT ); Tue, 9 Mar 2021 11:16:19 -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 4Dw0h22jsBzDsv2; Tue, 9 Mar 2021 08:16:18 -0800 (PST) X-Riseup-User-ID: 3ED3949EA10E99959A983EDB57BFE4D34477222650D69EAC7DC88CFF6BADEC7A Received: from [127.0.0.1] (localhost [127.0.0.1]) by fews1.riseup.net (Postfix) with ESMTPSA id 4Dw0h10VRjz5vhF; Tue, 9 Mar 2021 08:16:16 -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 v2] do_wait: make PIDTYPE_PID case O(1) instead of O(n) Date: Tue, 9 Mar 2021 10:15:48 -0600 Message-Id: <20210309161548.18786-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 | 54 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/kernel/exit.c b/kernel/exit.c index 04029e35e69a..312c4dfc9555 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -1439,6 +1439,33 @@ 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 *tsk) +{ + struct task_struct *target = pid_task(wo->wo_pid, PIDTYPE_PID); + if (!target) { + return 0; + } + if (tsk == target->real_parent || + (!(wo->wo_flags & __WNOTHREAD) && + same_thread_group(tsk, target->real_parent))) { + int retval = wait_consider_task(wo, /* ptrace= */ 0, target); + if (retval) { + return retval; + } + } + if (target->ptrace && (tsk == target->parent || + (!(wo->wo_flags & __WNOTHREAD) && + same_thread_group(tsk, target->parent)))) { + int 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; @@ -1464,18 +1491,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 (retval) + if (wo->wo_type == PIDTYPE_PID) { + retval = do_wait_pid(wo, tsk); + if (retval) { goto end; + } + } else { + do { + retval = do_wait_thread(wo, tsk); + if (retval) + goto end; - if (wo->wo_flags & __WNOTHREAD) - break; - } while_each_thread(current, tsk); + 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