Commit c92316bf authored by Luis R. Rodriguez's avatar Luis R. Rodriguez Committed by Greg Kroah-Hartman

test_firmware: add batched firmware tests

The firmware API has a feature to enable batching requests for the same fil
e under one worker, so only one lookup is done. This only triggers if we so
happen to schedule two lookups for same file around the same time, or if
release_firmware() has not been called for a successful firmware call. This
can happen for instance if you happen to have multiple devices and one
device driver for certain drivers where the stars line up scheduling
wise.

This adds a new sync and async test trigger. Instead of adding a new
trigger for each new test type we make the tests a bit configurable so that
we could configure the tests in userspace and just kick a test through a
few basic triggers. With this, for instance the two types of sync requests:

  o request_firmware() and
  o request_firmware_direct()

can be modified with a knob. Likewise the two type of async requests:

   o request_firmware_nowait(uevent=true) and
   o request_firmware_nowait(uevent=false)

can be configured with another knob. The call request_firmware_into_buf()
has no users... yet.

The old tests are left in place as-is given they serve a few other purposes
which we are currently not interested in also testing yet. This will change
later as we will be able to just consolidate all tests under a few basic
triggers with just one general configuration setup.

We perform two types of tests, one for where the file is present and one
for where the file is not present. All test tests go tested and they now
pass for the following 3 kernel builds possible for the firmware API:

0. Most distro setup:
   CONFIG_FW_LOADER_USER_HELPER_FALLBACK=n
   CONFIG_FW_LOADER_USER_HELPER=y
1. Android:
   CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
   CONFIG_FW_LOADER_USER_HELPER=y
2. Rare build:
   CONFIG_FW_LOADER_USER_HELPER_FALLBACK=n
   CONFIG_FW_LOADER_USER_HELPER=n
