Hi, I have prepared a patch that makes request_firmware skip the usual grace period that it gives firmware images to show up, if it determines that userspace was not notified at all.
When request_firmware is called, it sends an event to userspace to ask for the firmware image that is needed, and then it installs a timeout so that it will not wait forever for the image. However, if userspace did not receive the event at all (no /sbin/hotplug, for instance), then having the kernel wait is pointless. This is particularly true during boot, when the wait is done synchronously and the whole kernel freezes for a minute. The attached patch fixes this by making _request_firmware check whether the firmware loading event was succesfully sent to userspace, and skip the timeout if it has not. The patch comes in two parts: 1. The first part changes kobject_uevent_env in lib/kobject_uevent.c to report a failure if both netlink_broadcast (if applicable) and call_usermodehelper fail to send the event to userspace. Nothing in the kernel seems to care about the return value of kobject_uevent_env, so this should not break anything. 2. The second part changes _request_firmware in drivers/base/firmware_class.c to actually check the return value of kobject_uevent and skip the loading_timeout delay if the loading event was not delivered to userspace at all. The patches apply cleanly against 2.6.23-rc1. Any suggestions or feedback will be welcome. Javier PS Please CC: me on replies, as I am not subscribed to the list. ========== From: Javier Pello <[EMAIL PROTECTED]> kobject_uevent: return an error if event was not delivered to userspace Make kobject_uevent_env return an error to the caller if the event was not delivered to userspace either via netlink or via uevent_helper. Signed-off-by: Javier Pello <[EMAIL PROTECTED]> --- diff -u linux-2.6.22/lib/kobject_uevent.c linux-2.6.22-p/lib/kobject_uevent.c --- linux-2.6.22/lib/kobject_uevent.c 2007-07-09 01:32:17.000000000 +0200 +++ linux-2.6.22-p/lib/kobject_uevent.c 2007-07-18 20:17:10.000000000 +0200 @@ -186,7 +186,8 @@ } NETLINK_CB(skb).dst_group = 1; - netlink_broadcast(uevent_sock, skb, 0, 1, GFP_KERNEL); + retval = netlink_broadcast(uevent_sock, skb, 0, 1, + GFP_KERNEL); } } #endif @@ -198,7 +199,18 @@ argv [0] = uevent_helper; argv [1] = (char *)subsystem; argv [2] = NULL; - call_usermodehelper (argv[0], argv, envp, UMH_WAIT_EXEC); +#if defined(CONFIG_NET) + if (retval) { + retval = call_usermodehelper (argv[0], argv, envp, + UMH_WAIT_EXEC); + } else { + call_usermodehelper (argv[0], argv, envp, + UMH_WAIT_EXEC); + } +#else + retval = call_usermodehelper (argv[0], argv, envp, + UMH_WAIT_EXEC); +#endif } exit: ========== From: Javier Pello <[EMAIL PROTECTED]> request_firmware: skip timeout if userspace was not notified Stop _request_firmware from setting up a timer and waiting for the firmware image to appear if kobject_uevent returns an error (meaning userspace was not notified at all). This prevents useless delays if there is no userspace tool to provide the firmware image (eg during boot). Signed-off-by: Javier Pello <[EMAIL PROTECTED]> --- diff -u linux-2.6.22/drivers/base/firmware_class.c linux-2.6.22-p/drivers/base/firmware_class.c --- linux-2.6.22/drivers/base/firmware_class.c 2007-07-09 01:32:17.000000000 +0200 +++ linux-2.6.22-p/drivers/base/firmware_class.c 2007-07-18 20:06:53.000000000 +0200 @@ -420,8 +420,12 @@ add_timer(&fw_priv->timeout); } - kobject_uevent(&f_dev->kobj, KOBJ_ADD); - wait_for_completion(&fw_priv->completion); + retval = kobject_uevent(&f_dev->kobj, KOBJ_ADD); + if (retval) { + fw_load_abort(fw_priv); + } else { + wait_for_completion(&fw_priv->completion); + } set_bit(FW_STATUS_DONE, &fw_priv->status); del_timer_sync(&fw_priv->timeout); } else ========== - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/