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
History
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

back to top