Re: [PATCH 2/3] selftests/resctrl: Add L3_CAT_VALIDATE to check invalid CBMs

Reinette Chatre <[email protected]>
Newsgroups gmane.linux.kernel
Message-ID <[email protected]>
Hi Richard,

Thank you very much. This is useful.

On 6/8/26 4:06 AM, Richard Cheng wrote:
> A CAT allocation is a CBM, and the kernel must refuse masks that can't
> describe a valid allocation. Nothing in the suite check this.
> 
> Implement L3_CAT_VALIDATE, first confirm a valid full mask is accepted,

How about "L3_CBM_VALIDATE"?

> then write an empty mask and a mask with bits outside cbm_mask and
> confirm each is refused. A mask below min_cbm_bits is also checked where

The empty mask is not always a valid test (more below).

> the platform needs more than one bit.
(nit: please write changelog in imperative tone)

> 
> Signed-off-by: Richard Cheng <[email protected]>
> ---
>  tools/testing/selftests/resctrl/cat_test.c    | 79 +++++++++++++++++++
>  tools/testing/selftests/resctrl/resctrl.h     |  1 +
>  .../testing/selftests/resctrl/resctrl_tests.c |  1 +
>  3 files changed, 81 insertions(+)
> 
> diff --git a/tools/testing/selftests/resctrl/cat_test.c b/tools/testing/selftests/resctrl/cat_test.c
> index 16a947f1ed16..d236988916d9 100644
> --- a/tools/testing/selftests/resctrl/cat_test.c
> +++ b/tools/testing/selftests/resctrl/cat_test.c
> @@ -603,3 +603,82 @@ struct resctrl_test l3_cat_occup_test = {
>  	.run_test = cat_occup_run_test,
>  	.cleanup = cat_occup_test_cleanup,
>  };
> +
> +/*
> + * L3_CAT_VALIDATE - Verify the kernel rejects invalid L3 CBM writes.
> + *
> + * CAT allocation accepts a Capacity Bit Mask (CBM). The kernel must reject
> + * masks that cannot represent a valid allocation: an empty mask, a mask with
> + * bits outside cbm_mask, or (where the platform requires it) a mask with
> + * fewer than min_cbm_bits bits. A rejected schemata write makes
> + * write_schemata() return non-zero, which is the signal this test checks.
> + */
> +static int cat_validate_run_test(const struct resctrl_test *test,

All tests in this file are "cat" tests so this function name could be more
specific. How about "cbm_validate_run_test()"?

> +				 const struct user_params *uparams)
> +{
> +	unsigned long full_mask, bad_mask;
> +	unsigned int min_cbm_bits, start;
> +	char schemata[64];
> +	int count_of_bits, ret;

(reverse fir please)

> +
> +	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 1;

KSFT_FAIL?

> +	}
> +
> +	/* An empty mask must be rejected. */

Some systems do support an empty mask (AMD) so this needs to depend on min_cbm_bits
being larger than zero.

> +	if (!write_schemata("", "0", uparams->cpu, test->resource)) {
> +		ksft_print_msg("Empty CBM was accepted, must be rejected\n");
> +		return 1;
> +	}
> +
> +	/* A mask with a bit outside cbm_mask must be rejected. */
> +	bad_mask = full_mask | (1UL << count_of_bits);
> +	snprintf(schemata, sizeof(schemata), "%lx", bad_mask);
> +	if (!write_schemata("", schemata, uparams->cpu, test->resource)) {
> +		ksft_print_msg("Out-of-range CBM 0x%lx was accepted, must be rejected\n",
> +			       bad_mask);
> +		return 1;

KSFT_FAIL?

> +	}
> +
> +	/*
> +	 * A mask with fewer than min_cbm_bits bits must be rejected. When
> +	 * min_cbm_bits is 1 the only sub-minimum mask is the empty mask
> +	 * This case only applies when the platform requires more contiguous bits.
> +	 */
> +	if (min_cbm_bits > 1) {
> +		count_contiguous_bits(full_mask, &start);

The return value should be checked here to ensure that the create_bit_mask() below 
is valid.

> +		bad_mask = create_bit_mask(start, min_cbm_bits - 1);
> +		snprintf(schemata, sizeof(schemata), "%lx", bad_mask);
> +		if (!write_schemata("", schemata, uparams->cpu, test->resource)) {
> +			ksft_print_msg("CBM 0x%lx with too few bits was accepted\n",
> +				       bad_mask);
> +			return 1;

KSFT_FAIL?

> +		}
> +	}
> +
> +	ksft_print_msg("Pass: CAT rejects invalid CBM writes\n");
> +
> +	return 0;
> +}
> +
> +struct resctrl_test l3_cat_validate_test = {
> +	.name = "L3_CAT_VALIDATE",
> +	.group = "CAT",
> +	.resource = "L3",
> +	.feature_check = test_resource_feature_check,
> +	.run_test = cat_validate_run_test,
> +};
> diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h
> index ce3abf0bdac2..e2e3cf7833bc 100644
> --- a/tools/testing/selftests/resctrl/resctrl.h
> +++ b/tools/testing/selftests/resctrl/resctrl.h
> @@ -248,6 +248,7 @@ extern struct resctrl_test mba_test;
>  extern struct resctrl_test cmt_test;
>  extern struct resctrl_test l3_cat_test;
>  extern struct resctrl_test l3_cat_occup_test;
> +extern struct resctrl_test l3_cat_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 324a60818aa1..66739e96f33c 100644
> --- a/tools/testing/selftests/resctrl/resctrl_tests.c
> +++ b/tools/testing/selftests/resctrl/resctrl_tests.c
> @@ -20,6 +20,7 @@ static struct resctrl_test *resctrl_tests[] = {
>  	&cmt_test,
>  	&l3_cat_test,
>  	&l3_cat_occup_test,
> +	&l3_cat_validate_test,
>  	&l3_noncont_cat_test,
>  	&l2_noncont_cat_test,
>  };

Thank you.

Reinette
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.