All of lore.kernel.org
 help / color / mirror / Atom feed
From: Oleg Nesterov <oleg@redhat.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>,
	Rik van Riel <riel@redhat.com>, Christoph Lameter <cl@linux.com>,
	Tejun Heo <tj@kernel.org>, Rusty Russell <rusty@rustcorp.com.au>,
	linux-kernel@vger.kernel.org
Subject: [PATCH 1/1] Revert "kmod: handle UMH_WAIT_PROC from system unbound workqueue"
Date: Wed, 14 Oct 2015 20:52:09 +0200	[thread overview]
Message-ID: <20151014185209.GB8117@redhat.com> (raw)
In-Reply-To: <20151014185153.GA8117@redhat.com>

This reverts commit bb304a5c6fc63d8506cd9741a3a5f35b73605625.

Because this patch leads to kthread zombies.

call_usermodehelper_exec_sync() does fork() + wait() with "unignored"
SIGCHLD. What we have missed is that this worker thread can have other
children previously forked by call_usermodehelper_exec_work() without
UMH_WAIT_PROC. If such a child exits in between it becomes a zombie
and nobody can reap it (unless/until this worker thread exits too).

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
 kernel/kmod.c | 44 ++++++++++++++++++++++++--------------------
 1 file changed, 24 insertions(+), 20 deletions(-)

diff --git a/kernel/kmod.c b/kernel/kmod.c
index da98d05..d38b2da 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -265,9 +265,15 @@ out:
 	do_exit(0);
 }
 
-/* Handles UMH_WAIT_PROC.  */
-static void call_usermodehelper_exec_sync(struct subprocess_info *sub_info)
+/*
+ * Handles UMH_WAIT_PROC. Our parent (unbound workqueue) might not be able to
+ * run enough instances to handle usermodehelper completions without blocking
+ * some other pending requests. That's why we use a kernel thread dedicated for
+ * that purpose.
+ */
+static int call_usermodehelper_exec_sync(void *data)
 {
+	struct subprocess_info *sub_info = data;
 	pid_t pid;
 
 	/* If SIGCLD is ignored sys_wait4 won't populate the status. */
@@ -281,9 +287,9 @@ static void call_usermodehelper_exec_sync(struct subprocess_info *sub_info)
 		 * Normally it is bogus to call wait4() from in-kernel because
 		 * wait4() wants to write the exit code to a userspace address.
 		 * But call_usermodehelper_exec_sync() always runs as kernel
-		 * thread (workqueue) and put_user() to a kernel address works
-		 * OK for kernel threads, due to their having an mm_segment_t
-		 * which spans the entire address space.
+		 * thread and put_user() to a kernel address works OK for kernel
+		 * threads, due to their having an mm_segment_t which spans the
+		 * entire address space.
 		 *
 		 * Thus the __user pointer cast is valid here.
 		 */
@@ -298,21 +304,19 @@ static void call_usermodehelper_exec_sync(struct subprocess_info *sub_info)
 			sub_info->retval = ret;
 	}
 
-	/* Restore default kernel sig handler */
-	kernel_sigaction(SIGCHLD, SIG_IGN);
-
 	umh_complete(sub_info);
+	do_exit(0);
 }
 
 /*
- * We need to create the usermodehelper kernel thread from a task that is affine
+ * This function doesn't strictly needs to be called asynchronously. But we
+ * need to create the usermodehelper kernel threads from a task that is affine
  * to an optimized set of CPUs (or nohz housekeeping ones) such that they
  * inherit a widest affinity irrespective of call_usermodehelper() callers with
  * possibly reduced affinity (eg: per-cpu workqueues). We don't want
  * usermodehelper targets to contend a busy CPU.
  *
- * Unbound workqueues provide such wide affinity and allow to block on
- * UMH_WAIT_PROC requests without blocking pending request (up to some limit).
+ * Unbound workqueues provide such wide affinity.
  *
  * Besides, workqueues provide the privilege level that caller might not have
  * to perform the usermodehelper request.
@@ -322,18 +326,18 @@ static void call_usermodehelper_exec_work(struct work_struct *work)
 {
 	struct subprocess_info *sub_info =
 		container_of(work, struct subprocess_info, work);
+	pid_t pid;
 
-	if (sub_info->wait & UMH_WAIT_PROC) {
-		call_usermodehelper_exec_sync(sub_info);
-	} else {
-		pid_t pid;
-
+	if (sub_info->wait & UMH_WAIT_PROC)
+		pid = kernel_thread(call_usermodehelper_exec_sync, sub_info,
+				    CLONE_FS | CLONE_FILES | SIGCHLD);
+	else
 		pid = kernel_thread(call_usermodehelper_exec_async, sub_info,
 				    SIGCHLD);
-		if (pid < 0) {
-			sub_info->retval = pid;
-			umh_complete(sub_info);
-		}
+
+	if (pid < 0) {
+		sub_info->retval = pid;
+		umh_complete(sub_info);
 	}
 }
 
-- 
2.4.3



  reply	other threads:[~2015-10-14 18:55 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-14 18:51 [PATCH 0/1] Revert "kmod: handle UMH_WAIT_PROC from system unbound workqueue" Oleg Nesterov
2015-10-14 18:52 ` Oleg Nesterov [this message]
2015-10-15 13:37   ` [PATCH 1/1] " Frederic Weisbecker
2015-10-15 15:18     ` Oleg Nesterov
2015-10-15 15:34       ` Frederic Weisbecker
2015-10-15 14:37 ` [PATCH 0/1] kmod: don't run async usermode helper as a child of kworker thread Oleg Nesterov
2015-10-15 14:37   ` Oleg Nesterov
2015-10-15 15:52     ` Frederic Weisbecker
2015-10-15 16:32       ` Oleg Nesterov
2015-10-15 16:53         ` Frederic Weisbecker
2015-10-15 17:51           ` Oleg Nesterov
2015-10-15 17:52   ` [PATCH v2 1/1] " Oleg Nesterov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20151014185209.GB8117@redhat.com \
    --to=oleg@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=cl@linux.com \
    --cc=fweisbec@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=riel@redhat.com \
    --cc=rusty@rustcorp.com.au \
    --cc=tj@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.