All of lore.kernel.org
 help / color / mirror / Atom feed
From: Richard Cheng <icheng@nvidia.com>
To: tony.luck@intel.co, shuah@kernel.org, reinette.chatre@intel.com
Cc: Dave.Martin@arm.com, james.morse@arm.com, babu.moger@amd.com,
	linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org,
	fenghuay@nvidia.com, newtonl@nvidia.com, kristinc@nvidia.com,
	kaihengf@nvidia.com, kobak@nvidia.com, sdonthineni@nvidia.com,
	Richard Cheng <icheng@nvidia.com>
Subject: [PATCH v2 1/2] selftests/resctrl: Add L3_CBM_VALIDATE to check CBM writes
Date: Mon, 10 Aug 2026 17:51:22 +0800	[thread overview]
Message-ID: <20260810095124.32244-2-icheng@nvidia.com> (raw)
In-Reply-To: <20260810095124.32244-1-icheng@nvidia.com>

Add L3_CBM_VALIDATE to verify that resctrl enforces the L3 CBM rules
advertised by cbm_mask and min_cbm_bits.

Confirm that the full mask is accepted. Check the empty mask according
to min_cbm_bits, and confirm that out-of-range and undersized masks are
rejected.

This catches inconsistencies between the advertised capabilities and
schemata validation.

Signed-off-by: Richard Cheng <icheng@nvidia.com>
---
Changelog:

v1 -> v2:
    - Rename L3_CAT_VALIDATE to L3_CBM_VALIDATE
    - Handle empty CBMs according to min_cbm_bits
    - Check count_contiguous_bits() before using its result
    - Use KSFT_FAIL and reverse-fir-tree ordering
    - Use a 64-bit out-of-range mask

Best regards,
Richard Cheng.
---
 tools/testing/selftests/resctrl/cat_test.c    | 91 +++++++++++++++++++
 tools/testing/selftests/resctrl/resctrl.h     |  1 +
 .../testing/selftests/resctrl/resctrl_tests.c |  1 +
 3 files changed, 93 insertions(+)

diff --git a/tools/testing/selftests/resctrl/cat_test.c b/tools/testing/selftests/resctrl/cat_test.c
index 371a2f26dc47..a06c57954740 100644
--- a/tools/testing/selftests/resctrl/cat_test.c
+++ b/tools/testing/selftests/resctrl/cat_test.c
@@ -357,6 +357,89 @@ static bool noncont_cat_feature_check(const struct resctrl_test *test)
 	return resource_info_file_exists(test->resource, "sparse_masks");
 }
 
