Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 298609
b: refs/heads/master
c: 247bc03
h: refs/heads/master
i:
  298607: ded9ecf
v: v3
  • Loading branch information
Rafael J. Wysocki committed Mar 28, 2012
1 parent b1fc549 commit a111f84
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 14 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1e73203cd1157a03facc41ffb54050f5b28e55bd
refs/heads/master: 247bc03742545fec2f79939a3b9f738392a0f7b4
21 changes: 19 additions & 2 deletions trunk/include/linux/kmod.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,27 @@ call_usermodehelper(char *path, char **argv, char **envp, int wait)

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);
Expand Down
47 changes: 37 additions & 10 deletions trunk/kernel/kmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ static void __call_usermodehelper(struct work_struct *work)
* 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);
Expand All @@ -347,13 +347,30 @@ static DECLARE_WAIT_QUEUE_HEAD(usermodehelper_disabled_waitq);

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);
Expand Down Expand Up @@ -392,25 +409,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 to usermodehelper_disabled.
*
* Change the value of usermodehelper_disabled (under umhelper_sem locked for
* writing) and wakeup tasks waiting for it to change.
*/
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 to 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);

/*
Expand All @@ -425,7 +452,7 @@ int usermodehelper_disable(void)
if (retval)
return 0;

usermodehelper_enable();
__usermodehelper_set_disable_depth(UMH_ENABLED);
return -EAGAIN;
}

Expand Down
3 changes: 2 additions & 1 deletion trunk/kernel/power/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ int freeze_processes(void)
{
int error;

error = usermodehelper_disable();
error = __usermodehelper_disable(UMH_FREEZING);
if (error)
return error;

Expand All @@ -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");
Expand Down

0 comments on commit a111f84

Please sign in to comment.