x86/intel_rdt: Add command line options for resource director technology

Command line options allow us to ignore features that we don't want.
Also we can re-enable options that have been disabled on a platform
(so long as the underlying h/w actually supports the option).

[ tglx: Marked the option array __initdata and the helper function __init ]

Signed-off-by: Tony Luck <tony.luck@intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Fenghua" <fenghua.yu@intel.com>
Cc: Ravi V" <ravi.v.shankar@intel.com>
Cc: "Peter Zijlstra" <peterz@infradead.org>
Cc: "Stephane Eranian" <eranian@google.com>
Cc: "Andi Kleen" <ak@linux.intel.com>
Cc: "David Carrillo-Cisneros" <davidcc@google.com>
Cc: Vikas Shivappa <vikas.shivappa@linux.intel.com>
Link: http://lkml.kernel.org/r/0c37b0d4dbc30977a3c1cee08b66420f83662694.1503512900.git.tony.luck@intel.com
This commit is contained in:
Tony Luck
2017-08-24 09:26:51 -07:00
committed by Thomas Gleixner
parent 0576113a38
commit 1d9807fc64
3 changed files with 95 additions and 8 deletions

View File

@@ -138,6 +138,7 @@ parameter is applicable::
PPT Parallel port support is enabled. PPT Parallel port support is enabled.
PS2 Appropriate PS/2 support is enabled. PS2 Appropriate PS/2 support is enabled.
RAM RAM disk support is enabled. RAM RAM disk support is enabled.
RDT Intel Resource Director Technology.
S390 S390 architecture is enabled. S390 S390 architecture is enabled.
SCSI Appropriate SCSI support is enabled. SCSI Appropriate SCSI support is enabled.
A lot of drivers have their options described inside A lot of drivers have their options described inside

View File

@@ -3598,6 +3598,12 @@
Run specified binary instead of /init from the ramdisk, Run specified binary instead of /init from the ramdisk,
used for early userspace startup. See initrd. used for early userspace startup. See initrd.
rdt= [HW,X86,RDT]
Turn on/off individual RDT features. List is:
cmt, mbmtotal, mbmlocal, l3cat, l3cdp, l2cat, mba.
E.g. to turn on cmt and turn off mba use:
rdt=cmt,!mba
reboot= [KNL] reboot= [KNL]
Format (x86 or x86_64): Format (x86 or x86_64):
[w[arm] | c[old] | h[ard] | s[oft] | g[pio]] \ [w[arm] | c[old] | h[ard] | s[oft] | g[pio]] \

View File

