Skip to content

Commit ae63855

Browse files
maciejwieczorretmanshuahkh
authored andcommitted
selftests/resctrl: Add non-contiguous CBMs CAT test
Add tests for both L2 and L3 CAT to verify the return values generated by writing non-contiguous CBMs don't contradict the reported non-contiguous support information. Use a logical XOR to confirm return value of write_schemata() and non-contiguous CBMs support information match. Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com> Reviewed-by: Reinette Chatre <reinette.chatre@intel.com> Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
1 parent 74e76cb commit ae63855

File tree

3 files changed

+93
-0
lines changed

3 files changed

+93
-0
lines changed

tools/testing/selftests/resctrl/cat_test.c

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,10 +294,99 @@ static int cat_run_test(const struct resctrl_test *test, const struct user_param
294294
return ret;
295295
}
296296

297+
static int noncont_cat_run_test(const struct resctrl_test *test,
298+
const struct user_params *uparams)
299+
{
300+
unsigned long full_cache_mask, cont_mask, noncont_mask;
301+
unsigned int eax, ebx, ecx, edx, sparse_masks;
302+
int bit_center, ret;
303+
char schemata[64];
304+
305+
/* Check to compare sparse_masks content to CPUID output. */
306+
ret = resource_info_unsigned_get(test->resource, "sparse_masks", &sparse_masks);
307+
if (ret)
308+
return ret;
309+
310+
if (!strcmp(test->resource, "L3"))
311+
__cpuid_count(0x10, 1, eax, ebx, ecx, edx);
312+
else if (!strcmp(test->resource, "L2"))
313+
__cpuid_count(0x10, 2, eax, ebx, ecx, edx);
314+
else
315+
return -EINVAL;
316+
317+
if (sparse_masks != ((ecx >> 3) & 1)) {
318+
ksft_print_msg("CPUID output doesn't match 'sparse_masks' file content!\n");
319+
return 1;
320+
}
321+
322+
/* Write checks initialization. */
323+
ret = get_full_cbm(test->resource, &full_cache_mask);
324+
if (ret < 0)
325+
return ret;
326+
bit_center = count_bits(full_cache_mask) / 2;
327+
328+
/*
329+
* The bit_center needs to be at least 3 to properly calculate the CBM
330+
* hole in the noncont_mask. If it's smaller return an error since the
331+
* cache mask is too short and that shouldn't happen.
332+
*/
333+
if (bit_center < 3)
334+
return -EINVAL;
335+
cont_mask = full_cache_mask >> bit_center;
336+
337+
/* Contiguous mask write check. */
338+
snprintf(schemata, sizeof(schemata), "%lx", cont_mask);
339+
ret = write_schemata("", schemata, uparams->cpu, test->resource);
340+
if (ret) {
341+
ksft_print_msg("Write of contiguous CBM failed\n");
342+
return 1;
343+
}
344+
345+
/*
346+
* Non-contiguous mask write check. CBM has a 0xf hole approximately in the middle.
347+
* Output is compared with support information to catch any edge case errors.
348+
*/
349+
noncont_mask = ~(0xfUL << (bit_center - 2)) & full_cache_mask;
350+
snprintf(schemata, sizeof(schemata), "%lx", noncont_mask);
351+
ret = write_schemata("", schemata, uparams->cpu, test->resource);
352+
if (ret && sparse_masks)
353+
ksft_print_msg("Non-contiguous CBMs supported but write of non-contiguous CBM failed\n");
354+
else if (ret && !sparse_masks)
355+
ksft_print_msg("Non-contiguous CBMs not supported and write of non-contiguous CBM failed as expected\n");
356+
else if (!ret && !sparse_masks)
357+
ksft_print_msg("Non-contiguous CBMs not supported but write of non-contiguous CBM succeeded\n");
358+
359+
return !ret == !sparse_masks;
360+
}
361+
362+
static bool noncont_cat_feature_check(const struct resctrl_test *test)
363+
{
364+
if (!resctrl_resource_exists(test->resource))
365+
return false;
366+
367+
return resource_info_file_exists(test->resource, "sparse_masks");
368+
}
369+
297370
struct resctrl_test l3_cat_test = {
298371
.name = "L3_CAT",
299372
.group = "CAT",
300373
.resource = "L3",
301374
.feature_check = test_resource_feature_check,
302375
.run_test = cat_run_test,
303376
};
377+
378+
struct resctrl_test l3_noncont_cat_test = {
379+
.name = "L3_NONCONT_CAT",
380+
.group = "CAT",
381+
.resource = "L3",
382+
.feature_check = noncont_cat_feature_check,
383+
.run_test = noncont_cat_run_test,
384+
};
385+
386+
struct resctrl_test l2_noncont_cat_test = {
387+
.name = "L2_NONCONT_CAT",
388+
.group = "CAT",
389+
.resource = "L2",
390+
.feature_check = noncont_cat_feature_check,
391+
.run_test = noncont_cat_run_test,
392+
};

tools/testing/selftests/resctrl/resctrl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,5 +209,7 @@ extern struct resctrl_test mbm_test;
209209
extern struct resctrl_test mba_test;
210210
extern struct resctrl_test cmt_test;
211211
extern struct resctrl_test l3_cat_test;
212+
extern struct resctrl_test l3_noncont_cat_test;
213+
extern struct resctrl_test l2_noncont_cat_test;
212214

213215
#endif /* RESCTRL_H */

tools/testing/selftests/resctrl/resctrl_tests.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ static struct resctrl_test *resctrl_tests[] = {
1919
&mba_test,
2020
&cmt_test,
2121
&l3_cat_test,
22+
&l3_noncont_cat_test,
23+
&l2_noncont_cat_test,
2224
};
2325

2426
static int detect_vendor(void)

0 commit comments

Comments
 (0)