diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2011-12-25 17:42:20 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2011-12-25 17:42:20 -0500 |
commit | b7ba68c4a072c9aa8f04b8cf7838b6cd2f48d918 (patch) | |
tree | cd8f8029111fc52d06060691fb0325ba2e798e94 /kernel/kmod.c | |
parent | 8d274ab7d3d6f23e2bc0e433c8d53acbe60a9773 (diff) | |
parent | 90363ddf0a1a4dccfbb8d0c10b8f488bc7fa69f8 (diff) |
Merge branch 'pm-sleep' into pm-for-linus
* pm-sleep: (51 commits)
PM: Drop generic_subsys_pm_ops
PM / Sleep: Remove forward-only callbacks from AMBA bus type
PM / Sleep: Remove forward-only callbacks from platform bus type
PM: Run the driver callback directly if the subsystem one is not there
PM / Sleep: Make pm_op() and pm_noirq_op() return callback pointers
PM / Sleep: Merge internal functions in generic_ops.c
PM / Sleep: Simplify generic system suspend callbacks
PM / Hibernate: Remove deprecated hibernation snapshot ioctls
PM / Sleep: Fix freezer failures due to racy usermodehelper_is_disabled()
PM / Sleep: Recommend [un]lock_system_sleep() over using pm_mutex directly
PM / Sleep: Replace mutex_[un]lock(&pm_mutex) with [un]lock_system_sleep()
PM / Sleep: Make [un]lock_system_sleep() generic
PM / Sleep: Use the freezer_count() functions in [un]lock_system_sleep() APIs
PM / Freezer: Remove the "userspace only" constraint from freezer[_do_not]_count()
PM / Hibernate: Replace unintuitive 'if' condition in kernel/power/user.c with 'else'
Freezer / sunrpc / NFS: don't allow TASK_KILLABLE sleeps to block the freezer
PM / Sleep: Unify diagnostic messages from device suspend/resume
ACPI / PM: Do not save/restore NVS on Asus K54C/K54HR
PM / Hibernate: Remove deprecated hibernation test modes
PM / Hibernate: Thaw processes in SNAPSHOT_CREATE_IMAGE ioctl test path
...
Conflicts:
kernel/kmod.c
Diffstat (limited to 'kernel/kmod.c')
-rw-r--r-- | kernel/kmod.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/kernel/kmod.c b/kernel/kmod.c index 2142687094d3..a0a88543934e 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c | |||
@@ -34,6 +34,9 @@ | |||
34 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/resource.h> | 36 | #include <linux/resource.h> |
37 | #include <linux/notifier.h> | ||
38 | #include <linux/suspend.h> | ||
39 | #include <linux/rwsem.h> | ||
37 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
38 | 41 | ||
39 | #include <trace/events/module.h> | 42 | #include <trace/events/module.h> |
@@ -48,6 +51,7 @@ static struct workqueue_struct *khelper_wq; | |||
48 | static kernel_cap_t usermodehelper_bset = CAP_FULL_SET; | 51 | static kernel_cap_t usermodehelper_bset = CAP_FULL_SET; |
49 | static kernel_cap_t usermodehelper_inheritable = CAP_FULL_SET; | 52 | static kernel_cap_t usermodehelper_inheritable = CAP_FULL_SET; |
50 | static DEFINE_SPINLOCK(umh_sysctl_lock); | 53 | static DEFINE_SPINLOCK(umh_sysctl_lock); |
54 | static DECLARE_RWSEM(umhelper_sem); | ||
51 | 55 | ||
52 | #ifdef CONFIG_MODULES | 56 | #ifdef CONFIG_MODULES |
53 | 57 | ||
@@ -273,6 +277,7 @@ static void __call_usermodehelper(struct work_struct *work) | |||
273 | * If set, call_usermodehelper_exec() will exit immediately returning -EBUSY | 277 | * If set, call_usermodehelper_exec() will exit immediately returning -EBUSY |
274 | * (used for preventing user land processes from being created after the user | 278 | * (used for preventing user land processes from being created after the user |
275 | * land has been frozen during a system-wide hibernation or suspend operation). | 279 | * land has been frozen during a system-wide hibernation or suspend operation). |
280 | * Should always be manipulated under umhelper_sem acquired for write. | ||
276 | */ | 281 | */ |
277 | static int usermodehelper_disabled = 1; | 282 | static int usermodehelper_disabled = 1; |
278 | 283 | ||
@@ -291,6 +296,18 @@ static DECLARE_WAIT_QUEUE_HEAD(running_helpers_waitq); | |||
291 | */ | 296 | */ |
292 | #define RUNNING_HELPERS_TIMEOUT (5 * HZ) | 297 | #define RUNNING_HELPERS_TIMEOUT (5 * HZ) |
293 | 298 | ||
299 | void read_lock_usermodehelper(void) | ||
300 | { | ||
301 | down_read(&umhelper_sem); | ||
302 | } | ||
303 | EXPORT_SYMBOL_GPL(read_lock_usermodehelper); | ||
304 | |||
305 | void read_unlock_usermodehelper(void) | ||
306 | { | ||
307 | up_read(&umhelper_sem); | ||
308 | } | ||
309 | EXPORT_SYMBOL_GPL(read_unlock_usermodehelper); | ||
310 | |||
294 | /** | 311 | /** |
295 | * usermodehelper_disable - prevent new helpers from being started | 312 | * usermodehelper_disable - prevent new helpers from being started |
296 | */ | 313 | */ |
@@ -298,8 +315,10 @@ int usermodehelper_disable(void) | |||
298 | { | 315 | { |
299 | long retval; | 316 | long retval; |
300 | 317 | ||
318 | down_write(&umhelper_sem); | ||
301 | usermodehelper_disabled = 1; | 319 | usermodehelper_disabled = 1; |
302 | smp_mb(); | 320 | up_write(&umhelper_sem); |
321 | |||
303 | /* | 322 | /* |
304 | * From now on call_usermodehelper_exec() won't start any new | 323 | * From now on call_usermodehelper_exec() won't start any new |
305 | * helpers, so it is sufficient if running_helpers turns out to | 324 | * helpers, so it is sufficient if running_helpers turns out to |
@@ -312,7 +331,9 @@ int usermodehelper_disable(void) | |||
312 | if (retval) | 331 | if (retval) |
313 | return 0; | 332 | return 0; |
314 | 333 | ||
334 | down_write(&umhelper_sem); | ||
315 | usermodehelper_disabled = 0; | 335 | usermodehelper_disabled = 0; |
336 | up_write(&umhelper_sem); | ||
316 | return -EAGAIN; | 337 | return -EAGAIN; |
317 | } | 338 | } |
318 | 339 | ||
@@ -321,7 +342,9 @@ int usermodehelper_disable(void) | |||
321 | */ | 342 | */ |
322 | void usermodehelper_enable(void) | 343 | void usermodehelper_enable(void) |
323 | { | 344 | { |
345 | down_write(&umhelper_sem); | ||
324 | usermodehelper_disabled = 0; | 346 | usermodehelper_disabled = 0; |
347 | up_write(&umhelper_sem); | ||
325 | } | 348 | } |
326 | 349 | ||
327 | /** | 350 | /** |