On Mon, 2010-07-26 at 20:12 +0300, Michael S. Tsirkin wrote: > On Fri, Jul 02, 2010 at 11:06:37PM +0200, Oleg Nesterov wrote: > > On 07/02, Peter Zijlstra wrote: > > > > > > On Fri, 2010-07-02 at 11:01 -0700, Sridhar Samudrala wrote: > > > > > > > > Does it (Tejun's kthread_clone() patch) also inherit the > > > > cgroup of the caller? > > > > > > Of course, its a simple do_fork() which inherits everything just as you > > > would expect from a similar sys_clone()/sys_fork() call. > > > > Yes. And I'm afraid it can inherit more than we want. IIUC, this is called > > from ioctl(), right? > > > > Then the new thread becomes the natural child of the caller, and it shares > > ->mm with the parent. And files, dup_fd() without CLONE_FS. > > > > Signals. Say, if you send SIGKILL to this new thread, it can't sleep in > > TASK_INTERRUPTIBLE or KILLABLE after that. And this SIGKILL can be sent > > just because the parent gets SIGQUIT or abother coredumpable signal. > > Or the new thread can recieve SIGSTOP via ^Z. > > > > Perhaps this is OK, I do not know. Just to remind that kernel_thread() > > is merely clone(CLONE_VM). > > > > Oleg. > > With some machinery to stop it later, yes. > Oleg, how does the below look to you? > > Here I explicitly drop the fds so we don't share them. > CLONE_VM takes care of sharing the mm I think. > About signals - for the vhost-net use this is OK as we use > uninterruptible sleep anyway (like the new kthread_worker does). > > This code seems to work fine for me so far - any comments? > > --- > > diff --git a/include/linux/kthread.h b/include/linux/kthread.h > index aabc8a1..72c7b17 100644 > --- a/include/linux/kthread.h > +++ b/include/linux/kthread.h > @@ -9,6 +9,11 @@ struct task_struct *kthread_create(int (*threadfn)(void *data), > const char namefmt[], ...) > __attribute__((format(printf, 3, 4))); > > +struct task_struct *kthread_create_inherit(int (*threadfn)(void *data), > + void *data, > + const char namefmt[], ...) > + __attribute__((format(printf, 3, 4))); > + > /** > * kthread_run - create and wake a thread. > * @threadfn: the function to run until signal_pending(current). > diff --git a/kernel/kthread.c b/kernel/kthread.c > index 83911c7..b81588c 100644 > --- a/kernel/kthread.c > +++ b/kernel/kthread.c > @@ -149,6 +149,38 @@ struct task_struct *kthread_create(int (*threadfn)(void *data), > } > EXPORT_SYMBOL(kthread_create); > > +/* Same as kthread_create, but inherit attributes (cgroups, priority, CPU mask) > + * from current. */ > +struct task_struct *kthread_create_inherit(int (*threadfn)(void *data), > + void *data, > + const char namefmt[], > + ...) > +{ > + struct kthread_create_info create; > + > + create.threadfn = threadfn; > + create.data = data; > + init_completion(&create.done); > + > + create_kthread(&create); > + wait_for_completion(&create.done); > + > + if (!IS_ERR(create.result)) { > + va_list args; > + > + /* Don't share files with parent as drivers use release for > + * close on exit, etc. */ > + exit_files(create.result); > + > + va_start(args, namefmt); > + vsnprintf(create.result->comm, sizeof(create.result->comm), > + namefmt, args); > + va_end(args); > + } > + return create.result; > +} > +EXPORT_SYMBOL(kthread_create_inherit); > + > /** > * kthread_bind - bind a just-created kthread to a cpu. > * @p: thread created by kthread_create(). I have been testing out a similar patch that uses kernel_thread() without CLONE_FILES flag rather than create_kthread() and then closing the files. Either version should be fine. diff --git a/include/linux/kthread.h b/include/linux/kthread.h index aabc8a1..634eaf7 100644 --- a/include/linux/kthread.h +++ b/include/linux/kthread.h @@ -9,6 +9,11 @@ struct task_struct *kthread_create(int (*threadfn)(void *data), const char namefmt[], ...) __attribute__((format(printf, 3, 4))); +struct task_struct *kthread_clone(int (*threadfn)(void *data), + void *data, + const char namefmt[], ...) + __attribute__((format(printf, 3, 4))); + /** * kthread_run - create and wake a thread. * @threadfn: the function to run until signal_pending(current). diff --git a/kernel/kthread.c b/kernel/kthread.c index 83911c7..806dae5 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -149,6 +149,38 @@ struct task_struct *kthread_create(int (*threadfn)(void *data), } EXPORT_SYMBOL(kthread_create); +struct task_struct *kthread_clone(int (*threadfn)(void *data), + void *data, + const char namefmt[], + ...) +{ + struct kthread_create_info create; + int pid; + + create.threadfn = threadfn; + create.data = data; + init_completion(&create.done); + INIT_LIST_HEAD(&create.list); + + pid = kernel_thread(kthread, &create, CLONE_FS); + if (pid < 0) { + create.result = ERR_PTR(pid); + complete(&create.done); + } + wait_for_completion(&create.done); + + if (!IS_ERR(create.result)) { + va_list args; + va_start(args, namefmt); + vsnprintf(create.result->comm, sizeof(create.result->comm), + namefmt, args); + va_end(args); + } + + return create.result; +} +EXPORT_SYMBOL(kthread_clone); + /** * kthread_bind - bind a just-created kthread to a cpu. * @p: thread created by kthread_create(). -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html