From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from 011.lax.mailroute.net (011.lax.mailroute.net [199.89.1.14]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 75E0072603 for ; Wed, 3 Jun 2026 20:50:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=199.89.1.14 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780519831; cv=none; b=VNECWMITy2GGCFRr3kTRs481H+DHLsiD5KV3uHOuKDLgy9k1/mTdeOzwkPt+z2unTb5n3dTqFsDAO/1oQQFSc8x1z+Y/E54amE9Otd6eZPd3WGe+SEBgfwuWe7rGzBcEQGr2f9D670FY/rJUdgkFeEgbdXw7/aoXtWtslg6AYJE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780519831; c=relaxed/simple; bh=uompo60iwQOtWpXlrHzE2THVdlpVUKEPDfzH7BWrsxI=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=CVpOpn7IUogqO5lCgPGqZGmltCxR/fyuejE7lSVEjWVkWUvAGI12VAlUAbjJaJHU9GAwsFzu8QbbJmIKN0/b8NCpOrm27kTAiBtzHdSxhIiC80uWPM1d8DBDUzsAhWVvfVPJNagZNHTWmHFSCIdYG0Q+3OMibOsOVHCvlxHdcug= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=acm.org; spf=pass smtp.mailfrom=acm.org; dkim=pass (2048-bit key) header.d=acm.org header.i=@acm.org header.b=WnM8lya/; arc=none smtp.client-ip=199.89.1.14 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=acm.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=acm.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=acm.org header.i=@acm.org header.b="WnM8lya/" Received: from localhost (localhost [127.0.0.1]) by 011.lax.mailroute.net (Postfix) with ESMTP id 4gW0Fr4PhVz1XM0pG; Wed, 3 Jun 2026 20:50:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=acm.org; h= content-transfer-encoding:mime-version:x-mailer:message-id:date :date:subject:subject:from:from:received:received; s=mr01; t= 1780519820; x=1783111821; bh=cb1lbaPnO6aaEWyf/wH1MQHWWmur3nFBSTG LC8HJT6k=; b=WnM8lya/Sey/Bs5Y3f+MmmPF4TS2KrywuLZsyLpriCSmmIwxYse pLsqcRO8fyyxkjpvj1skmw3eJJjfauwwkZzM1HRK/EwH+1xvV4/b1LLGWJxnTZ+Y Amg95jopG28vX1dMJrgSPeYE7Yw3nimwgNwYvRjlkahjK7sr3OuteqYX7Gi2gRUe XdoQM6/l12zMp26MY7BsNm2joGkHAUnwTp719zQ5rGPlf9SAGe8bsAZJjFcdvTfp EtFAWWi4wOTXcz2/stQ2h8JRlQ09a51DpWnqpkK2OkwQMuocyR5O7vCR1ft4lReH qPgypIYgymNRd29ZuDUCtucmGs81L2ji7cQ== X-Virus-Scanned: by MailRoute Received: from 011.lax.mailroute.net ([127.0.0.1]) by localhost (011.lax [127.0.0.1]) (mroute_mailscanner, port 10029) with LMTP id o3yKNKvhrEnZ; Wed, 3 Jun 2026 20:50:20 +0000 (UTC) Received: from bvanassche.mtv.corp.google.com (unknown [104.135.180.219]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: bvanassche@acm.org) by 011.lax.mailroute.net (Postfix) with ESMTPSA id 4gW0Fl3J1rz1XMFjJ; Wed, 3 Jun 2026 20:50:19 +0000 (UTC) From: Bart Van Assche To: Shin'ichiro Kawasaki Cc: Damien Le Moal , linux-block@vger.kernel.org, Bart Van Assche Subject: [PATCH blktests] throtl/008: Add a test for the iocost cgroup controller Date: Wed, 3 Jun 2026 13:50:07 -0700 Message-ID: <20260603205007.2654971-1-bvanassche@acm.org> X-Mailer: git-send-email 2.54.0.1032.g2f8565e1d1-goog Precedence: bulk X-Mailing-List: linux-block@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Add a test for read and write IOPS throttling. The test implementation has been generated by Antigravity and Gemini with a few manual edits. Signed-off-by: Bart Van Assche --- tests/throtl/008 | 152 +++++++++++++++++++++++++++++++++++++++++++ tests/throtl/008.out | 2 + 2 files changed, 154 insertions(+) create mode 100755 tests/throtl/008 create mode 100644 tests/throtl/008.out diff --git a/tests/throtl/008 b/tests/throtl/008 new file mode 100755 index 000000000000..0570fc0188e0 --- /dev/null +++ b/tests/throtl/008 @@ -0,0 +1,152 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-3.0+ +# Copyright (C) 2026 Google LLC +# +# Test cgroup iocost IOPS limiting. + +. tests/block/rc +. common/null_blk +. common/cgroup +. common/fio + +DESCRIPTION=3D"test cgroup iocost controller limits" + +requires() { + _have_cgroup2_controller io + _have_null_blk + _have_fio + _have_program bc + if [[ ! -e "$(_cgroup2_base_dir)/io.cost.qos" ]]; then + SKIP_REASONS+=3D("iocost controller not supported (CONFIG_BLK_CGROUP_I= OCOST)") + return 1 + fi +} + +test() { + echo "Running ${TEST_NAME}" + + # Create a null_blk instance + local null_blk_params=3D( + blocksize=3D4096 + completion_nsec=3D0 + memory_backed=3D0 + size=3D1024 # MB + submit_queues=3D1 + power=3D1 + ) + _init_null_blk nr_devices=3D0 queue_mode=3D2 && + if ! _configure_null_blk nullb0 "${null_blk_params[@]}"; then + echo "Configuring null_blk failed" + return 1 + fi + + local dev_t + dev_t=3D$( "$(_cgroup2_base_dir)/cgroup.subtree_control"; then + echo "Failed to enable io controller on cgroup root" + _exit_cgroup2 + _exit_null_blk + return 1 + fi + deactivate_io_ctrlr=3Dtrue + fi + + if ! echo "+io" > "$CGROUP2_DIR/cgroup.subtree_control"; then + echo "Failed to enable io controller on $CGROUP2_DIR" + if [[ $deactivate_io_ctrlr =3D=3D true ]]; then + echo "-io" > "$(_cgroup2_base_dir)/cgroup.subtree_control" + fi + _exit_cgroup2 + _exit_null_blk + return 1 + fi + + # Configure iocost controller globally for the device + # min=3D100.00 max=3D100.00 forces vrate to be fixed at 100% + if ! echo "$dev_t enable=3D1 min=3D100.00 max=3D100.00" > "$(_cgroup2_b= ase_dir)/io.cost.qos"; then + echo "Failed to configure io.cost.qos" + if [[ $deactivate_io_ctrlr =3D=3D true ]]; then + echo "-io" > "$(_cgroup2_base_dir)/cgroup.subtree_control" + fi + _exit_cgroup2 + _exit_null_blk + return 1 + fi + + # Limit read iops to 100 and write iops to 10. + # Setting rbps/wbps to 0 means they are ignored (costs calculated purel= y based on IOPS) + if ! echo "$dev_t ctrl=3Duser model=3Dlinear rbps=3D0 rseqiops=3D100 rr= andiops=3D100 wbps=3D0 wseqiops=3D10 wrandiops=3D10" > "$(_cgroup2_base_d= ir)/io.cost.model"; then + echo "Failed to configure io.cost.model" + echo "$dev_t enable=3D0" > "$(_cgroup2_base_dir)/io.cost.qos" + if [[ $deactivate_io_ctrlr =3D=3D true ]]; then + echo "-io" > "$(_cgroup2_base_dir)/cgroup.subtree_control" + fi + _exit_cgroup2 + _exit_null_blk + return 1 + fi + + # Create a child cgroup for test + local cg_name=3D"testgrp" + local cg_path=3D"$CGROUP2_DIR/$cg_name" + mkdir "$cg_path" + + # 1. Run FIO read test + local -a FIO_PERF_FIELDS + FIO_PERF_FIELDS=3D("read iops") + if ! _fio_perf --bs=3D4k --rw=3Drandread --name=3Dread-test --filename=3D= /dev/nullb0 \ + --ioengine=3Dlibaio --direct=3D1 --iodepth=3D64 --time_based --runtim= e=3D10 \ + --cgroup=3D"blktests/$cg_name" > /dev/null 2>&1; then + echo "FIO read test failed" + else + local read_iops=3D${TEST_RUN["read iops"]} + if [[ -z $read_iops ]]; then + echo "Read IOPS is empty" + elif (( "$(echo "$read_iops < 90 || $read_iops > 110" | bc -l)" )); th= en + echo "Read IOPS $read_iops not in expected range [90, 110]" + fi + fi + + # 2. Run FIO write test + FIO_PERF_FIELDS=3D("write iops") + if ! _fio_perf --bs=3D4k --rw=3Drandwrite --name=3Dwrite-test --filenam= e=3D/dev/nullb0 \ + --ioengine=3Dlibaio --direct=3D1 --iodepth=3D64 --time_based --runtim= e=3D10 \ + --cgroup=3D"blktests/$cg_name" > /dev/null 2>&1; then + echo "FIO write test failed" + else + local write_iops=3D${TEST_RUN["write iops"]} + if [[ -z $write_iops ]]; then + echo "Write IOPS is empty" + elif (( "$(echo "$write_iops < 8 || $write_iops > 12" | bc -l)" )); th= en + echo "Write IOPS $write_iops not in expected range [8, 12]" + fi + fi + + # Clean up cgroups + rmdir "$cg_path" + if [[ $deactivate_io_ctrlr =3D=3D true ]]; then + { echo "-io" > "$(_cgroup2_base_dir)/cgroup.subtree_control"; } &> "${= FULL}" + fi + _exit_cgroup2 + + # Clean up null_blk + _exit_null_blk + + echo "Test complete" +} diff --git a/tests/throtl/008.out b/tests/throtl/008.out new file mode 100644 index 000000000000..890ff7f226d1 --- /dev/null +++ b/tests/throtl/008.out @@ -0,0 +1,2 @@ +Running throtl/008 +Test complete