Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ---
- include/linux/kmod.h | 21 +++++++++++++++++++--
- kernel/kmod.c | 47 +++++++++++++++++++++++++++++++++++++----------
- kernel/power/process.c | 3 ++-
- 3 files changed, 58 insertions(+), 13 deletions(-)
- --- a/include/linux/kmod.h
- +++ b/include/linux/kmod.h
- @@ -112,10 +112,27 @@ call_usermodehelper(char *path, char **a
- extern struct ctl_table usermodehelper_table[];
- +enum umh_disable_depth {
- + UMH_ENABLED = 0,
- + UMH_FREEZING,
- + UMH_DISABLED,
- +};
- +
- extern void usermodehelper_init(void);
- -extern int usermodehelper_disable(void);
- -extern void usermodehelper_enable(void);
- +extern int __usermodehelper_disable(enum umh_disable_depth depth);
- +extern void __usermodehelper_set_disable_depth(enum umh_disable_depth depth);
- +
- +static inline int usermodehelper_disable(void)
- +{
- + return __usermodehelper_disable(UMH_DISABLED);
- +}
- +
- +static inline void usermodehelper_enable(void)
- +{
- + __usermodehelper_set_disable_depth(UMH_ENABLED);
- +}
- +
- extern int usermodehelper_read_trylock(void);
- extern long usermodehelper_read_lock_wait(long timeout);
- extern void usermodehelper_read_unlock(void);
- --- a/kernel/kmod.c
- +++ b/kernel/kmod.c
- @@ -279,7 +279,7 @@ static void __call_usermodehelper(struct
- * land has been frozen during a system-wide hibernation or suspend operation).
- * Should always be manipulated under umhelper_sem acquired for write.
- */
- -static int usermodehelper_disabled = 1;
- +static enum umh_disable_depth usermodehelper_disabled = UMH_DISABLED;
- /* Number of helpers running */
- static atomic_t running_helpers = ATOMIC_INIT(0);
- @@ -304,13 +304,30 @@ static DECLARE_WAIT_QUEUE_HEAD(usermodeh
- int usermodehelper_read_trylock(void)
- {
- + DEFINE_WAIT(wait);
- int ret = 0;
- down_read(&umhelper_sem);
- - if (usermodehelper_disabled) {
- + for (;;) {
- + prepare_to_wait(&usermodehelper_disabled_waitq, &wait,
- + TASK_INTERRUPTIBLE);
- + if (!usermodehelper_disabled)
- + break;
- +
- + if (usermodehelper_disabled == UMH_DISABLED)
- + ret = -EAGAIN;
- +
- up_read(&umhelper_sem);
- - ret = -EAGAIN;
- +
- + if (ret)
- + break;
- +
- + schedule();
- + try_to_freeze();
- +
- + down_read(&umhelper_sem);
- }
- + finish_wait(&usermodehelper_disabled_waitq, &wait);
- return ret;
- }
- EXPORT_SYMBOL_GPL(usermodehelper_read_trylock);
- @@ -349,25 +366,35 @@ void usermodehelper_read_unlock(void)
- EXPORT_SYMBOL_GPL(usermodehelper_read_unlock);
- /**
- - * usermodehelper_enable - allow new helpers to be started again
- + * __usermodehelper_set_disable_depth - Modify usermodehelper_disabled.
- + * depth: New value to assign into usermodehelper_disabled.
- + *
- + * Change the value of usermodehelper_disabled (under umhelper_sem locked for
- + * writing) and wakeup tasks waiting for it to change and prevent race.
- */
- -void usermodehelper_enable(void)
- +void __usermodehelper_set_disable_depth(enum umh_disable_depth depth)
- {
- down_write(&umhelper_sem);
- - usermodehelper_disabled = 0;
- + usermodehelper_disabled = depth;
- wake_up(&usermodehelper_disabled_waitq);
- up_write(&umhelper_sem);
- }
- /**
- - * usermodehelper_disable - prevent new helpers from being started
- + * __usermodehelper_disable - Prevent new helpers from being started.
- + * @depth: New value to assign into usermodehelper_disabled.
- + *
- + * Set usermodehelper_disabled to @depth and wait for running helpers to exit.
- */
- -int usermodehelper_disable(void)
- +int __usermodehelper_disable(enum umh_disable_depth depth)
- {
- long retval;
- + if (!depth)
- + return -EINVAL;
- +
- down_write(&umhelper_sem);
- - usermodehelper_disabled = 1;
- + usermodehelper_disabled = depth;
- up_write(&umhelper_sem);
- /*
- @@ -382,7 +409,7 @@ int usermodehelper_disable(void)
- if (retval)
- return 0;
- - usermodehelper_enable();
- + __usermodehelper_set_disable_depth(UMH_ENABLED);
- return -EAGAIN;
- }
- --- a/kernel/power/process.c
- +++ b/kernel/power/process.c
- @@ -123,7 +123,7 @@ int freeze_processes(void)
- {
- int error;
- - error = usermodehelper_disable();
- + error = __usermodehelper_disable(UMH_FREEZING);
- if (error)
- return error;
- @@ -135,6 +135,7 @@ int freeze_processes(void)
- error = try_to_freeze_tasks(true);
- if (!error) {
- printk("done.");
- + __usermodehelper_set_disable_depth(UMH_DISABLED);
- oom_killer_disable();
- }
- printk("\n");
- --
Add Comment
Please, Sign In to add comment