t/zbd: check device for unrestricted read support
authorDmitry Fomichev <dmitry.fomichev@wdc.com>
Tue, 6 Feb 2024 10:57:54 +0000 (19:57 +0900)
committerVincent Fu <vincent.fu@samsung.com>
Wed, 7 Feb 2024 13:43:13 +0000 (08:43 -0500)
ZBD unit tests in t/zbd/test-zbd-support currently assume that the
drive that is being tested supports unrestricted reads, i.e. reads
that (partially or entirely) occur above the write pointer. This is
always the case with ZBD core code because Linux kernel rejects zoned
devices with restricted reads. However, libzbc ioengine does support
such devices.

The restricted/unrestricted reads feature is controlled by URSWRZ
device bit ("Unrestricted Reads of Sequential Write Required Zones")
which, depending on the device design, can be hard-coded to be reported
as 1 or 0 or it can be made configurable via MODE SET or SET FEATURES
commands. The unit tests need to behave correctly with any URSWRZ bit
value reported by the device if libzbc ioengine is used for testing.

Test #4 in the test script currently expects the device to have
unrestricted SWR zone reads. This test is guaranteed to fail if
the script is run against a drive that reports URSWRZ=0 with libzbc
ioengine.

Check if the drive has unrestricted read support disabled and process
the outcome of test #4 accordingly.

Signed-off-by: Dmitry Fomichev <dmitry.fomichev@wdc.com>
Reviewed-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Tested-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Link: https://lore.kernel.org/r/20240206105755.214891-5-dmitry.fomichev@wdc.com
Signed-off-by: Vincent Fu <vincent.fu@samsung.com>
t/zbd/functions
t/zbd/test-zbd-support

index 028df4040e626a5f2823d84bd36a158996fd0f84..7734371e5e065dae8a487c28c3bb9e865261aa80 100644 (file)
@@ -290,6 +290,28 @@ min_seq_write_size() {
        fi
 }
 
+urswrz() {
+    local dev=$1
+
+    if [ -n "${sg_inq}" ] && [ ! -n "${use_libzbc}" ]; then
+       if ! ${sg_inq} -e --page=0xB6 --len=10 --hex "$dev" \
+                > /dev/null 2>&1; then
+           # Couldn't get URSWRZ bit. Assume the reads are unrestricted
+           # because this configuration is more common.
+           echo 1
+       else
+           ${sg_inq} -e --page=0xB6 --len=10 --hex "$dev" | tail -1 |
+               {
+                   read -r offset b0 b1 b2 b3 b4 trailer && \
+                       echo $(( $b4 & 0x01 )) || echo 0
+               }
+       fi
+    else
+       ${zbc_info} "$dev" |
+           sed -n 's/^[[:blank:]].*Read commands are \(un\)restricted*/\1/p' | grep -q ^ && echo 1 || echo 0
+    fi
+}
+
 is_zbc() {
        local dev=$1
 
index 532860ebc86d6b59300fcbb6c3f0515316065ba8..defb36527b80d8a58d9a9bd20193d4e635f1bca9 100755 (executable)
@@ -412,8 +412,16 @@ test4() {
     opts+=("--size=$size" "--thread=1" "--read_beyond_wp=1")
     opts+=("$(ioengine "psync")" "--rw=read" "--direct=1" "--disable_lat=1")
     opts+=("--zonemode=zbd" "--zonesize=${zone_size}")
-    run_fio "${opts[@]}" >> "${logfile}.${test_number}" 2>&1 || return $?
-    check_read $size || return $?
+    run_fio "${opts[@]}" >> "${logfile}.${test_number}" 2>&1
+    fio_rc=$?
+    if [[ $unrestricted_reads != 0 ]]; then
+       if [[ $fio_rc != 0 ]]; then
+               return "$fio_rc"
+       fi
+       check_read $size || return $?
+    else
+        [ $fio_rc == 0 ] && return 1 || return 0
+    fi
 }
 
 # Sequential write to sequential zones.
@@ -1664,6 +1672,7 @@ if [[ -b "$realdev" ]]; then
                first_sequential_zone_sector=${result[0]}
                sectors_per_zone=${result[1]}
                zone_size=$((sectors_per_zone * 512))
+               unrestricted_reads=$(urswrz "$dev")
                if ! max_open_zones=$(max_open_zones "$dev"); then
                        echo "Failed to determine maximum number of open zones"
                        exit 1
@@ -1681,6 +1690,7 @@ if [[ -b "$realdev" ]]; then
                sectors_per_zone=$((zone_size / 512))
                max_open_zones=128
                max_active_zones=0
+               unrestricted_reads=1
                set_io_scheduler "$basename" none || exit $?
                ;;
        esac
@@ -1712,6 +1722,7 @@ elif [[ -c "$realdev" ]]; then
        first_sequential_zone_sector=${result[0]}
        sectors_per_zone=${result[1]}
        zone_size=$((sectors_per_zone * 512))
+       unrestricted_reads=$(urswrz "$dev")
        if ! max_open_zones=$(max_open_zones "$dev"); then
                echo "Failed to determine maximum number of open zones"
                exit 1