make sure that we always have a return path from kernel_execve()

The only place where kernel_execve() is called without a way to
return to the caller of kernel_thread() callback is kernel_post().
Reorganize kernel_init()/kernel_post() - instead of the former
calling the latter in the end (and getting freed by it), have the
latter *begin* with calling the former (and turn the latter into
kernel_thread() callback, of course).

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Al Viro 2012-10-10 19:57:26 -04:00
Родитель ecf89e581a
Коммит d6b2123802
1 изменённых файлов: 5 добавлений и 8 удалений

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

@ -794,11 +794,11 @@ static void run_init_process(const char *init_filename)
kernel_execve(init_filename, argv_init, envp_init); kernel_execve(init_filename, argv_init, envp_init);
} }
/* This is a non __init function. Force it to be noinline otherwise gcc static void __init kernel_init_freeable(void);
* makes it inline to init() and it becomes part of init.text section
*/ static int __ref kernel_init(void *unused)
static noinline int init_post(void)
{ {
kernel_init_freeable();
/* need to finish all async __init code before freeing the memory */ /* need to finish all async __init code before freeing the memory */
async_synchronize_full(); async_synchronize_full();
free_initmem(); free_initmem();
@ -835,7 +835,7 @@ static noinline int init_post(void)
"See Linux Documentation/init.txt for guidance."); "See Linux Documentation/init.txt for guidance.");
} }
static int __init kernel_init(void * unused) static void __init kernel_init_freeable(void)
{ {
/* /*
* Wait until kthreadd is all set-up. * Wait until kthreadd is all set-up.
@ -890,7 +890,4 @@ static int __init kernel_init(void * unused)
* we're essentially up and running. Get rid of the * we're essentially up and running. Get rid of the
* initmem segments and start the user-mode stuff.. * initmem segments and start the user-mode stuff..
*/ */
init_post();
return 0;
} }