Signed-off-by: default avatarLuis R. Rodriguez <mcgrof@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 30172bea
This diff is collapsed.
...@@ -25,8 +25,9 @@ if [ ! -d $DIR ]; then ...@@ -25,8 +25,9 @@ if [ ! -d $DIR ]; then
fi fi
# CONFIG_FW_LOADER_USER_HELPER has a sysfs class under /sys/class/firmware/ # CONFIG_FW_LOADER_USER_HELPER has a sysfs class under /sys/class/firmware/
# These days no one enables CONFIG_FW_LOADER_USER_HELPER so check for that # These days most distros enable CONFIG_FW_LOADER_USER_HELPER but disable
# as an indicator for CONFIG_FW_LOADER_USER_HELPER. # CONFIG_FW_LOADER_USER_HELPER_FALLBACK. We use /sys/class/firmware/ as an
# indicator for CONFIG_FW_LOADER_USER_HELPER.
HAS_FW_LOADER_USER_HELPER=$(if [ -d /sys/class/firmware/ ]; then echo yes; else echo no; fi) HAS_FW_LOADER_USER_HELPER=$(if [ -d /sys/class/firmware/ ]; then echo yes; else echo no; fi)
if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
...@@ -116,4 +117,240 @@ else ...@@ -116,4 +117,240 @@ else
echo "$0: async filesystem loading works" echo "$0: async filesystem loading works"
fi fi
### Batched requests tests
test_config_present()
{
if [ ! -f $DIR/reset ]; then
echo "Configuration triggers not present, ignoring test"
exit 0
fi
}
# Defaults :
#
# send_uevent: 1
# sync_direct: 0
# name: test-firmware.bin
# num_requests: 4
config_reset()
{
echo 1 > $DIR/reset
}
release_all_firmware()
{
echo 1 > $DIR/release_all_firmware
}
config_set_name()
{
echo -n $1 > $DIR/config_name
}
config_set_sync_direct()
{
echo 1 > $DIR/config_sync_direct
}
config_unset_sync_direct()
{
echo 0 > $DIR/config_sync_direct
}
config_set_uevent()
{
echo 1 > $DIR/config_send_uevent
}
config_unset_uevent()
{
echo 0 > $DIR/config_send_uevent
}
config_trigger_sync()
{
echo -n 1 > $DIR/trigger_batched_requests 2>/dev/null
}
config_trigger_async()
{
echo -n 1 > $DIR/trigger_batched_requests_async 2> /dev/null
}
config_set_read_fw_idx()
{
echo -n $1 > $DIR/config_read_fw_idx 2> /dev/null
}
read_firmwares()
{
for i in $(seq 0 3); do
config_set_read_fw_idx $i
# Verify the contents are what we expect.
# -Z required for now -- check for yourself, md5sum
# on $FW and DIR/read_firmware will yield the same. Even
# cmp agrees, so something is off.
if ! diff -q -Z "$FW" $DIR/read_firmware 2>/dev/null ; then
echo "request #$i: firmware was not loaded" >&2
exit 1
fi
done
}
read_firmwares_expect_nofile()
{
for i in $(seq 0 3); do
config_set_read_fw_idx $i
# Ensures contents differ
if diff -q -Z "$FW" $DIR/read_firmware 2>/dev/null ; then
echo "request $i: file was not expected to match" >&2
exit 1
fi
done
}
test_batched_request_firmware_nofile()
{
echo -n "Batched request_firmware() nofile try #$1: "
config_reset
config_set_name nope-test-firmware.bin
config_trigger_sync
read_firmwares_expect_nofile
release_all_firmware
echo "OK"
}
test_batched_request_firmware_direct_nofile()
{
echo -n "Batched request_firmware_direct() nofile try #$1: "
config_reset
config_set_name nope-test-firmware.bin
config_set_sync_direct
config_trigger_sync
release_all_firmware
echo "OK"
}
test_request_firmware_nowait_uevent_nofile()
{
echo -n "Batched request_firmware_nowait(uevent=true) nofile try #$1: "
config_reset
config_set_name nope-test-firmware.bin
config_trigger_async
release_all_firmware
echo "OK"
}
test_wait_and_cancel_custom_load()
{
if [ "$HAS_FW_LOADER_USER_HELPER" != "yes" ]; then
return
fi
local timeout=10
name=$1
while [ ! -e "$DIR"/"$name"/loading ]; do
sleep 0.1
timeout=$(( $timeout - 1 ))
if [ "$timeout" -eq 0 ]; then
echo "firmware interface never appeared:" >&2
echo "$DIR/$name/loading" >&2
exit 1
fi
done
echo -1 >"$DIR"/"$name"/loading
}
test_request_firmware_nowait_custom_nofile()
{
echo -n "Batched request_firmware_nowait(uevent=false) nofile try #$1: "
config_unset_uevent
config_set_name nope-test-firmware.bin
config_trigger_async &
test_wait_and_cancel_custom_load nope-test-firmware.bin
wait
release_all_firmware
echo "OK"
}
test_batched_request_firmware()
{
echo -n "Batched request_firmware() try #$1: "
config_reset
config_trigger_sync
read_firmwares
release_all_firmware
echo "OK"
}
test_batched_request_firmware_direct()
{
echo -n "Batched request_firmware_direct() try #$1: "
config_reset
config_set_sync_direct
config_trigger_sync
release_all_firmware
echo "OK"
}
test_request_firmware_nowait_uevent()
{
echo -n "Batched request_firmware_nowait(uevent=true) try #$1: "
config_reset
config_trigger_async
release_all_firmware
echo "OK"
}
test_request_firmware_nowait_custom()
{
echo -n "Batched request_firmware_nowait(uevent=false) try #$1: "
config_unset_uevent
config_trigger_async
release_all_firmware
echo "OK"
}
# Only continue if batched request triggers are present on the
# test-firmware driver
test_config_present
# test with the file present
echo
echo "Testing with the file present..."
for i in $(seq 1 5); do
test_batched_request_firmware $i
done
for i in $(seq 1 5); do
test_batched_request_firmware_direct $i
done
for i in $(seq 1 5); do
test_request_firmware_nowait_uevent $i
done
for i in $(seq 1 5); do
test_request_firmware_nowait_custom $i
done
# Test for file not found, errors are expected, the failure would be
# a hung task, which would require a hard reset.
echo
echo "Testing with the file missing..."
for i in $(seq 1 5); do
test_batched_request_firmware_nofile $i
done
for i in $(seq 1 5); do
test_batched_request_firmware_direct_nofile $i
done
for i in $(seq 1 5); do
test_request_firmware_nowait_uevent_nofile $i
done
for i in $(seq 1 5); do
test_request_firmware_nowait_custom_nofile $i
done
exit 0 exit 0
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment