Commit a144c6a (PM: Print a warning if firmware is requested when tasksare frozen) introduced usermodehelper_is_disabled() to warn and exitimmediately if firmware is requested when usermodehelpers are disabled.

However, it is racy. Consider the following scenario, currently used indrivers/base/firmware_class.c:

...if (usermodehelper_is_disabled()) goto out;

/* Do actual work */...

out: return err;

Nothing prevents someone from disabling usermodehelpers just after the checkin the 'if' condition, which means that it is quite possible to try doing the"actual work" with usermodehelpers disabled, leading to undesirableconsequences.

In particular, this race condition in _request_firmware() causes task freezingfailures whenever suspend/hibernation is in progress because, it wrongly waitsto get the firmware/microcode image from userspace when actually theusermodehelpers are disabled or userspace has been frozen.Some of the example scenarios that cause freezing failures due to this raceare those that depend on userspace via request_firmware(), such as x86microcode module initialization and microcode image reload.

It is to be noted that this patchset fixes the freezing failures but doesn'tremove the warnings. IOW, it does not attempt to add explicit synchronizationto x86 microcode driver to avoid requesting microcode image at inopportunemoments. Because, the warnings were introduced to highlight such cases, in thefirst place. And we need not silence the warnings, since we take care of the*real* problem (freezing failure) and hence, after that, the warnings arepretty harmless anyway.

/*@@ -286,6 +289,7 @@ static void __call_usermodehelper(struct * If set, call_usermodehelper_exec() will exit immediately returning -EBUSY * (used for preventing user land processes from being created after the user * 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;