diff options
author | KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> | 2008-07-25 04:45:38 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-25 13:53:28 -0400 |
commit | ac331d158e198d2a91a5b0a3ec4ca9991fdb57af (patch) | |
tree | b0921e2bc8e59d5df2c554c41c3b9f04e05d6d7c /kernel | |
parent | f557d0996a6f9c06912528ea85e1dba0fb7d485f (diff) |
call_usermodehelper(): increase reliability
Presently call_usermodehelper_setup() uses GFP_ATOMIC. but it can return
NULL _very_ easily.
GFP_ATOMIC is needed only when we can't sleep. and, GFP_KERNEL is robust
and better.
thus, I add gfp_mask argument to call_usermodehelper_setup().
So, its callers pass the gfp_t as below:
call_usermodehelper() and call_usermodehelper_keys():
depend on 'wait' argument.
call_usermodehelper_pipe():
always GFP_KERNEL because always run under process context.
orderly_poweroff():
pass to GFP_ATOMIC because may run under interrupt context.
Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: "Paul Menage" <menage@google.com>
Reviewed-by: Li Zefan <lizf@cn.fujitsu.com>
Acked-by: Jeremy Fitzhardinge <jeremy@xensource.com>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/kmod.c | 9 | ||||
-rw-r--r-- | kernel/sys.c | 2 |
2 files changed, 6 insertions, 5 deletions
diff --git a/kernel/kmod.c b/kernel/kmod.c index 2989f67c4446..2456d1a0befb 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c | |||
@@ -352,16 +352,17 @@ static inline void register_pm_notifier_callback(void) {} | |||
352 | * @path: path to usermode executable | 352 | * @path: path to usermode executable |
353 | * @argv: arg vector for process | 353 | * @argv: arg vector for process |
354 | * @envp: environment for process | 354 | * @envp: environment for process |
355 | * @gfp_mask: gfp mask for memory allocation | ||
355 | * | 356 | * |
356 | * Returns either %NULL on allocation failure, or a subprocess_info | 357 | * Returns either %NULL on allocation failure, or a subprocess_info |
357 | * structure. This should be passed to call_usermodehelper_exec to | 358 | * structure. This should be passed to call_usermodehelper_exec to |
358 | * exec the process and free the structure. | 359 | * exec the process and free the structure. |
359 | */ | 360 | */ |
360 | struct subprocess_info *call_usermodehelper_setup(char *path, | 361 | struct subprocess_info *call_usermodehelper_setup(char *path, char **argv, |
361 | char **argv, char **envp) | 362 | char **envp, gfp_t gfp_mask) |
362 | { | 363 | { |
363 | struct subprocess_info *sub_info; | 364 | struct subprocess_info *sub_info; |
364 | sub_info = kzalloc(sizeof(struct subprocess_info), GFP_ATOMIC); | 365 | sub_info = kzalloc(sizeof(struct subprocess_info), gfp_mask); |
365 | if (!sub_info) | 366 | if (!sub_info) |
366 | goto out; | 367 | goto out; |
367 | 368 | ||
@@ -494,7 +495,7 @@ int call_usermodehelper_pipe(char *path, char **argv, char **envp, | |||
494 | struct subprocess_info *sub_info; | 495 | struct subprocess_info *sub_info; |
495 | int ret; | 496 | int ret; |
496 | 497 | ||
497 | sub_info = call_usermodehelper_setup(path, argv, envp); | 498 | sub_info = call_usermodehelper_setup(path, argv, envp, GFP_KERNEL); |
498 | if (sub_info == NULL) | 499 | if (sub_info == NULL) |
499 | return -ENOMEM; | 500 | return -ENOMEM; |
500 | 501 | ||
diff --git a/kernel/sys.c b/kernel/sys.c index 14e97282eb6c..6c2188046048 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -1795,7 +1795,7 @@ int orderly_poweroff(bool force) | |||
1795 | goto out; | 1795 | goto out; |
1796 | } | 1796 | } |
1797 | 1797 | ||
1798 | info = call_usermodehelper_setup(argv[0], argv, envp); | 1798 | info = call_usermodehelper_setup(argv[0], argv, envp, GFP_ATOMIC); |
1799 | if (info == NULL) { | 1799 | if (info == NULL) { |
1800 | argv_free(argv); | 1800 | argv_free(argv); |
1801 | goto out; | 1801 | goto out; |