From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751573AbdFFTQX (ORCPT ); Tue, 6 Jun 2017 15:16:23 -0400 Received: from out02.mta.xmission.com ([166.70.13.232]:51934 "EHLO out02.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751946AbdFFTOj (ORCPT ); Tue, 6 Jun 2017 15:14:39 -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:31 -0500 Message-Id: <20170606190338.28347-19-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=1dIJv4-0006wd-OK;;;mid=<20170606190338.28347-19-ebiederm@xmission.com>;;;hst=in02.mta.xmission.com;;;ip=97.121.81.159;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX197ZCDhAdi+lnSmDShZYDC9/w8f8R447tM= 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 * 0.0 TVD_RCVD_IP Message was received from an IP address * 1.5 XMNoVowels Alpha-numberic number with no vowels * 0.7 XMSubLong Long Subject * 0.8 BAYES_50 BODY: Bayes spam probability is 40 to 60% * [score: 0.5000] * -0.0 DCC_CHECK_NEGATIVE Not listed in DCC * [sa05 1397; Body=1 Fuz1=1 Fuz2=1] * 0.0 T_TooManySym_01 4+ unique symbols in subject * 0.1 XMSolicitRefs_0 Weightloss drug X-Spam-DCC: XMission; sa05 1397; Body=1 Fuz1=1 Fuz2=1 X-Spam-Combo: **;linux-kernel@vger.kernel.org X-Spam-Relay-Country: X-Spam-Timing: total 5541 ms - load_scoreonly_sql: 0.04 (0.0%), signal_user_changed: 2.7 (0.0%), b_tie_ro: 1.89 (0.0%), parse: 1.09 (0.0%), extract_message_metadata: 14 (0.3%), get_uri_detail_list: 2.8 (0.1%), tests_pri_-1000: 3.8 (0.1%), tests_pri_-950: 1.35 (0.0%), tests_pri_-900: 1.16 (0.0%), tests_pri_-400: 25 (0.4%), check_bayes: 23 (0.4%), b_tokenize: 10 (0.2%), b_tok_get_all: 7 (0.1%), b_comp_prob: 2.4 (0.0%), b_tok_touch_all: 2.5 (0.0%), b_finish: 0.57 (0.0%), tests_pri_0: 249 (4.5%), check_dkim_signature: 0.53 (0.0%), check_dkim_adsp: 2.5 (0.0%), tests_pri_500: 5240 (94.6%), poll_dns_idle: 5235 (94.5%), rewrite_mail: 0.00 (0.0%) Subject: [PATCH 19/26] wait: Simpler code for clearing notask_error in wait_consider_task 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 Start with reaping pending zombies and then return if there is nothing wait_task_consider can ever do with the task. What remains are living tasks and delayed child zombie thread group leaders waiting for their thread group to exit. Leaving something for WEXITED to find later. As long as WEXITED can happen the code is guaranteed not to block indefinitely, as at least the exit event will wake it up. The only reason not to clear notask_error is if it is impossible for wait to find something to report. For zombie thread group leaders it is possible that living threads will report group wide continued or stopped states. Which means we can now safely and practically always clear notask_error. Signed-off-by: "Eric W. Biederman" --- kernel/exit.c | 62 ++++++++++++++++++++++------------------------------------- 1 file changed, 23 insertions(+), 39 deletions(-) diff --git a/kernel/exit.c b/kernel/exit.c index 4e2d2b6f5581..8f3825b22de5 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -1359,47 +1359,31 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace, if ((exit_state == EXIT_TRACEE) && ptrace) return wait_task_zombie(wo, exit_state, p); - if (unlikely(exit_state == EXIT_TRACED)) { - /* - * ptrace == 0 means we are the natural parent. In this case - * we should clear notask_error, debugger will notify us. - */ - if (likely(!ptrace)) - wo->notask_error = 0; + /* Is this task past the point where ptrace cares? */ + if (unlikely((exit_state == EXIT_TRACED) && ptrace)) return 0; - } - if (exit_state == EXIT_ZOMBIE) { - /* - * Allow access to stopped/continued state via zombie by - * falling through. Clearing of notask_error is complex. - * - * When !@ptrace: - * - * If WEXITED is set, notask_error should naturally be - * cleared. If not, subset of WSTOPPED|WCONTINUED is set, - * so, if there are live subthreads, there are events to - * wait for. If all subthreads are dead, it's still safe - * to clear - this function will be called again in finite - * amount time once all the subthreads are released and - * will then return without clearing. - * - * When @ptrace: - * - * Stopped state is per-task and thus can't change once the - * target task dies. Only continued and exited can happen. - * Clear notask_error if WCONTINUED | WEXITED. - */ - if ((!ptrace && (!p->ptrace || ptrace_reparented(p))) || - (wo->wo_flags & (WCONTINUED | WEXITED))) - wo->notask_error = 0; - } else { - /* - * @p is alive and it's gonna stop, continue or exit, so - * there always is something to wait for. - */ - wo->notask_error = 0; - } + /* + * A this point @p is alive or the zombie of a delayed + * child thread group leader that has not been reaped yet. + * + * Allow access to stopped/continued state via zombie by + * falling through. Clearing of notask_error is logically complex. + * + * When @p is alive and it's gonna stop, continue or exit, + * so there always is something to wait for. + * + * When @p is a zombie + * + * If WEXITED is set, notask_error should naturally be + * cleared. If not, subset of WSTOPPED|WCONTINUED is set, + * so, if there are live subthreads, there are events to + * wait for. If all subthreads are dead, it's still safe + * to clear - this function will be called again in finite + * amount time once all the subthreads are released and + * will then return without clearing. + */ + wo->notask_error = 0; /* * Wait for stopped. -- 2.10.1