Commit ac331d158e198d2a91a5b0a3ec4ca9991fdb57af
Committed by
Linus Torvalds
1 parent
f557d0996a
Exists in
master
and in
39 other branches
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>
Showing 3 changed files with 13 additions and 9 deletions Side-by-side Diff
include/linux/kmod.h
... | ... | @@ -19,6 +19,7 @@ |
19 | 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
20 | 20 | */ |
21 | 21 | |
22 | +#include <linux/gfp.h> | |
22 | 23 | #include <linux/stddef.h> |
23 | 24 | #include <linux/errno.h> |
24 | 25 | #include <linux/compiler.h> |
... | ... | @@ -41,8 +42,8 @@ |
41 | 42 | struct subprocess_info; |
42 | 43 | |
43 | 44 | /* Allocate a subprocess_info structure */ |
44 | -struct subprocess_info *call_usermodehelper_setup(char *path, | |
45 | - char **argv, char **envp); | |
45 | +struct subprocess_info *call_usermodehelper_setup(char *path, char **argv, | |
46 | + char **envp, gfp_t gfp_mask); | |
46 | 47 | |
47 | 48 | /* Set various pieces of state into the subprocess_info structure */ |
48 | 49 | void call_usermodehelper_setkeys(struct subprocess_info *info, |
49 | 50 | |
... | ... | @@ -69,8 +70,9 @@ |
69 | 70 | call_usermodehelper(char *path, char **argv, char **envp, enum umh_wait wait) |
70 | 71 | { |
71 | 72 | struct subprocess_info *info; |
73 | + gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL; | |
72 | 74 | |
73 | - info = call_usermodehelper_setup(path, argv, envp); | |
75 | + info = call_usermodehelper_setup(path, argv, envp, gfp_mask); | |
74 | 76 | if (info == NULL) |
75 | 77 | return -ENOMEM; |
76 | 78 | return call_usermodehelper_exec(info, wait); |
77 | 79 | |
... | ... | @@ -81,8 +83,9 @@ |
81 | 83 | struct key *session_keyring, enum umh_wait wait) |
82 | 84 | { |
83 | 85 | struct subprocess_info *info; |
86 | + gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL; | |
84 | 87 | |
85 | - info = call_usermodehelper_setup(path, argv, envp); | |
88 | + info = call_usermodehelper_setup(path, argv, envp, gfp_mask); | |
86 | 89 | if (info == NULL) |
87 | 90 | return -ENOMEM; |
88 | 91 |
kernel/kmod.c
... | ... | @@ -352,16 +352,17 @@ |
352 | 352 | * @path: path to usermode executable |
353 | 353 | * @argv: arg vector for process |
354 | 354 | * @envp: environment for process |
355 | + * @gfp_mask: gfp mask for memory allocation | |
355 | 356 | * |
356 | 357 | * Returns either %NULL on allocation failure, or a subprocess_info |
357 | 358 | * structure. This should be passed to call_usermodehelper_exec to |
358 | 359 | * exec the process and free the structure. |
359 | 360 | */ |
360 | -struct subprocess_info *call_usermodehelper_setup(char *path, | |
361 | - char **argv, char **envp) | |
361 | +struct subprocess_info *call_usermodehelper_setup(char *path, char **argv, | |
362 | + char **envp, gfp_t gfp_mask) | |
362 | 363 | { |
363 | 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 | 366 | if (!sub_info) |
366 | 367 | goto out; |
367 | 368 | |
... | ... | @@ -494,7 +495,7 @@ |
494 | 495 | struct subprocess_info *sub_info; |
495 | 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 | 499 | if (sub_info == NULL) |
499 | 500 | return -ENOMEM; |
500 | 501 |
kernel/sys.c