aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2015-09-09 18:38:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-09-10 16:29:01 -0400
commitb6b50a814d0ece9c1f98f2b3b5c2a251a5c9a211 (patch)
treed615f7b28ea461c7357fa57cc7ec308274d3846d
parent60b61a6f42f36e4fbfbc0139b7e86ce1494d2d9b (diff)
kmod: bunch of internal functions renames
This patchset does a bunch of cleanups and converts khelper to use system unbound workqueues. The 3 first patches should be uncontroversial. The last 2 patches are debatable. Kmod creates kernel threads that perform userspace jobs and we want those to have a large affinity in order not to contend busy CPUs. This is (partly) why we use khelper which has a wide affinity that the kernel threads it create can inherit from. Now khelper is a dedicated workqueue that has singlethread properties which we aren't interested in. Hence those two debatable changes: _ We would like to use generic workqueues. System unbound workqueues are a very good candidate but they are not wide affine, only node affine. Now probably a node is enough to perform many parallel kmod jobs. _ We would like to remove the wait_for_helper kernel thread (UMH_WAIT_PROC handler) to use the workqueue. It means that if the workqueue blocks, and no other worker can take pending kmod request, we can be screwed. Now if we have 512 threads, this should be enough. This patch (of 5): Underscores on function names aren't much verbose to explain the purpose of a function. And kmod has interesting such flavours. Lets rename the following functions: * __call_usermodehelper -> call_usermodehelper_exec_work * ____call_usermodehelper -> call_usermodehelper_exec_async * wait_for_helper -> call_usermodehelper_exec_sync Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Rik van Riel <riel@redhat.com> Reviewed-by: Oleg Nesterov <oleg@redhat.com> Cc: Christoph Lameter <cl@linux.com> Cc: Tejun Heo <tj@kernel.org> Cc: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--kernel/kmod.c30
1 files changed, 17 insertions, 13 deletions
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 1734ba61ff23..2d83511e9610 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -214,7 +214,7 @@ static void umh_complete(struct subprocess_info *sub_info)
214/* 214/*
215 * This is the task which runs the usermode application 215 * This is the task which runs the usermode application
216 */ 216 */
217static int ____call_usermodehelper(void *data) 217static int call_usermodehelper_exec_async(void *data)
218{ 218{
219 struct subprocess_info *sub_info = data; 219 struct subprocess_info *sub_info = data;
220 struct cred *new; 220 struct cred *new;
@@ -259,7 +259,10 @@ static int ____call_usermodehelper(void *data)
259 (const char __user *const __user *)sub_info->envp); 259 (const char __user *const __user *)sub_info->envp);
260out: 260out:
261 sub_info->retval = retval; 261 sub_info->retval = retval;
262 /* wait_for_helper() will call umh_complete if UHM_WAIT_PROC. */ 262 /*
263 * call_usermodehelper_exec_sync() will call umh_complete
264 * if UHM_WAIT_PROC.
265 */
263 if (!(sub_info->wait & UMH_WAIT_PROC)) 266 if (!(sub_info->wait & UMH_WAIT_PROC))
264 umh_complete(sub_info); 267 umh_complete(sub_info);
265 if (!retval) 268 if (!retval)
@@ -268,14 +271,14 @@ out:
268} 271}
269 272
270/* Keventd can't block, but this (a child) can. */ 273/* Keventd can't block, but this (a child) can. */
271static int wait_for_helper(void *data) 274static int call_usermodehelper_exec_sync(void *data)
272{ 275{
273 struct subprocess_info *sub_info = data; 276 struct subprocess_info *sub_info = data;
274 pid_t pid; 277 pid_t pid;
275 278
276 /* If SIGCLD is ignored sys_wait4 won't populate the status. */ 279 /* If SIGCLD is ignored sys_wait4 won't populate the status. */
277 kernel_sigaction(SIGCHLD, SIG_DFL); 280 kernel_sigaction(SIGCHLD, SIG_DFL);
278 pid = kernel_thread(____call_usermodehelper, sub_info, SIGCHLD); 281 pid = kernel_thread(call_usermodehelper_exec_async, sub_info, SIGCHLD);
279 if (pid < 0) { 282 if (pid < 0) {
280 sub_info->retval = pid; 283 sub_info->retval = pid;
281 } else { 284 } else {
@@ -283,17 +286,18 @@ static int wait_for_helper(void *data)
283 /* 286 /*
284 * Normally it is bogus to call wait4() from in-kernel because 287 * Normally it is bogus to call wait4() from in-kernel because
285 * wait4() wants to write the exit code to a userspace address. 288 * wait4() wants to write the exit code to a userspace address.
286 * But wait_for_helper() always runs as keventd, and put_user() 289 * But call_usermodehelper_exec_sync() always runs as keventd,
287 * to a kernel address works OK for kernel threads, due to their 290 * and put_user() to a kernel address works OK for kernel
288 * having an mm_segment_t which spans the entire address space. 291 * threads, due to their having an mm_segment_t which spans the
292 * entire address space.
289 * 293 *
290 * Thus the __user pointer cast is valid here. 294 * Thus the __user pointer cast is valid here.
291 */ 295 */
292 sys_wait4(pid, (int __user *)&ret, 0, NULL); 296 sys_wait4(pid, (int __user *)&ret, 0, NULL);
293 297
294 /* 298 /*
295 * If ret is 0, either ____call_usermodehelper failed and the 299 * If ret is 0, either call_usermodehelper_exec_async failed and
296 * real error code is already in sub_info->retval or 300 * the real error code is already in sub_info->retval or
297 * sub_info->retval is 0 anyway, so don't mess with it then. 301 * sub_info->retval is 0 anyway, so don't mess with it then.
298 */ 302 */
299 if (ret) 303 if (ret)
@@ -305,17 +309,17 @@ static int wait_for_helper(void *data)
305} 309}
306 310
307/* This is run by khelper thread */ 311/* This is run by khelper thread */
308static void __call_usermodehelper(struct work_struct *work) 312static void call_usermodehelper_exec_work(struct work_struct *work)
309{ 313{
310 struct subprocess_info *sub_info = 314 struct subprocess_info *sub_info =
311 container_of(work, struct subprocess_info, work); 315 container_of(work, struct subprocess_info, work);
312 pid_t pid; 316 pid_t pid;
313 317
314 if (sub_info->wait & UMH_WAIT_PROC) 318 if (sub_info->wait & UMH_WAIT_PROC)
315 pid = kernel_thread(wait_for_helper, sub_info, 319 pid = kernel_thread(call_usermodehelper_exec_sync, sub_info,
316 CLONE_FS | CLONE_FILES | SIGCHLD); 320 CLONE_FS | CLONE_FILES | SIGCHLD);
317 else 321 else
318 pid = kernel_thread(____call_usermodehelper, sub_info, 322 pid = kernel_thread(call_usermodehelper_exec_async, sub_info,
319 SIGCHLD); 323 SIGCHLD);
320 324
321 if (pid < 0) { 325 if (pid < 0) {
@@ -510,7 +514,7 @@ struct subprocess_info *call_usermodehelper_setup(char *path, char **argv,
510 if (!sub_info) 514 if (!sub_info)
511 goto out; 515 goto out;
512 516
513 INIT_WORK(&sub_info->work, __call_usermodehelper); 517 INIT_WORK(&sub_info->work, call_usermodehelper_exec_work);
514 sub_info->path = path; 518 sub_info->path = path;
515 sub_info->argv = argv; 519 sub_info->argv = argv;
516 sub_info->envp = envp; 520 sub_info->envp = envp;