Skip to content

Commit 316e7f9

Browse files
James Morsesuryasaimadhu
authored andcommitted
x86/resctrl: Add struct rdt_cache::arch_has_{sparse, empty}_bitmaps
Intel CPUs expect the cache bitmap provided by user-space to have on a single span of 1s, whereas AMD can support bitmaps like 0xf00f. Arm's MPAM support also allows sparse bitmaps. Similarly, Intel CPUs check at least one bit set, whereas AMD CPUs are quite happy with an empty bitmap. Arm's MPAM allows an empty bitmap. To move resctrl out to /fs/, platform differences like this need to be explained. Add two resource properties arch_has_{empty,sparse}_bitmaps. Test these around the relevant parts of cbm_validate(). Merging the validate calls causes AMD to gain the min_cbm_bits test needed for Haswell, but as it always sets this value to 1, it will never match. [ bp: Massage commit message. ] Signed-off-by: James Morse <james.morse@arm.com> Signed-off-by: Borislav Petkov <bp@suse.de> Reviewed-by: Babu Moger <babu.moger@amd.com> Reviewed-by: Reinette Chatre <reinette.chatre@intel.com> Link: https://lkml.kernel.org/r/20200708163929.2783-10-james.morse@arm.com
1 parent 5df3ca9 commit 316e7f9

3 files changed

Lines changed: 22 additions & 39 deletions

File tree

arch/x86/kernel/cpu/resctrl/core.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -922,9 +922,10 @@ static __init void rdt_init_res_defs_intel(void)
922922
r->rid == RDT_RESOURCE_L3CODE ||
923923
r->rid == RDT_RESOURCE_L2 ||
924924
r->rid == RDT_RESOURCE_L2DATA ||
925-
r->rid == RDT_RESOURCE_L2CODE)
926-
r->cbm_validate = cbm_validate_intel;
927-
else if (r->rid == RDT_RESOURCE_MBA) {
925+
r->rid == RDT_RESOURCE_L2CODE) {
926+
r->cache.arch_has_sparse_bitmaps = false;
927+
r->cache.arch_has_empty_bitmaps = false;
928+
} else if (r->rid == RDT_RESOURCE_MBA) {
928929
r->msr_base = MSR_IA32_MBA_THRTL_BASE;
929930
r->msr_update = mba_wrmsr_intel;
930931
}
@@ -941,9 +942,10 @@ static __init void rdt_init_res_defs_amd(void)
941942
r->rid == RDT_RESOURCE_L3CODE ||
942943
r->rid == RDT_RESOURCE_L2 ||
943944
r->rid == RDT_RESOURCE_L2DATA ||
944-
r->rid == RDT_RESOURCE_L2CODE)
945-
r->cbm_validate = cbm_validate_amd;
946-
else if (r->rid == RDT_RESOURCE_MBA) {
945+
r->rid == RDT_RESOURCE_L2CODE) {
946+
r->cache.arch_has_sparse_bitmaps = true;
947+
r->cache.arch_has_empty_bitmaps = true;
948+
} else if (r->rid == RDT_RESOURCE_MBA) {
947949
r->msr_base = MSR_IA32_MBA_BW_BASE;
948950
r->msr_update = mba_wrmsr_amd;
949951
}

arch/x86/kernel/cpu/resctrl/ctrlmondata.c

Lines changed: 10 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,14 @@ int parse_bw(struct rdt_parse_data *data, struct rdt_resource *r,
7676
}
7777

7878
/*
79-
* Check whether a cache bit mask is valid. The SDM says:
79+
* Check whether a cache bit mask is valid.
80+
* For Intel the SDM says:
8081
* Please note that all (and only) contiguous '1' combinations
8182
* are allowed (e.g. FFFFH, 0FF0H, 003CH, etc.).
8283
* Additionally Haswell requires at least two bits set.
84+
* AMD allows non-contiguous bitmasks.
8385
*/
84-
bool cbm_validate_intel(char *buf, u32 *data, struct rdt_resource *r)
86+
static bool cbm_validate(char *buf, u32 *data, struct rdt_resource *r)
8587
{
8688
unsigned long first_bit, zero_bit, val;
8789
unsigned int cbm_len = r->cache.cbm_len;
@@ -93,15 +95,18 @@ bool cbm_validate_intel(char *buf, u32 *data, struct rdt_resource *r)
9395
return false;
9496
}
9597

