Revision 90d41e74a9c36a84e2efbd2a5b8d79299feee6fa authored by Luis R. Rodriguez on 20 July 2017, 20:13:10 UTC, committed by Greg Kroah-Hartman on 10 August 2017, 20:54:16 UTC
Fix batched requests from waiting forever on failure. The firmware API batched requests feature has been broken since the API call request_firmware_direct() was introduced on commit bba3a87e982ad ("firmware: Introduce request_firmware_direct()"), added on v3.14 *iff* the firmware being requested was not present in *certain kernel builds* [0]. When no firmware is found the worker which goes on to finish never informs waiters queued up of this, so any batched request will stall in what seems to be forever (MAX_SCHEDULE_TIMEOUT). Sadly, a reboot will also stall, as the reboot notifier was only designed to kill custom fallback workers. The issue seems to the user as a type of soft lockup, what *actually* happens underneath the hood is a wait call which never completes as we failed to issue a completion on error. For device drivers with optional firmware schemes (ie, Intel iwlwifi, or Netronome -- even though it uses request_firmware() and not request_firmware_direct()), this could mean that when you boot a system with multiple cards the firmware will seem to never load on the system, or that the card is just not responsive even the driver initialization. Due to differences in scheduling possible this should not always trigger -- one would need to to ensure that multiple requests are in place at the right time for this to work, also release_firmware() must not be called prior to any other incoming request. The complexity may not be worth supporting batched requests in the future given the wait mechanism is only used also for the fallback mechanism. We'll keep it for now and just fix it. Its reported that at least with the Intel WiFi cards on one system this issue was creeping up 50% of the boots [0]. Before this commit batched requests testing revealed: ============================================================================ CONFIG_FW_LOADER_USER_HELPER_FALLBACK=n CONFIG_FW_LOADER_USER_HELPER=y Most common Linux distribution setup. API-type no-firmware-found firmware-found ---------------------------------------------------------------------- request_firmware() FAIL OK request_firmware_direct() FAIL OK request_firmware_nowait(uevent=true) FAIL OK request_firmware_nowait(uevent=false) FAIL OK ============================================================================ CONFIG_FW_LOADER_USER_HELPER_FALLBACK=n CONFIG_FW_LOADER_USER_HELPER=n Only possible if CONFIG_DELL_RBU=n and CONFIG_LEDS_LP55XX_COMMON=n, rare. API-type no-firmware-found firmware-found ---------------------------------------------------------------------- request_firmware() FAIL OK request_firmware_direct() FAIL OK request_firmware_nowait(uevent=true) FAIL OK request_firmware_nowait(uevent=false) FAIL OK ============================================================================ CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y CONFIG_FW_LOADER_USER_HELPER=y Google Android setup. API-type no-firmware-found firmware-found ---------------------------------------------------------------------- request_firmware() OK OK request_firmware_direct() FAIL OK request_firmware_nowait(uevent=true) OK OK request_firmware_nowait(uevent=false) OK OK ============================================================================ Ater this commit batched testing results: ============================================================================ CONFIG_FW_LOADER_USER_HELPER_FALLBACK=n CONFIG_FW_LOADER_USER_HELPER=y Most common Linux distribution setup. API-type no-firmware-found firmware-found ---------------------------------------------------------------------- request_firmware() OK OK request_firmware_direct() OK OK request_firmware_nowait(uevent=true) OK OK request_firmware_nowait(uevent=false) OK OK ============================================================================ CONFIG_FW_LOADER_USER_HELPER_FALLBACK=n CONFIG_FW_LOADER_USER_HELPER=n Only possible if CONFIG_DELL_RBU=n and CONFIG_LEDS_LP55XX_COMMON=n, rare. API-type no-firmware-found firmware-found ---------------------------------------------------------------------- request_firmware() OK OK request_firmware_direct() OK OK request_firmware_nowait(uevent=true) OK OK request_firmware_nowait(uevent=false) OK OK ============================================================================ CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y CONFIG_FW_LOADER_USER_HELPER=y Google Android setup. API-type no-firmware-found firmware-found ---------------------------------------------------------------------- request_firmware() OK OK request_firmware_direct() OK OK request_firmware_nowait(uevent=true) OK OK request_firmware_nowait(uevent=false) OK OK ============================================================================ [0] https://bugzilla.kernel.org/show_bug.cgi?id=195477 Cc: stable <stable@vger.kernel.org> # v3.14 Fixes: bba3a87e982ad ("firmware: Introduce request_firmware_direct()" Reported-by: Nicolas <nbroeking@me.com> Reported-by: John Ewalt <jewalt@lgsinnovations.com> Reported-by: Jakub Kicinski <jakub.kicinski@netronome.com> Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent e44565f
File | Mode | Size |
---|---|---|
842 | ||
fonts | ||
lz4 | ||
lzo | ||
mpi | ||
raid6 | ||
reed_solomon | ||
xz | ||
zlib_deflate | ||
zlib_inflate | ||
.gitignore | -rw-r--r-- | 70 bytes |
Kconfig | -rw-r--r-- | 12.6 KB |
Kconfig.debug | -rw-r--r-- | 65.2 KB |
Kconfig.kasan | -rw-r--r-- | 1.8 KB |
Kconfig.kgdb | -rw-r--r-- | 4.1 KB |
Kconfig.kmemcheck | -rw-r--r-- | 2.9 KB |
Kconfig.ubsan | -rw-r--r-- | 1.5 KB |
Makefile | -rw-r--r-- | 7.7 KB |
argv_split.c | -rw-r--r-- | 2.1 KB |
asn1_decoder.c | -rw-r--r-- | 13.2 KB |
assoc_array.c | -rw-r--r-- | 52.6 KB |
atomic64.c | -rw-r--r-- | 4.8 KB |
atomic64_test.c | -rw-r--r-- | 6.6 KB |
audit.c | -rw-r--r-- | 1.7 KB |
bcd.c | -rw-r--r-- | 261 bytes |
bch.c | -rw-r--r-- | 35.6 KB |
bitmap.c | -rw-r--r-- | 36.5 KB |
bitrev.c | -rw-r--r-- | 1.9 KB |
bsearch.c | -rw-r--r-- | 1.5 KB |
btree.c | -rw-r--r-- | 19.2 KB |
bug.c | -rw-r--r-- | 4.9 KB |
build_OID_registry | -rwxr-xr-x | 4.7 KB |
bust_spinlocks.c | -rw-r--r-- | 660 bytes |
chacha20.c | -rw-r--r-- | 2.6 KB |
check_signature.c | -rw-r--r-- | 599 bytes |
checksum.c | -rw-r--r-- | 5.0 KB |
clz_ctz.c | -rw-r--r-- | 1.3 KB |
clz_tab.c | -rw-r--r-- | 855 bytes |
cmdline.c | -rw-r--r-- | 5.1 KB |
compat_audit.c | -rw-r--r-- | 796 bytes |
cordic.c | -rw-r--r-- | 2.5 KB |
cpu_rmap.c | -rw-r--r-- | 7.8 KB |
cpumask.c | -rw-r--r-- | 5.3 KB |
crc-ccitt.c | -rw-r--r-- | 3.0 KB |
crc-itu-t.c | -rw-r--r-- | 2.8 KB |
crc-t10dif.c | -rw-r--r-- | 1.6 KB |
crc16.c | -rw-r--r-- | 2.8 KB |
crc32.c | -rw-r--r-- | 9.1 KB |
crc32defs.h | -rw-r--r-- | 2.0 KB |
crc32test.c | -rw-r--r-- | 37.5 KB |
crc4.c | -rw-r--r-- | 1.1 KB |
crc7.c | -rw-r--r-- | 2.6 KB |
crc8.c | -rw-r--r-- | 2.4 KB |
ctype.c | -rw-r--r-- | 1.4 KB |
debug_info.c | -rw-r--r-- | 741 bytes |
debug_locks.c | -rw-r--r-- | 1.2 KB |
debugobjects.c | -rw-r--r-- | 28.2 KB |
dec_and_lock.c | -rw-r--r-- | 784 bytes |
decompress.c | -rw-r--r-- | 1.7 KB |
decompress_bunzip2.c | -rw-r--r-- | 23.5 KB |
decompress_inflate.c | -rw-r--r-- | 4.4 KB |
decompress_unlz4.c | -rw-r--r-- | 4.2 KB |
decompress_unlzma.c | -rw-r--r-- | 15.8 KB |
decompress_unlzo.c | -rw-r--r-- | 7.1 KB |
decompress_unxz.c | -rw-r--r-- | 10.9 KB |
devres.c | -rw-r--r-- | 9.8 KB |
digsig.c | -rw-r--r-- | 5.6 KB |
div64.c | -rw-r--r-- | 4.1 KB |
dma-debug.c | -rw-r--r-- | 44.2 KB |
dma-noop.c | -rw-r--r-- | 1.6 KB |
dma-virt.c | -rw-r--r-- | 1.4 KB |
dump_stack.c | -rw-r--r-- | 1.2 KB |
dynamic_debug.c | -rw-r--r-- | 25.3 KB |
dynamic_queue_limits.c | -rw-r--r-- | 4.3 KB |
earlycpio.c | -rw-r--r-- | 4.0 KB |
errseq.c | -rw-r--r-- | 6.5 KB |
extable.c | -rw-r--r-- | 3.2 KB |
fault-inject.c | -rw-r--r-- | 6.2 KB |
fdt.c | -rw-r--r-- | 69 bytes |
fdt_empty_tree.c | -rw-r--r-- | 80 bytes |
fdt_ro.c | -rw-r--r-- | 72 bytes |
fdt_rw.c | -rw-r--r-- | 72 bytes |
fdt_strerror.c | -rw-r--r-- | 78 bytes |
fdt_sw.c | -rw-r--r-- | 72 bytes |
fdt_wip.c | -rw-r--r-- | 73 bytes |
find_bit.c | -rw-r--r-- | 4.5 KB |
flex_array.c | -rw-r--r-- | 11.0 KB |
flex_proportions.c | -rw-r--r-- | 6.9 KB |
gcd.c | -rw-r--r-- | 1.3 KB |
gen_crc32table.c | -rw-r--r-- | 3.2 KB |
genalloc.c | -rw-r--r-- | 21.6 KB |
glob.c | -rw-r--r-- | 3.5 KB |
globtest.c | -rw-r--r-- | 4.2 KB |
hexdump.c | -rw-r--r-- | 8.3 KB |
hweight.c | -rw-r--r-- | 2.0 KB |
idr.c | -rw-r--r-- | 14.3 KB |
inflate.c | -rw-r--r-- | 38.6 KB |
int_sqrt.c | -rw-r--r-- | 652 bytes |
interval_tree.c | -rw-r--r-- | 499 bytes |
interval_tree_test.c | -rw-r--r-- | 3.3 KB |
iomap.c | -rw-r--r-- | 6.5 KB |
iomap_copy.c | -rw-r--r-- | 2.8 KB |
iommu-common.c | -rw-r--r-- | 7.0 KB |
iommu-helper.c | -rw-r--r-- | 1.0 KB |
ioremap.c | -rw-r--r-- | 4.1 KB |
iov_iter.c | -rw-r--r-- | 33.6 KB |
irq_poll.c | -rw-r--r-- | 5.4 KB |
irq_regs.c | -rw-r--r-- | 604 bytes |
is_single_threaded.c | -rw-r--r-- | 1.4 KB |
jedec_ddr_data.c | -rw-r--r-- | 3.0 KB |
kasprintf.c | -rw-r--r-- | 1.4 KB |
kfifo.c | -rw-r--r-- | 12.7 KB |
klist.c | -rw-r--r-- | 10.3 KB |
kobject.c | -rw-r--r-- | 26.1 KB |
kobject_uevent.c | -rw-r--r-- | 14.3 KB |
kstrtox.c | -rw-r--r-- | 10.6 KB |
kstrtox.h | -rw-r--r-- | 254 bytes |
lcm.c | -rw-r--r-- | 441 bytes |
libcrc32c.c | -rw-r--r-- | 2.1 KB |
list_debug.c | -rw-r--r-- | 1.8 KB |
list_sort.c | -rw-r--r-- | 3.5 KB |
llist.c | -rw-r--r-- | 3.1 KB |
locking-selftest-hardirq.h | -rw-r--r-- | 207 bytes |
locking-selftest-mutex.h | -rw-r--r-- | 120 bytes |
locking-selftest-rlock-hardirq.h | -rw-r--r-- | 74 bytes |
locking-selftest-rlock-softirq.h | -rw-r--r-- | 74 bytes |
locking-selftest-rlock.h | -rw-r--r-- | 158 bytes |
locking-selftest-rsem.h | -rw-r--r-- | 163 bytes |
locking-selftest-rtmutex.h | -rw-r--r-- | 123 bytes |
locking-selftest-softirq.h | -rw-r--r-- | 207 bytes |
locking-selftest-spin-hardirq.h | -rw-r--r-- | 73 bytes |
locking-selftest-spin-softirq.h | -rw-r--r-- | 73 bytes |
locking-selftest-spin.h | -rw-r--r-- | 118 bytes |
locking-selftest-wlock-hardirq.h | -rw-r--r-- | 74 bytes |
locking-selftest-wlock-softirq.h | -rw-r--r-- | 74 bytes |
locking-selftest-wlock.h | -rw-r--r-- | 158 bytes |
locking-selftest-wsem.h | -rw-r--r-- | 163 bytes |
locking-selftest.c | -rw-r--r-- | 41.9 KB |
lockref.c | -rw-r--r-- | 3.9 KB |
lru_cache.c | -rw-r--r-- | 19.4 KB |
memory-notifier-error-inject.c | -rw-r--r-- | 1.1 KB |
memweight.c | -rw-r--r-- | 999 bytes |
net_utils.c | -rw-r--r-- | 604 bytes |
netdev-notifier-error-inject.c | -rw-r--r-- | 1.5 KB |
nlattr.c | -rw-r--r-- | 15.8 KB |
nmi_backtrace.c | -rw-r--r-- | 3.1 KB |
nodemask.c | -rw-r--r-- | 617 bytes |
notifier-error-inject.c | -rw-r--r-- | 2.7 KB |
notifier-error-inject.h | -rw-r--r-- | 614 bytes |
of-reconfig-notifier-error-inject.c | -rw-r--r-- | 1.3 KB |
oid_registry.c | -rw-r--r-- | 3.8 KB |
once.c | -rw-r--r-- | 1.3 KB |
parman.c | -rw-r--r-- | 10.6 KB |
parser.c | -rw-r--r-- | 8.4 KB |
pci_iomap.c | -rw-r--r-- | 4.2 KB |
percpu-refcount.c | -rw-r--r-- | 12.4 KB |
percpu_counter.c | -rw-r--r-- | 5.8 KB |
percpu_ida.c | -rw-r--r-- | 9.5 KB |
percpu_test.c | -rw-r--r-- | 3.2 KB |
plist.c | -rw-r--r-- | 5.9 KB |
pm-notifier-error-inject.c | -rw-r--r-- | 1.1 KB |
prime_numbers.c | -rw-r--r-- | 6.5 KB |
radix-tree.c | -rw-r--r-- | 62.3 KB |
random32.c | -rw-r--r-- | 12.7 KB |
ratelimit.c | -rw-r--r-- | 1.6 KB |
rational.c | -rw-r--r-- | 1.5 KB |
rbtree.c | -rw-r--r-- | 17.4 KB |
rbtree_test.c | -rw-r--r-- | 5.5 KB |
reciprocal_div.c | -rw-r--r-- | 492 bytes |
refcount.c | -rw-r--r-- | 10.2 KB |
rhashtable.c | -rw-r--r-- | 27.0 KB |
sbitmap.c | -rw-r--r-- | 12.5 KB |
scatterlist.c | -rw-r--r-- | 19.5 KB |
seq_buf.c | -rw-r--r-- | 7.8 KB |
sg_pool.c | -rw-r--r-- | 3.6 KB |
sg_split.c | -rw-r--r-- | 5.1 KB |
sha1.c | -rw-r--r-- | 6.1 KB |
show_mem.c | -rw-r--r-- | 1.3 KB |
siphash.c | -rw-r--r-- | 11.7 KB |
smp_processor_id.c | -rw-r--r-- | 1.3 KB |
sort.c | -rw-r--r-- | 2.4 KB |
stackdepot.c | -rw-r--r-- | 8.5 KB |
stmp_device.c | -rw-r--r-- | 2.1 KB |
string.c | -rw-r--r-- | 20.7 KB |
string_helpers.c | -rw-r--r-- | 13.5 KB |
strncpy_from_user.c | -rw-r--r-- | 3.1 KB |
strnlen_user.c | -rw-r--r-- | 3.4 KB |
swiotlb.c | -rw-r--r-- | 28.3 KB |
syscall.c | -rw-r--r-- | 2.6 KB |
test-kstrtox.c | -rw-r--r-- | 17.3 KB |
test-string_helpers.c | -rw-r--r-- | 10.3 KB |
test_bitmap.c | -rw-r--r-- | 9.9 KB |
test_bpf.c | -rw-r--r-- | 139.0 KB |
test_firmware.c | -rw-r--r-- | 4.8 KB |
test_hash.c | -rw-r--r-- | 6.3 KB |
test_hexdump.c | -rw-r--r-- | 5.7 KB |
test_kasan.c | -rw-r--r-- | 10.0 KB |
test_kmod.c | -rw-r--r-- | 30.3 KB |
test_list_sort.c | -rw-r--r-- | 3.4 KB |
test_module.c | -rw-r--r-- | 753 bytes |
test_parman.c | -rw-r--r-- | 11.2 KB |
test_printf.c | -rw-r--r-- | 12.4 KB |
test_rhashtable.c | -rw-r--r-- | 10.3 KB |
test_siphash.c | -rw-r--r-- | 7.5 KB |
test_sort.c | -rw-r--r-- | 754 bytes |
test_static_key_base.c | -rw-r--r-- | 2.0 KB |
test_static_keys.c | -rw-r--r-- | 6.0 KB |
test_sysctl.c | -rw-r--r-- | 3.3 KB |
test_user_copy.c | -rw-r--r-- | 5.6 KB |
test_uuid.c | -rw-r--r-- | 3.4 KB |
textsearch.c | -rw-r--r-- | 9.4 KB |
timerqueue.c | -rw-r--r-- | 3.1 KB |
ts_bm.c | -rw-r--r-- | 5.3 KB |
ts_fsm.c | -rw-r--r-- | 10.6 KB |
ts_kmp.c | -rw-r--r-- | 4.3 KB |
ubsan.c | -rw-r--r-- | 10.9 KB |
ubsan.h | -rw-r--r-- | 1.5 KB |
ucs2_string.c | -rw-r--r-- | 2.4 KB |
usercopy.c | -rw-r--r-- | 728 bytes |
uuid.c | -rw-r--r-- | 3.1 KB |
vsprintf.c | -rw-r--r-- | 70.4 KB |
win_minmax.c | -rw-r--r-- | 3.3 KB |
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...