[RFC PATCH blktests v1] nvme: check user queue limits across namespace rescans
Yao Sang <[email protected]>
| Newsgroups | org.infradead.lists.linux-nvme |
|---|---|
| Message-ID | <[email protected]> |
NVMe namespace rescans should not reset queue user caps on the namespace head. Add a regression test that lowers max_sectors_kb, optionally lowers discard_max_bytes, optionally disables write_zeroes_unmap_max_bytes, runs nvme ns-rescan, and verifies that the user values are preserved. Mark the test as zoned-capable so it can run on ZNS devices as well. Signed-off-by: Yao Sang <[email protected]> --- tests/nvme/068 | 151 +++++++++++++++++++++++++++++++++++++++++++++ tests/nvme/068.out | 2 + 2 files changed, 153 insertions(+) create mode 100755 tests/nvme/068 create mode 100644 tests/nvme/068.out diff --git a/tests/nvme/068 b/tests/nvme/068 new file mode 100755 index 0000000..a7786db --- /dev/null +++ b/tests/nvme/068 @@ -0,0 +1,151 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-3.0+ +# +# Test queue user limits across NVMe namespace rescans. + +. tests/nvme/rc + +DESCRIPTION="check queue user limits across NVMe namespace rescans" +QUICK=1 +CAN_BE_ZONED=1 + +requires() { + _nvme_requires + _have_program nvme +} + +_test_dev_nvme_ctrl_dev() { + local ctrl + + ctrl="$(_nvme_get_ctrl_list | head -n 1)" + if [[ -z "$ctrl" ]]; then + return 1 + fi + + echo "/dev/$(basename "$ctrl")" +} + +device_requires() { + local ctrl_dev + + _require_test_dev_is_nvme + _require_test_dev_sysfs queue/max_sectors_kb queue/max_hw_sectors_kb + + if ! ctrl_dev="$(_test_dev_nvme_ctrl_dev)"; then + SKIP_REASONS+=("unable to find NVMe controller for $TEST_DEV") + return 1 + fi + if [[ ! -c "$ctrl_dev" ]]; then + SKIP_REASONS+=("$ctrl_dev is not a character device") + return 1 + fi +} + +_cleanup_queue_limits() { + if [[ -z "${nvme068_queue_path:-}" ]]; then + return + fi + + echo "$nvme068_max_sectors_kb" > "$nvme068_queue_path/max_sectors_kb" + if [[ -n "${nvme068_discard_max_bytes:-}" ]]; then + echo "$nvme068_discard_max_bytes" > \ + "$nvme068_queue_path/discard_max_bytes" + fi + if [[ -n "${nvme068_wzeroes_unmap_max_bytes:-}" ]]; then + echo "$nvme068_wzeroes_unmap_max_bytes" > \ + "$nvme068_queue_path/write_zeroes_unmap_max_bytes" + fi +} + +_check_queue_limit() { + local queue_path=$1 + local attr=$2 + local expected=$3 + local actual + + actual="$(cat "$queue_path/$attr")" + if [[ "$actual" -ne "$expected" ]]; then + echo "ERROR: $attr changed from $expected to $actual" + fi +} + +test_device() { + local queue_path="$TEST_DEV_SYSFS/queue" + local ctrl_dev + local max_hw_sectors_kb + local max_sectors_kb + local discard_hw_bytes + local discard_granularity + local discard_max_bytes="" + local wzeroes_unmap_hw_bytes + local wzeroes_unmap_max_bytes="" + + echo "Running ${TEST_NAME}" + + ctrl_dev="$(_test_dev_nvme_ctrl_dev)" + nvme068_queue_path="$queue_path" + nvme068_max_sectors_kb="$(cat "$queue_path/max_sectors_kb")" + nvme068_discard_max_bytes="" + nvme068_wzeroes_unmap_max_bytes="" + _register_test_cleanup _cleanup_queue_limits + + max_hw_sectors_kb="$(cat "$queue_path/max_hw_sectors_kb")" + max_sectors_kb=$((max_hw_sectors_kb / 2)) + if ((max_sectors_kb == 0)); then + max_sectors_kb=1 + fi + + if [[ -e "$queue_path/discard_max_bytes" && + -e "$queue_path/discard_max_hw_bytes" && + -e "$queue_path/discard_granularity" ]]; then + nvme068_discard_max_bytes="$(cat "$queue_path/discard_max_bytes")" + if echo "$nvme068_discard_max_bytes" > \ + "$queue_path/discard_max_bytes" 2>/dev/null; then + discard_hw_bytes="$(cat "$queue_path/discard_max_hw_bytes")" + discard_granularity="$(cat "$queue_path/discard_granularity")" + if ((discard_granularity > 0 && + discard_hw_bytes >= discard_granularity * 2)); then + discard_max_bytes=$(((discard_hw_bytes / 2) / + discard_granularity * discard_granularity)) + fi + else + nvme068_discard_max_bytes="" + fi + fi + + if [[ -e "$queue_path/write_zeroes_unmap_max_bytes" && + -e "$queue_path/write_zeroes_unmap_max_hw_bytes" ]]; then + nvme068_wzeroes_unmap_max_bytes="$(<"$queue_path/write_zeroes_unmap_max_bytes")" + wzeroes_unmap_hw_bytes="$(<"$queue_path/write_zeroes_unmap_max_hw_bytes")" + if ((wzeroes_unmap_hw_bytes > 0)); then + wzeroes_unmap_max_bytes=0 + fi + fi + + echo "$max_sectors_kb" > "$queue_path/max_sectors_kb" + if [[ -n "$discard_max_bytes" ]]; then + echo "$discard_max_bytes" > "$queue_path/discard_max_bytes" + fi + if [[ -n "$wzeroes_unmap_max_bytes" ]]; then + echo "$wzeroes_unmap_max_bytes" > \ + "$queue_path/write_zeroes_unmap_max_bytes" + fi + + if ! nvme ns-rescan "$ctrl_dev" >> "$FULL" 2>&1; then + echo "ERROR: ns-rescan failed" + fi + + _check_queue_limit "$queue_path" max_sectors_kb "$max_sectors_kb" + if [[ -n "$discard_max_bytes" ]]; then + _check_queue_limit "$queue_path" discard_max_bytes \ + "$discard_max_bytes" + fi + if [[ -n "$wzeroes_unmap_max_bytes" ]]; then + _check_queue_limit "$queue_path" write_zeroes_unmap_max_bytes \ + "$wzeroes_unmap_max_bytes" + fi + + _cleanup_queue_limits + + echo "Test complete" +} diff --git a/tests/nvme/068.out b/tests/nvme/068.out new file mode 100644 index 0000000..28407c6 --- /dev/null +++ b/tests/nvme/068.out @@ -0,0 +1,2 @@ +Running nvme/068 +Test complete -- 2.25.1