@@ -637,6 +637,85 @@ static __init void rdt_init_padding(void)
} }
} }
enum {
RDT_FLAG_CMT,
RDT_FLAG_MBM_TOTAL,
RDT_FLAG_MBM_LOCAL,
RDT_FLAG_L3_CAT,
RDT_FLAG_L3_CDP,
RDT_FLAG_L2_CAT,
RDT_FLAG_MBA,
};
#define RDT_OPT(idx, n, f) \
[idx] = { \
.name = n, \
.flag = f \
}
struct rdt_options {
char *name;
int flag;
bool force_off, force_on;
};
static struct rdt_options rdt_options[] __initdata = {
RDT_OPT(RDT_FLAG_CMT, "cmt", X86_FEATURE_CQM_OCCUP_LLC),
RDT_OPT(RDT_FLAG_MBM_TOTAL, "mbmtotal", X86_FEATURE_CQM_MBM_TOTAL),
RDT_OPT(RDT_FLAG_MBM_LOCAL, "mbmlocal", X86_FEATURE_CQM_MBM_LOCAL),
RDT_OPT(RDT_FLAG_L3_CAT, "l3cat", X86_FEATURE_CAT_L3),
RDT_OPT(RDT_FLAG_L3_CDP, "l3cdp", X86_FEATURE_CDP_L3),
RDT_OPT(RDT_FLAG_L2_CAT, "l2cat", X86_FEATURE_CAT_L2),
RDT_OPT(RDT_FLAG_MBA, "mba", X86_FEATURE_MBA),
};
#define NUM_RDT_OPTIONS ARRAY_SIZE(rdt_options)
static int __init set_rdt_options(char *str)
{
struct rdt_options *o;
bool force_off;
char *tok;
if (*str == '=')
str++;
while ((tok = strsep(&str, ",")) != NULL) {
force_off = *tok == '!';
if (force_off)
tok++;
for (o = rdt_options; o < &rdt_options[NUM_RDT_OPTIONS]; o++) {
if (strcmp(tok, o->name) == 0) {
if (force_off)
o->force_off = true;
else
o->force_on = true;
break;
}
}
}
return 1;
}
__setup("rdt", set_rdt_options);
static bool __init rdt_cpu_has(int flag)
{
bool ret = boot_cpu_has(flag);
struct rdt_options *o;
if (!ret)
return ret;
for (o = rdt_options; o < &rdt_options[NUM_RDT_OPTIONS]; o++) {
if (flag == o->flag) {
if (o->force_off)
ret = false;
if (o->force_on)
ret = true;
break;
}
}
return ret;
}
static __init bool get_rdt_alloc_resources(void) static __init bool get_rdt_alloc_resources(void)
{ {
bool ret = false; bool ret = false;
@@ -647,21 +726,21 @@ static __init bool get_rdt_alloc_resources(void)
if (!boot_cpu_has(X86_FEATURE_RDT_A)) if (!boot_cpu_has(X86_FEATURE_RDT_A))
return false; return false;
if (boot_cpu_has(X86_FEATURE_CAT_L3)) { if (rdt_cpu_has(X86_FEATURE_CAT_L3)) {
rdt_get_cache_alloc_cfg(1, &rdt_resources_all[RDT_RESOURCE_L3]); rdt_get_cache_alloc_cfg(1, &rdt_resources_all[RDT_RESOURCE_L3]);
if (boot_cpu_has(X86_FEATURE_CDP_L3)) { if (rdt_cpu_has(X86_FEATURE_CDP_L3)) {
rdt_get_cdp_l3_config(RDT_RESOURCE_L3DATA); rdt_get_cdp_l3_config(RDT_RESOURCE_L3DATA);
rdt_get_cdp_l3_config(RDT_RESOURCE_L3CODE); rdt_get_cdp_l3_config(RDT_RESOURCE_L3CODE);
} }
ret = true; ret = true;
} }
if (boot_cpu_has(X86_FEATURE_CAT_L2)) { if (rdt_cpu_has(X86_FEATURE_CAT_L2)) {
/* CPUID 0x10.2 fields are same format at 0x10.1 */ /* CPUID 0x10.2 fields are same format at 0x10.1 */
rdt_get_cache_alloc_cfg(2, &rdt_resources_all[RDT_RESOURCE_L2]); rdt_get_cache_alloc_cfg(2, &rdt_resources_all[RDT_RESOURCE_L2]);
ret = true; ret = true;
} }
if (boot_cpu_has(X86_FEATURE_MBA)) { if (rdt_cpu_has(X86_FEATURE_MBA)) {
if (rdt_get_mem_config(&rdt_resources_all[RDT_RESOURCE_MBA])) if (rdt_get_mem_config(&rdt_resources_all[RDT_RESOURCE_MBA]))
ret = true; ret = true;
} }
@@ -670,11 +749,11 @@ static __init bool get_rdt_alloc_resources(void)
static __init bool get_rdt_mon_resources(void) static __init bool get_rdt_mon_resources(void)
{ {
if (boot_cpu_has(X86_FEATURE_CQM_OCCUP_LLC)) if (rdt_cpu_has(X86_FEATURE_CQM_OCCUP_LLC))
rdt_mon_features |= (1 << QOS_L3_OCCUP_EVENT_ID); rdt_mon_features |= (1 << QOS_L3_OCCUP_EVENT_ID);
if (boot_cpu_has(X86_FEATURE_CQM_MBM_TOTAL)) if (rdt_cpu_has(X86_FEATURE_CQM_MBM_TOTAL))
rdt_mon_features |= (1 << QOS_L3_MBM_TOTAL_EVENT_ID); rdt_mon_features |= (1 << QOS_L3_MBM_TOTAL_EVENT_ID);
if (boot_cpu_has(X86_FEATURE_CQM_MBM_LOCAL)) if (rdt_cpu_has(X86_FEATURE_CQM_MBM_LOCAL))
rdt_mon_features |= (1 << QOS_L3_MBM_LOCAL_EVENT_ID); rdt_mon_features |= (1 << QOS_L3_MBM_LOCAL_EVENT_ID);
if (!rdt_mon_features) if (!rdt_mon_features)
@@ -687,7 +766,8 @@ static __init void rdt_quirks(void)
{ {
switch (boot_cpu_data.x86_model) { switch (boot_cpu_data.x86_model) {
case INTEL_FAM6_HASWELL_X: case INTEL_FAM6_HASWELL_X:
cache_alloc_hsw_probe(); if (!rdt_options[RDT_FLAG_L3_CAT].force_off)
cache_alloc_hsw_probe();
break; break;
} }
} }