From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753506AbcGYQX6 (ORCPT ); Mon, 25 Jul 2016 12:23:58 -0400 Received: from mx1.redhat.com ([209.132.183.28]:50595 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752930AbcGYQX4 (ORCPT ); Mon, 25 Jul 2016 12:23:56 -0400 Date: Mon, 25 Jul 2016 18:23:53 +0200 From: Oleg Nesterov To: Andrew Morton Cc: Dave Anderson , Ingo Molnar , Peter Zijlstra , "Paul E. McKenney" , Wang Shu , linux-kernel@vger.kernel.org Subject: [PATCH 3/3] hung_task.c: change the "max_count" code to use for_each_process_thread_break/continue Message-ID: <20160725162353.GA23953@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20160725162332.GA23935@redhat.com> User-Agent: Mutt/1.5.24 (2015-08-30) X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Mon, 25 Jul 2016 16:23:56 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org If sysctl_hung_task_check_count is low and the first "max_count" threads do not exit, check_hung_uninterruptible_tasks() will never check other tasks, this is just ugly. Now that we have for_each_process_thread_continue(), we can save g/t before return and restart on the next call. Signed-off-by: Oleg Nesterov --- kernel/hung_task.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/kernel/hung_task.c b/kernel/hung_task.c index 517f52e..e6e516d 100644 --- a/kernel/hung_task.c +++ b/kernel/hung_task.c @@ -148,6 +148,9 @@ static void rcu_lock_break(void) */ static void check_hung_uninterruptible_tasks(unsigned long timeout) { + /* we have only one watchdog() thread */ + static struct task_struct *g_saved, *t_saved; + int max_count = sysctl_hung_task_check_count; int batch_count = HUNG_TASK_BATCHING; struct task_struct *g, *t; @@ -160,18 +163,29 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout) return; rcu_read_lock(); + if (g_saved) { + g = g_saved; + t = t_saved; + g_saved = NULL; + goto resume; + } + for_each_process_thread(g, t) { /* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */ if (t->state == TASK_UNINTERRUPTIBLE) check_hung_task(t, timeout); - if (!--max_count) - goto unlock; - if (!--batch_count) { - batch_count = HUNG_TASK_BATCHING; + if (!--max_count || !--batch_count) { for_each_process_thread_break(g, t); + if (!max_count) { + g_saved = g; + t_saved = t; + goto unlock; + } rcu_lock_break(); + resume: for_each_process_thread_continue(&g, &t); + batch_count = HUNG_TASK_BATCHING; } } unlock: -- 2.5.0