96-
if (val == 0 || val > r->default_ctrl) {
98+
if ((!r->cache.arch_has_empty_bitmaps && val == 0) ||
99+
val > r->default_ctrl) {
97100
rdt_last_cmd_puts("Mask out of range\n");
98101
return false;
99102
}
100103

101104
first_bit = find_first_bit(&val, cbm_len);
102105
zero_bit = find_next_zero_bit(&val, cbm_len, first_bit);
103106

104-
if (find_next_bit(&val, cbm_len, zero_bit) < cbm_len) {
107+
/* Are non-contiguous bitmaps allowed? */
108+
if (!r->cache.arch_has_sparse_bitmaps &&
109+
(find_next_bit(&val, cbm_len, zero_bit) < cbm_len)) {
105110
rdt_last_cmd_printf("The mask %lx has non-consecutive 1-bits\n", val);
106111
return false;
107112
}
@@ -116,30 +121,6 @@ bool cbm_validate_intel(char *buf, u32 *data, struct rdt_resource *r)
116121
return true;
117122
}
118123

119-
/*
120-
* Check whether a cache bit mask is valid. AMD allows non-contiguous
121-
* bitmasks
122-
*/
123-
bool cbm_validate_amd(char *buf, u32 *data, struct rdt_resource *r)
124-
{
125-
unsigned long val;
126-
int ret;
127-
128-
ret = kstrtoul(buf, 16, &val);
129-
if (ret) {
130-
rdt_last_cmd_printf("Non-hex character in the mask %s\n", buf);
131-
return false;
132-
}
133-
134-
if (val > r->default_ctrl) {
135-
rdt_last_cmd_puts("Mask out of range\n");
136-
return false;
137-
}
138-
139-
*data = val;
140-
return true;
141-
}
142-
143124
/*
144125
* Read one cache bit mask (hex). Check that it is valid for the current
145126
* resource type.
@@ -165,7 +146,7 @@ int parse_cbm(struct rdt_parse_data *data, struct rdt_resource *r,
165146
return -EINVAL;
166147
}
167148

168-
if (!r->cbm_validate(data->buf, &cbm_val, r))
149+
if (!cbm_validate(data->buf, &cbm_val, r))
169150
return -EINVAL;
170151

171152
if ((rdtgrp->mode == RDT_MODE_EXCLUSIVE ||

arch/x86/kernel/cpu/resctrl/internal.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -358,13 +358,17 @@ struct msr_param {
358358
* in a cache bit mask
359359
* @shareable_bits: Bitmask of shareable resource with other
360360
* executing entities
361+
* @arch_has_sparse_bitmaps: True if a bitmap like f00f is valid.
362+
* @arch_has_empty_bitmaps: True if the '0' bitmap is valid.
361363
*/
362364
struct rdt_cache {
363365
unsigned int cbm_len;
364366
unsigned int min_cbm_bits;
365367
unsigned int cbm_idx_mult;
366368
unsigned int cbm_idx_offset;
367369
unsigned int shareable_bits;
370+
bool arch_has_sparse_bitmaps;
371+
bool arch_has_empty_bitmaps;
368372
};
369373

370374
/**
@@ -434,7 +438,6 @@ struct rdt_parse_data {
434438
* @cache: Cache allocation related data
435439
* @format_str: Per resource format string to show domain value
436440
* @parse_ctrlval: Per resource function pointer to parse control values
437-
* @cbm_validate Cache bitmask validate function
438441
* @evt_list: List of monitoring events
439442
* @num_rmid: Number of RMIDs available
440443
* @mon_scale: cqm counter * mon_scale = occupancy in bytes
@@ -461,7 +464,6 @@ struct rdt_resource {
461464
int (*parse_ctrlval)(struct rdt_parse_data *data,
462465
struct rdt_resource *r,
463466
struct rdt_domain *d);
464-
bool (*cbm_validate)(char *buf, u32 *data, struct rdt_resource *r);
465467
struct list_head evt_list;
466468
int num_rmid;
467469
unsigned int mon_scale;
@@ -604,8 +606,6 @@ void cqm_setup_limbo_handler(struct rdt_domain *dom, unsigned long delay_ms);
604606
void cqm_handle_limbo(struct work_struct *work);
605607
bool has_busy_rmid(struct rdt_resource *r, struct rdt_domain *d);
606608
void __check_limbo(struct rdt_domain *d, bool force_free);
607-
bool cbm_validate_intel(char *buf, u32 *data, struct rdt_resource *r);
608-
bool cbm_validate_amd(char *buf, u32 *data, struct rdt_resource *r);
609609
void rdt_domain_reconfigure_cdp(struct rdt_resource *r);
610610

611611
#endif /* _ASM_X86_RESCTRL_INTERNAL_H */

0 commit comments

Comments
 (0)