+/*
+ * L3_CBM_VALIDATE - Verify L3 CBM write validation.
+ *
+ * A full CBM must be accepted. An empty CBM is valid only when min_cbm_bits
+ * is zero. Masks with bits outside cbm_mask or fewer than min_cbm_bits must
+ * be rejected.
+ */
+static int cbm_validate_run_test(const struct resctrl_test *test,
+				 const struct user_params *uparams)
+{
+	unsigned int min_cbm_bits, contiguous_bits;
+	unsigned long long invalid_mask;
+	unsigned int count_of_bits;
+	unsigned long full_mask;
+	unsigned int start;
+	char schemata[64];
+	int ret;
+
+	ret = get_full_cbm(test->resource, &full_mask);
+	if (ret)
+		return ret;
+
+	ret = resource_info_unsigned_get(test->resource, "min_cbm_bits",
+					 &min_cbm_bits);
+	if (ret)
+		return ret;
+
+	count_of_bits = count_bits(full_mask);
+
+	/* A valid full CBM must be accepted. */
+	snprintf(schemata, sizeof(schemata), "%lx", full_mask);
+	if (write_schemata("", schemata, uparams->cpu, test->resource)) {
+		ksft_print_msg("Valid CBM 0x%lx was rejected\n", full_mask);
+		return KSFT_FAIL;
+	}
+
+	ret = write_schemata("", "0", uparams->cpu, test->resource);
+	if (min_cbm_bits && !ret) {
+		ksft_print_msg("Empty CBM was accepted, must be rejected\n");
+		return KSFT_FAIL;
+	}
+	if (!min_cbm_bits && ret) {
+		ksft_print_msg("Empty CBM was rejected, must be accepted\n");
+		return KSFT_FAIL;
+	}
+
+	/* A mask with a bit outside cbm_mask must be rejected. */
+	invalid_mask = (unsigned long long)full_mask | (1ULL << count_of_bits);
+	snprintf(schemata, sizeof(schemata), "%llx", invalid_mask);
+	if (!write_schemata("", schemata, uparams->cpu, test->resource)) {
+		ksft_print_msg("Out-of-range CBM 0x%llx was accepted, must be rejected\n",
+			       invalid_mask);
+		return KSFT_FAIL;
+	}
+
+	/*
+	 * When min_cbm_bits is greater than one, a non-empty mask with fewer
+	 * bits must be rejected.
+	 */
+	if (min_cbm_bits > 1) {
+		contiguous_bits = count_contiguous_bits(full_mask, &start);
+		if (contiguous_bits < min_cbm_bits) {
+			ksft_print_msg("Full CBM has %u contiguous bits, fewer than "
+				       "min_cbm_bits=%u\n",
+				       contiguous_bits, min_cbm_bits);
+			return KSFT_FAIL;
+		}
+
+		invalid_mask = create_bit_mask(start, min_cbm_bits - 1);
+		snprintf(schemata, sizeof(schemata), "%llx", invalid_mask);
+		if (!write_schemata("", schemata, uparams->cpu,
+				    test->resource)) {
+			ksft_print_msg("CBM 0x%llx with too few bits was accepted\n",
+				       invalid_mask);
+			return KSFT_FAIL;
+		}
+	}
+
+	ksft_print_msg("Pass: L3 CBM writes were validated correctly\n");
+
+	return 0;
+}
+
 struct resctrl_test l3_cat_test = {
 	.name = "L3_CAT",
 	.group = "CAT",
@@ -366,6 +449,14 @@ struct resctrl_test l3_cat_test = {
 	.cleanup = cat_test_cleanup,
 };
 
+struct resctrl_test l3_cbm_validate_test = {
+	.name = "L3_CBM_VALIDATE",
+	.group = "CAT",
+	.resource = "L3",
+	.feature_check = test_resource_feature_check,
+	.run_test = cbm_validate_run_test,
+};
+
 struct resctrl_test l3_noncont_cat_test = {
 	.name = "L3_NONCONT_CAT",
 	.group = "CAT",
diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h
index 175101022bf3..a6fc688ed997 100644
--- a/tools/testing/selftests/resctrl/resctrl.h
+++ b/tools/testing/selftests/resctrl/resctrl.h
@@ -240,6 +240,7 @@ extern struct resctrl_test mbm_test;
 extern struct resctrl_test mba_test;
 extern struct resctrl_test cmt_test;
 extern struct resctrl_test l3_cat_test;
+extern struct resctrl_test l3_cbm_validate_test;
 extern struct resctrl_test l3_noncont_cat_test;
 extern struct resctrl_test l2_noncont_cat_test;
 
diff --git a/tools/testing/selftests/resctrl/resctrl_tests.c b/tools/testing/selftests/resctrl/resctrl_tests.c
index dbcd5eea9fbc..57a4d0815b67 100644
--- a/tools/testing/selftests/resctrl/resctrl_tests.c
+++ b/tools/testing/selftests/resctrl/resctrl_tests.c
@@ -19,6 +19,7 @@ static struct resctrl_test *resctrl_tests[] = {
 	&mba_test,
 	&cmt_test,
 	&l3_cat_test,
+	&l3_cbm_validate_test,
 	&l3_noncont_cat_test,
 	&l2_noncont_cat_test,
 };
-- 
2.53.0


  reply	other threads:[~2026-08-10  9:51 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-10  9:51 [PATCH v2 0/2] selftests/resctrl: Increase L3 cache test coverage Richard Cheng
2026-08-10  9:51 ` Richard Cheng [this message]
2026-08-10  9:51 ` [PATCH v2 2/2] selftests/resctrl: Add L3_BIT_USAGE to check allocation reporting Richard Cheng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260810095124.32244-2-icheng@nvidia.com \
    --to=icheng@nvidia.com \
    --cc=Dave.Martin@arm.com \
    --cc=babu.moger@amd.com \
    --cc=fenghuay@nvidia.com \
    --cc=james.morse@arm.com \
    --cc=kaihengf@nvidia.com \
    --cc=kobak@nvidia.com \
    --cc=kristinc@nvidia.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=newtonl@nvidia.com \
    --cc=reinette.chatre@intel.com \
    --cc=sdonthineni@nvidia.com \
    --cc=shuah@kernel.org \
    --cc=tony.luck@intel.co \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.