Re: [PATCH v3 1/3] init / kthread: add module_long_probe_init() and module_long_probe_exit()
From: Oleg Nesterov <oleg@redhat.com>
Date: 2014-08-18 15:23:04
Also in:
linux-scsi, lkml
On 08/18, Takashi Iwai wrote:
At Mon, 18 Aug 2014 14:22:17 +0200, Oleg Nesterov wrote:quoted
On 08/18, Takashi Iwai wrote:quoted
#define module_long_probe_init(initfn) \ static int _long_probe_##initfn(void *arg) \ { \ module_put_and_exit(initfn()); \ return 0; \ } \ static int __init __long_probe_##initfn(void) \ { \ struct task_struct *__init_thread = \ kthread_create(_long_probe_##initfn, \ NULL, #initfn); \ if (IS_ERR(__init_thread)) \ return PTR_ERR(__init_thread); \ __module_get(THIS_MODULE); \ wake_up_process(__init_thread); \ return 0; \ } \ module_init(__long_probe_##initfn) ... and module_exit() remains identical as the normal version.Aaaah. This is not true, module_exit() should not call exitfn() if initfn() fails... So _long_probe_##initfn() needs to save the error code which should be checked by module_exit().Oh, right. So we need a reference in the module exit path in anyway,
We only need to save the error code,
static int _long_probe_retval;
static int _long_probe_##initfn(void *arg)
{
_long_probe_retval = initfn();
module_put_and_exit(0); /* noreturn */
}
static void __long_probe_##exitfn(void)
{
if (!_long_probe_retval)
exitfn();
}
and Luis' version might be shorter in the end.
I dont't think that "shorter" does matter in this case. The real difference is sys_delete_module() behaviour if it is called before initfn() completes. And, again, I do not really know which version is better. Oleg.