aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/kmod.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2011-12-25 17:42:20 -0500
committerRafael J. Wysocki <rjw@sisk.pl>2011-12-25 17:42:20 -0500
commitb7ba68c4a072c9aa8f04b8cf7838b6cd2f48d918 (patch)
treecd8f8029111fc52d06060691fb0325ba2e798e94 /kernel/kmod.c
parent8d274ab7d3d6f23e2bc0e433c8d53acbe60a9773 (diff)
parent90363ddf0a1a4dccfbb8d0c10b8f488bc7fa69f8 (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.c25
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;
48static kernel_cap_t usermodehelper_bset = CAP_FULL_SET; 51static kernel_cap_t usermodehelper_bset = CAP_FULL_SET;
49static kernel_cap_t usermodehelper_inheritable = CAP_FULL_SET; 52static kernel_cap_t usermodehelper_inheritable = CAP_FULL_SET;
50static DEFINE_SPINLOCK(umh_sysctl_lock); 53static DEFINE_SPINLOCK(umh_sysctl_lock);
54static 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 */
277static int usermodehelper_disabled = 1; 282static 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
299void read_lock_usermodehelper(void)
300{
301 down_read(&umhelper_sem);
302}
303EXPORT_SYMBOL_GPL(read_lock_usermodehelper);
304
305void read_unlock_usermodehelper(void)
306{
307 up_read(&umhelper_sem);
308}
309EXPORT_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 */
322void usermodehelper_enable(void) 343void 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/**