Skip to content

Commit

Permalink
t/zbd: set mq-deadline scheduler to device-mapper destination devices
Browse files Browse the repository at this point in the history
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 <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Vincent Fu <[email protected]>
  • Loading branch information
kawasaki authored and vincentkfu committed Sep 26, 2023
1 parent a142e0d commit 996ac91
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 1 deletion.
11 changes: 11 additions & 0 deletions t/zbd/functions
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
61 changes: 60 additions & 1 deletion t/zbd/test-zbd-support
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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() {
Expand Down

0 comments on commit 996ac91

Please sign in to comment.