aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/kmod.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2012-03-28 17:30:02 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2012-03-28 17:30:02 -0400
commit9b78c1da60b3c62ccdd1509f0902ad19ceaf776b (patch)
tree1e662bb29f04c2b875207d907db917476ddce60b /kernel/kmod.c
parent811fa4004485dec8977176bf605a5b0508ee206c (diff)
firmware_class: Do not warn that system is not ready from async loads
If firmware is requested asynchronously, by calling request_firmware_nowait(), there is no reason to fail the request (and warn the user) when the system is (presumably temporarily) unready to handle it (because user space is not available yet or frozen). For this reason, introduce an alternative routine for read-locking umhelper_sem, usermodehelper_read_lock_wait(), that will wait for usermodehelper_disabled to be unset (possibly with a timeout) and make request_firmware_work_func() use it instead of usermodehelper_read_trylock(). Accordingly, modify request_firmware() so that it uses usermodehelper_read_trylock() to acquire umhelper_sem and remove the code related to that lock from _request_firmware(). Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: stable@vger.kernel.org
Diffstat (limited to 'kernel/kmod.c')
-rw-r--r--kernel/kmod.c58
1 files changed, 45 insertions, 13 deletions
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 4079ac1d5e79..da7fcca279f9 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -334,6 +334,12 @@ static atomic_t running_helpers = ATOMIC_INIT(0);
334static DECLARE_WAIT_QUEUE_HEAD(running_helpers_waitq); 334static DECLARE_WAIT_QUEUE_HEAD(running_helpers_waitq);
335 335
336/* 336/*
337 * Used by usermodehelper_read_lock_wait() to wait for usermodehelper_disabled
338 * to become 'false'.
339 */
340static DECLARE_WAIT_QUEUE_HEAD(usermodehelper_disabled_waitq);
341
342/*
337 * Time to wait for running_helpers to become zero before the setting of 343 * Time to wait for running_helpers to become zero before the setting of
338 * usermodehelper_disabled in usermodehelper_disable() fails 344 * usermodehelper_disabled in usermodehelper_disable() fails
339 */ 345 */
@@ -352,6 +358,33 @@ int usermodehelper_read_trylock(void)
352} 358}
353EXPORT_SYMBOL_GPL(usermodehelper_read_trylock); 359EXPORT_SYMBOL_GPL(usermodehelper_read_trylock);
354 360
361long usermodehelper_read_lock_wait(long timeout)
362{
363 DEFINE_WAIT(wait);
364
365 if (timeout < 0)
366 return -EINVAL;
367
368 down_read(&umhelper_sem);
369 for (;;) {
370 prepare_to_wait(&usermodehelper_disabled_waitq, &wait,
371 TASK_UNINTERRUPTIBLE);
372 if (!usermodehelper_disabled)
373 break;
374
375 up_read(&umhelper_sem);
376
377 timeout = schedule_timeout(timeout);
378 if (!timeout)
379 break;
380
381 down_read(&umhelper_sem);
382 }
383 finish_wait(&usermodehelper_disabled_waitq, &wait);
384 return timeout;
385}
386EXPORT_SYMBOL_GPL(usermodehelper_read_lock_wait);
387
355void usermodehelper_read_unlock(void) 388void usermodehelper_read_unlock(void)
356{ 389{
357 up_read(&umhelper_sem); 390 up_read(&umhelper_sem);
@@ -359,6 +392,17 @@ void usermodehelper_read_unlock(void)
359EXPORT_SYMBOL_GPL(usermodehelper_read_unlock); 392EXPORT_SYMBOL_GPL(usermodehelper_read_unlock);
360 393
361/** 394/**
395 * usermodehelper_enable - allow new helpers to be started again
396 */
397void usermodehelper_enable(void)
398{
399 down_write(&umhelper_sem);
400 usermodehelper_disabled = 0;
401 wake_up(&usermodehelper_disabled_waitq);
402 up_write(&umhelper_sem);
403}
404
405/**
362 * usermodehelper_disable - prevent new helpers from being started 406 * usermodehelper_disable - prevent new helpers from being started
363 */ 407 */
364int usermodehelper_disable(void) 408int usermodehelper_disable(void)
@@ -381,22 +425,10 @@ int usermodehelper_disable(void)
381 if (retval) 425 if (retval)
382 return 0; 426 return 0;
383 427
384 down_write(&umhelper_sem); 428 usermodehelper_enable();
385 usermodehelper_disabled = 0;
386 up_write(&umhelper_sem);
387 return -EAGAIN; 429 return -EAGAIN;
388} 430}
389 431
390/**
391 * usermodehelper_enable - allow new helpers to be started again
392 */
393void usermodehelper_enable(void)
394{
395 down_write(&umhelper_sem);
396 usermodehelper_disabled = 0;
397 up_write(&umhelper_sem);
398}
399
400static void helper_lock(void) 432static void helper_lock(void)
401{ 433{
402 atomic_inc(&running_helpers); 434 atomic_inc(&running_helpers);