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>
This commit is contained in:
Frederic Weisbecker 2015-09-09 15:38:13 -07:00 коммит произвёл Linus Torvalds
Родитель 60b61a6f42
Коммит b6b50a814d
1 изменённых файлов: 17 добавлений и 13 удалений

Просмотреть файл

@ -214,7 +214,7 @@ static void umh_complete(struct subprocess_info *sub_info)
/* /*
* This is the task which runs the usermode application * This is the task which runs the usermode application
*/ */
static int ____call_usermodehelper(void *data) static int call_usermodehelper_exec_async(void *data)
{ {
struct subprocess_info *sub_info = data; struct subprocess_info *sub_info = data;
struct cred *new; struct cred *new;
@ -259,7 +259,10 @@ static int ____call_usermodehelper(void *data)
(const char __user *const __user *)sub_info->envp); (const char __user *const __user *)sub_info->envp);
out: out:
sub_info->retval = retval; sub_info->retval = retval;
/* wait_for_helper() will call umh_complete if UHM_WAIT_PROC. */ /*
* call_usermodehelper_exec_sync() will call umh_complete
* if UHM_WAIT_PROC.
*/
if (!(sub_info->wait & UMH_WAIT_PROC)) if (!(sub_info->wait & UMH_WAIT_PROC))
umh_complete(sub_info); umh_complete(sub_info);
if (!retval) if (!retval)
@ -268,14 +271,14 @@ out:
} }
/* Keventd can't block, but this (a child) can. */ /* Keventd can't block, but this (a child) can. */
static int wait_for_helper(void *data) static int call_usermodehelper_exec_sync(void *data)
{ {
struct subprocess_info *sub_info = data; struct subprocess_info *sub_info = data;
pid_t pid; pid_t pid;
/* If SIGCLD is ignored sys_wait4 won't populate the status. */ /* If SIGCLD is ignored sys_wait4 won't populate the status. */
kernel_sigaction(SIGCHLD, SIG_DFL); kernel_sigaction(SIGCHLD, SIG_DFL);
pid = kernel_thread(____call_usermodehelper, sub_info, SIGCHLD); pid = kernel_thread(call_usermodehelper_exec_async, sub_info, SIGCHLD);
if (pid < 0) { if (pid < 0) {
sub_info->retval = pid; sub_info->retval = pid;
} else { } else {
@ -283,17 +286,18 @@ static int wait_for_helper(void *data)
/* /*
* Normally it is bogus to call wait4() from in-kernel because * Normally it is bogus to call wait4() from in-kernel because
* wait4() wants to write the exit code to a userspace address. * wait4() wants to write the exit code to a userspace address.
* But wait_for_helper() always runs as keventd, and put_user() * But call_usermodehelper_exec_sync() always runs as keventd,
* to a kernel address works OK for kernel threads, due to their * and put_user() to a kernel address works OK for kernel
* having an mm_segment_t which spans the entire address space. * threads, due to their having an mm_segment_t which spans the
* entire address space.
* *
* Thus the __user pointer cast is valid here. * Thus the __user pointer cast is valid here.
*/ */
sys_wait4(pid, (int __user *)&ret, 0, NULL); sys_wait4(pid, (int __user *)&ret, 0, NULL);
/* /*
* If ret is 0, either ____call_usermodehelper failed and the * If ret is 0, either call_usermodehelper_exec_async failed and
* real error code is already in sub_info->retval or * the real error code is already in sub_info->retval or
* sub_info->retval is 0 anyway, so don't mess with it then. * sub_info->retval is 0 anyway, so don't mess with it then.
*/ */
if (ret) if (ret)
@ -305,17 +309,17 @@ static int wait_for_helper(void *data)
} }
/* This is run by khelper thread */ /* This is run by khelper thread */
static void __call_usermodehelper(struct work_struct *work) static void call_usermodehelper_exec_work(struct work_struct *work)
{ {
struct subprocess_info *sub_info = struct subprocess_info *sub_info =
container_of(work, struct subprocess_info, work); container_of(work, struct subprocess_info, work);
pid_t pid; pid_t pid;
if (sub_info->wait & UMH_WAIT_PROC) if (sub_info->wait & UMH_WAIT_PROC)
pid = kernel_thread(wait_for_helper, sub_info, pid = kernel_thread(call_usermodehelper_exec_sync, sub_info,
CLONE_FS | CLONE_FILES | SIGCHLD); CLONE_FS | CLONE_FILES | SIGCHLD);
else else
pid = kernel_thread(____call_usermodehelper, sub_info, pid = kernel_thread(call_usermodehelper_exec_async, sub_info,
SIGCHLD); SIGCHLD);
if (pid < 0) { if (pid < 0) {
@ -510,7 +514,7 @@ struct subprocess_info *call_usermodehelper_setup(char *path, char **argv,
if (!sub_info) if (!sub_info)
goto out; goto out;
INIT_WORK(&sub_info->work, __call_usermodehelper); INIT_WORK(&sub_info->work, call_usermodehelper_exec_work);
sub_info->path = path; sub_info->path = path;
sub_info->argv = argv; sub_info->argv = argv;
sub_info->envp = envp; sub_info->envp = envp;