diff options
author | Oleg Nesterov <oleg@redhat.com> | 2014-12-10 18:54:42 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-10 20:41:17 -0500 |
commit | 7f6def9f9b6ebba42fcdc12cfb3092f2cf44b3fe (patch) | |
tree | 031f84245bea9a5b64bcbdf0eb1f61e4949c6c34 /kernel/kmod.c | |
parent | 7117bc8888aff73fb081956afa501edcc85a1552 (diff) |
usermodehelper: kill the kmod_thread_locker logic
Now that we do not call kernel_thread(CLONE_VFORK) from the worker
thread we can not deadlock if do_execve() in turn triggers another
call_usermodehelper(), we can remove the kmod_thread_locker code.
Note: we should probably kill khelper_wq and simply use one of the
global workqueues, say, system_unbound_wq, this special wq for umh buys
nothing nowadays.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/kmod.c')
-rw-r--r-- | kernel/kmod.c | 33 |
1 files changed, 3 insertions, 30 deletions
diff --git a/kernel/kmod.c b/kernel/kmod.c index 4621771b43b9..2777f40a9c7b 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c | |||
@@ -47,13 +47,6 @@ extern int max_threads; | |||
47 | 47 | ||
48 | static struct workqueue_struct *khelper_wq; | 48 | static struct workqueue_struct *khelper_wq; |
49 | 49 | ||
50 | /* | ||
51 | * kmod_thread_locker is used for deadlock avoidance. There is no explicit | ||
52 | * locking to protect this global - it is private to the singleton khelper | ||
53 | * thread and should only ever be modified by that thread. | ||
54 | */ | ||
55 | static const struct task_struct *kmod_thread_locker; | ||
56 | |||
57 | #define CAP_BSET (void *)1 | 50 | #define CAP_BSET (void *)1 |
58 | #define CAP_PI (void *)2 | 51 | #define CAP_PI (void *)2 |
59 | 52 | ||
@@ -273,13 +266,6 @@ out: | |||
273 | do_exit(0); | 266 | do_exit(0); |
274 | } | 267 | } |
275 | 268 | ||
276 | static int call_helper(void *data) | ||
277 | { | ||
278 | /* Worker thread started blocking khelper thread. */ | ||
279 | kmod_thread_locker = current; | ||
280 | return ____call_usermodehelper(data); | ||
281 | } | ||
282 | |||
283 | /* Keventd can't block, but this (a child) can. */ | 269 | /* Keventd can't block, but this (a child) can. */ |
284 | static int wait_for_helper(void *data) | 270 | static int wait_for_helper(void *data) |
285 | { | 271 | { |
@@ -327,11 +313,9 @@ static void __call_usermodehelper(struct work_struct *work) | |||
327 | if (sub_info->wait & UMH_WAIT_PROC) | 313 | if (sub_info->wait & UMH_WAIT_PROC) |
328 | pid = kernel_thread(wait_for_helper, sub_info, | 314 | pid = kernel_thread(wait_for_helper, sub_info, |
329 | CLONE_FS | CLONE_FILES | SIGCHLD); | 315 | CLONE_FS | CLONE_FILES | SIGCHLD); |
330 | else { | 316 | else |
331 | pid = kernel_thread(call_helper, sub_info, SIGCHLD); | 317 | pid = kernel_thread(____call_usermodehelper, sub_info, |
332 | /* Worker thread stopped blocking khelper thread. */ | 318 | SIGCHLD); |
333 | kmod_thread_locker = NULL; | ||
334 | } | ||
335 | 319 | ||
336 | if (pid < 0) { | 320 | if (pid < 0) { |
337 | sub_info->retval = pid; | 321 | sub_info->retval = pid; |
@@ -565,17 +549,6 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, int wait) | |||
565 | goto out; | 549 | goto out; |
566 | } | 550 | } |
567 | /* | 551 | /* |
568 | * Worker thread must not wait for khelper thread at below | ||
569 | * wait_for_completion() if the thread was created with CLONE_VFORK | ||
570 | * flag, for khelper thread is already waiting for the thread at | ||
571 | * wait_for_completion() in do_fork(). | ||
572 | */ | ||
573 | if (wait != UMH_NO_WAIT && current == kmod_thread_locker) { | ||
574 | retval = -EBUSY; | ||
575 | goto out; | ||
576 | } | ||
577 | |||
578 | /* | ||
579 | * Set the completion pointer only if there is a waiter. | 552 | * Set the completion pointer only if there is a waiter. |
580 | * This makes it possible to use umh_complete to free | 553 | * This makes it possible to use umh_complete to free |
581 | * the data structure in case of UMH_NO_WAIT. | 554 | * the data structure in case of UMH_NO_WAIT. |