aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>2023-09-13 10:52:49 +0900
committerVincent Fu <vincent.fu@samsung.com>2023-09-26 09:00:13 -0400
commit996ac91f54844e63ef43092472fc1f7610567b67 (patch)
tree3f48313af8a82faa9351e8f3c926aaf991b2ff67
parenta142e0df6c1483a76d92ff7f9d8c07242af9910e (diff)
downloadfio-996ac91f54844e63ef43092472fc1f7610567b67.tar.gz
t/zbd: set mq-deadline scheduler to device-mapper destination devices
When write workloads run on zoned block devices, mq-deadline scheduler is required to ensure write operations are sequential. To fulfill this requirement, the test script t/zbd/test-zbd-support sets mq-deadline to the sysfs attribute "queue/scheduler". However, this preparation does not work when the write target device is a bio based device-mapper device. The device is bio based then I/O scheduler does not work. Setting mq-deadline to the sysfs attribute has no effect. On top of that, the sysfs attribute "queue/scheduler" is no longer available for bio based device-mapper devices since Linux kernel version v6.5. To ensure mq-deadline scheduler for bio based device-mapper devices, improve the helper function set_io_scheduler. If the sysfs attribute "queue/scheduler" is available, use it. Otherwise, check if the test device is a zoned device-mapper (linear, flakey or crypt). If so, set mq-deadline scheduler to destination devices of the device-mapper device. To implement these, add some helper functions. Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com> Link: https://lore.kernel.org/r/20230913015249.2226799-1-shinichiro.kawasaki@wdc.com Signed-off-by: Vincent Fu <vincent.fu@samsung.com>
-rw-r--r--t/zbd/functions11
-rwxr-xr-xt/zbd/test-zbd-support61
2 files changed, 71 insertions, 1 deletions
diff --git a/t/zbd/functions b/t/zbd/functions
index 4faa45a92..028df4040 100644
--- a/t/zbd/functions
+++ b/t/zbd/functions
@@ -27,6 +27,17 @@ blkzone_reports_capacity() {
"${blkzone}" report -c 1 -o 0 "${dev}" | grep -q 'cap '
}
+has_command() {
+ local cmd="${1}"
+
+ cmd_path=$(type -p "${cmd}" 2>/dev/null)
+ if [ -z "${cmd_path}" ]; then
+ echo "${cmd} is not available"
+ return 1
+ fi
+ return 0
+}
+
# Whether or not $1 (/dev/...) is a NVME ZNS device.
is_nvme_zns() {
local s
diff --git a/t/zbd/test-zbd-support b/t/zbd/test-zbd-support
index c8f3eb614..0436d319d 100755
--- a/t/zbd/test-zbd-support
+++ b/t/zbd/test-zbd-support
@@ -46,6 +46,55 @@ ioengine() {
fi
}
+get_dev_path_by_id() {
+ for d in /sys/block/* /sys/block/*/*; do
+ if [[ ! -r "${d}/dev" ]]; then
+ continue
+ fi
+ if [[ "${1}" == "$(<"${d}/dev")" ]]; then
+ echo "/dev/${d##*/}"
+ return 0
+ fi
+ done
+ return 1
+}
+
+dm_destination_dev_set_io_scheduler() {
+ local dev=$1 sched=$2
+ local dest_dev_id dest_dev path
+
+ has_command dmsetup || return 1
+
+ while read -r dest_dev_id; do
+ if ! dest_dev=$(get_dev_path_by_id "${dest_dev_id}"); then
+ continue
+ fi
+ path=${dest_dev/dev/sys\/block}/queue/scheduler
+ if [[ ! -w ${path} ]]; then
+ echo "Can not set scheduler of device mapper destination: ${dest_dev}"
+ continue
+ fi
+ echo "${2}" > "${path}"
+ done < <(dmsetup table "$(<"/sys/block/$dev/dm/name")" |
+ sed -n 's/.* \([0-9]*:[0-9]*\).*/\1/p')
+}
+
+dev_has_dm_map() {
+ local dev=${1} target_type=${2}
+ local dm_name
+
+ has_command dmsetup || return 1
+
+ dm_name=$(<"/sys/block/$dev/dm/name")
+ if ! dmsetup status "${dm_name}" | grep -qe "${target_type}"; then
+ return 1
+ fi
+ if dmsetup status "${dm_name}" | grep -v "${target_type}"; then
+ return 1
+ fi
+ return 0
+}
+
set_io_scheduler() {
local dev=$1 sched=$2
@@ -62,7 +111,17 @@ set_io_scheduler() {
esac
fi
- echo "$sched" >"/sys/block/$dev/queue/scheduler"
+ if [ -w "/sys/block/$dev/queue/scheduler" ]; then
+ echo "$sched" >"/sys/block/$dev/queue/scheduler"
+ elif [ -r "/sys/block/$dev/dm/name" ] &&
+ ( dev_has_dm_map "$dev" linear ||
+ dev_has_dm_map "$dev" flakey ||
+ dev_has_dm_map "$dev" crypt ); then
+ dm_destination_dev_set_io_scheduler "$dev" "$sched"
+ else
+ echo "can not set io scheduler"
+ exit 1
+ fi
}
check_read() {