Re: [Xen-devel] [PATCH v2 1/4] x86: Support enable CDP by boot parameter and add get CDP status
On Wed, Sep 09, 2015 at 01:16:45PM +0800, He Chen wrote: > Intel Code/Data Prioritization(CDP) feature is based on CAT. cdp_enabled > is added to CAT socket info to indicate CDP is on or off on the socket, > note that cos_max would be half when CDP is on. struct psr_cat_cbm is > extended to support CDP operation. Extend psr_get_cat_l3_info sysctl to > get CDP status. > > Signed-off-by: He Chen> --- > xen/arch/x86/psr.c | 84 > ++--- > xen/arch/x86/sysctl.c | 5 ++- > xen/include/asm-x86/msr-index.h | 3 ++ > xen/include/asm-x86/psr.h | 11 +- > xen/include/public/sysctl.h | 2 + > 5 files changed, 89 insertions(+), 16 deletions(-) > > diff --git a/xen/arch/x86/psr.c b/xen/arch/x86/psr.c > index c0daa2e..ba0f726 100644 > --- a/xen/arch/x86/psr.c > +++ b/xen/arch/x86/psr.c > @@ -17,13 +17,21 @@ > #include > #include > #include > +#include Is this still needed? > #include > > #define PSR_CMT(1<<0) > #define PSR_CAT(1<<1) > +#define PSR_CDP(1<<2) > > struct psr_cat_cbm { > -uint64_t cbm; > +union { > +uint64_t cbm; > +struct { > +uint64_t code; > +uint64_t data; > +} cdp; > +} u; > unsigned int ref; > }; > > @@ -32,6 +40,7 @@ struct psr_cat_socket_info { > unsigned int cos_max; > struct psr_cat_cbm *cos_to_cbm; > spinlock_t cbm_lock; As you defined the cdp stauts for each socket here ... > +bool_t cdp_enabled; > }; > > struct psr_assoc { > @@ -43,6 +52,7 @@ struct psr_cmt *__read_mostly psr_cmt; > > static unsigned long *__read_mostly cat_socket_enable; > static struct psr_cat_socket_info *__read_mostly cat_socket_info; > +static unsigned long *__read_mostly cdp_socket_enable; ... this one then perhaps is redundency. If only one is need then I really like to keep the latter one. > @@ -470,6 +500,7 @@ static void cat_cpu_init(void) > struct psr_cat_socket_info *info; > unsigned int socket; > unsigned int cpu = smp_processor_id(); > +uint64_t val; > const struct cpuinfo_x86 *c = cpu_data + cpu; > > if ( !cpu_has(c, X86_FEATURE_CAT) || c->cpuid_level < > PSR_CPUID_LEVEL_CAT ) > @@ -490,13 +521,34 @@ static void cat_cpu_init(void) > info->cos_to_cbm = temp_cos_to_cbm; > temp_cos_to_cbm = NULL; > /* cos=0 is reserved as default cbm(all ones). */ > -info->cos_to_cbm[0].cbm = (1ull << info->cbm_len) - 1; > +info->cos_to_cbm[0].u.cbm = (1ull << info->cbm_len) - 1; > > spin_lock_init(>cbm_lock); > > set_bit(socket, cat_socket_enable); > printk(XENLOG_INFO "CAT: enabled on socket %u, cos_max:%u, > cbm_len:%u\n", > socket, info->cos_max, info->cbm_len); If CDP is enable below, then this information is quite misleading. > + > +if ( (ecx & PSR_CAT_CDP_CAPABILITY) && (opt_psr & PSR_CDP) ) > +{ > +if ( test_bit(socket, cdp_socket_enable) ) > +return; > + > +rdmsrl(MSR_IA32_PSR_L3_QOS_CFG, val); > +wrmsrl(MSR_IA32_PSR_L3_QOS_CFG, val | 1 << > PSR_L3_QOS_CDP_ENABLE_BIT); > + > +/* No need to write register since CBMs are fully open as > default by HW */ > +info->cos_to_cbm[0].u.cdp.code = (1ull << info->cbm_len) - 1; > +info->cos_to_cbm[0].u.cdp.data = (1ull << info->cbm_len) - 1; If I remember correctly, HW is supposed to boot as CAT mode by default and only IA32_L3_QOS_Mask_0 is all ones, other mask msrs however are not mentioned in the spec which then may contain arbitrary value. So I guesss as least you need write all ones to IA32_L3_QOS_Mask_1 explicitly and that should be done before you enabled CDP. > + > +/* Cut half of cos_max when CDP enabled */ > +info->cos_max = info->cos_max / 2; > + > +info->cdp_enabled = 1; > +set_bit(socket, cdp_socket_enable); > +printk(XENLOG_INFO "CDP: enabled on socket %u, cos_max:%u, > cbm_len:%u\n", > + socket, info->cos_max, info->cbm_len); > +} > } > } > > diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h > index e9c4723..402e7a7 100644 > --- a/xen/include/asm-x86/msr-index.h > +++ b/xen/include/asm-x86/msr-index.h > @@ -328,7 +328,10 @@ > #define MSR_IA32_CMT_EVTSEL 0x0c8d > #define MSR_IA32_CMT_CTR 0x0c8e > #define MSR_IA32_PSR_ASSOC 0x0c8f > +#define MSR_IA32_PSR_L3_QOS_CFG 0x0c81 > #define MSR_IA32_PSR_L3_MASK(n) (0x0c90 + (n)) > +#define MSR_IA32_PSR_L3_MASK_CBM_CODE(n) (0x0c90 + (n * 2 + 1)) > +#define MSR_IA32_PSR_L3_MASK_CBM_DATA(n) (0x0c90 + (n * 2)) I guess 'CBM' can be removed from these two macros, e.g. MSR_IA32_PSR_L3_MASK_CODE & MSR_IA32_PSR_L3_MASK_DATA Chao
Re: [Xen-devel] [PATCH v2 1/4] x86: Support enable CDP by boot parameter and add get CDP status
On Wed, Sep 09, 2015 at 03:04:35PM +0800, Chao Peng wrote: > On Wed, Sep 09, 2015 at 01:16:45PM +0800, He Chen wrote: > > Intel Code/Data Prioritization(CDP) feature is based on CAT. cdp_enabled > > is added to CAT socket info to indicate CDP is on or off on the socket, > > note that cos_max would be half when CDP is on. struct psr_cat_cbm is > > extended to support CDP operation. Extend psr_get_cat_l3_info sysctl to > > get CDP status. > > > > Signed-off-by: He Chen> > --- > > xen/arch/x86/psr.c | 84 > > ++--- > > xen/arch/x86/sysctl.c | 5 ++- > > xen/include/asm-x86/msr-index.h | 3 ++ > > xen/include/asm-x86/psr.h | 11 +- > > xen/include/public/sysctl.h | 2 + > > 5 files changed, 89 insertions(+), 16 deletions(-) > > > > diff --git a/xen/arch/x86/psr.c b/xen/arch/x86/psr.c > > index c0daa2e..ba0f726 100644 > > --- a/xen/arch/x86/psr.c > > +++ b/xen/arch/x86/psr.c > > @@ -17,13 +17,21 @@ > > #include > > #include > > #include > > +#include > > Is this still needed? > Obviously not, my mistake. > > #include > > > > #define PSR_CMT(1<<0) > > #define PSR_CAT(1<<1) > > +#define PSR_CDP(1<<2) > > > > struct psr_cat_cbm { > > -uint64_t cbm; > > +union { > > +uint64_t cbm; > > +struct { > > +uint64_t code; > > +uint64_t data; > > +} cdp; > > +} u; > > unsigned int ref; > > }; > > > > @@ -32,6 +40,7 @@ struct psr_cat_socket_info { > > unsigned int cos_max; > > struct psr_cat_cbm *cos_to_cbm; > > spinlock_t cbm_lock; > > As you defined the cdp stauts for each socket here ... > > +bool_t cdp_enabled; > > }; > > > > struct psr_assoc { > > @@ -43,6 +52,7 @@ struct psr_cmt *__read_mostly psr_cmt; > > > > static unsigned long *__read_mostly cat_socket_enable; > > static struct psr_cat_socket_info *__read_mostly cat_socket_info; > > +static unsigned long *__read_mostly cdp_socket_enable; > > ... this one then perhaps is redundency. If only one is need then I really > like to keep the latter one. > You're right. I would refine this. > > @@ -470,6 +500,7 @@ static void cat_cpu_init(void) > > struct psr_cat_socket_info *info; > > unsigned int socket; > > unsigned int cpu = smp_processor_id(); > > +uint64_t val; > > const struct cpuinfo_x86 *c = cpu_data + cpu; > > > > if ( !cpu_has(c, X86_FEATURE_CAT) || c->cpuid_level < > > PSR_CPUID_LEVEL_CAT ) > > @@ -490,13 +521,34 @@ static void cat_cpu_init(void) > > info->cos_to_cbm = temp_cos_to_cbm; > > temp_cos_to_cbm = NULL; > > /* cos=0 is reserved as default cbm(all ones). */ > > -info->cos_to_cbm[0].cbm = (1ull << info->cbm_len) - 1; > > +info->cos_to_cbm[0].u.cbm = (1ull << info->cbm_len) - 1; > > > > spin_lock_init(>cbm_lock); > > > > set_bit(socket, cat_socket_enable); > > printk(XENLOG_INFO "CAT: enabled on socket %u, cos_max:%u, > > cbm_len:%u\n", > > socket, info->cos_max, info->cbm_len); > > If CDP is enable below, then this information is quite misleading. > Is it proper to remove CAT printk info? > > + > > +if ( (ecx & PSR_CAT_CDP_CAPABILITY) && (opt_psr & PSR_CDP) ) > > +{ > > +if ( test_bit(socket, cdp_socket_enable) ) > > +return; > > + > > +rdmsrl(MSR_IA32_PSR_L3_QOS_CFG, val); > > +wrmsrl(MSR_IA32_PSR_L3_QOS_CFG, val | 1 << > > PSR_L3_QOS_CDP_ENABLE_BIT); > > + > > +/* No need to write register since CBMs are fully open as > > default by HW */ > > +info->cos_to_cbm[0].u.cdp.code = (1ull << info->cbm_len) - 1; > > +info->cos_to_cbm[0].u.cdp.data = (1ull << info->cbm_len) - 1; > > If I remember correctly, HW is supposed to boot as CAT mode by default and > only IA32_L3_QOS_Mask_0 is all ones, other mask msrs however are not mentioned > in the spec which then may contain arbitrary value. So I guesss as > least you need write all ones to IA32_L3_QOS_Mask_1 explicitly and that > should be done before you enabled CDP. > I have tested it at Broadwell server. I mean, I have used rdmsr to get mask0 and mask1 during booting and then check them, I found that they all ones by default. But since spec doesn't mention it as you said, I would write all ones to mask1 for better compatibility. > > + > > +/* Cut half of cos_max when CDP enabled */ > > +info->cos_max = info->cos_max / 2; > > + > > +info->cdp_enabled = 1; > > +set_bit(socket, cdp_socket_enable); > > +printk(XENLOG_INFO "CDP: enabled on socket %u, cos_max:%u, > > cbm_len:%u\n", > > + socket, info->cos_max, info->cbm_len); > > +} > > } > > } > > > > diff --git a/xen/include/asm-x86/msr-index.h > > b/xen/include/asm-x86/msr-index.h > >
[Xen-devel] [PATCH v2 1/4] x86: Support enable CDP by boot parameter and add get CDP status
Intel Code/Data Prioritization(CDP) feature is based on CAT. cdp_enabled is added to CAT socket info to indicate CDP is on or off on the socket, note that cos_max would be half when CDP is on. struct psr_cat_cbm is extended to support CDP operation. Extend psr_get_cat_l3_info sysctl to get CDP status. Signed-off-by: He Chen--- xen/arch/x86/psr.c | 84 ++--- xen/arch/x86/sysctl.c | 5 ++- xen/include/asm-x86/msr-index.h | 3 ++ xen/include/asm-x86/psr.h | 11 +- xen/include/public/sysctl.h | 2 + 5 files changed, 89 insertions(+), 16 deletions(-) diff --git a/xen/arch/x86/psr.c b/xen/arch/x86/psr.c index c0daa2e..ba0f726 100644 --- a/xen/arch/x86/psr.c +++ b/xen/arch/x86/psr.c @@ -17,13 +17,21 @@ #include #include #include +#include #include #define PSR_CMT(1<<0) #define PSR_CAT(1<<1) +#define PSR_CDP(1<<2) struct psr_cat_cbm { -uint64_t cbm; +union { +uint64_t cbm; +struct { +uint64_t code; +uint64_t data; +} cdp; +} u; unsigned int ref; }; @@ -32,6 +40,7 @@ struct psr_cat_socket_info { unsigned int cos_max; struct psr_cat_cbm *cos_to_cbm; spinlock_t cbm_lock; +bool_t cdp_enabled; }; struct psr_assoc { @@ -43,6 +52,7 @@ struct psr_cmt *__read_mostly psr_cmt; static unsigned long *__read_mostly cat_socket_enable; static struct psr_cat_socket_info *__read_mostly cat_socket_info; +static unsigned long *__read_mostly cdp_socket_enable; static unsigned int __initdata opt_psr; static unsigned int __initdata opt_rmid_max = 255; @@ -94,6 +104,7 @@ static void __init parse_psr_param(char *s) parse_psr_bool(s, val_str, "cmt", PSR_CMT); parse_psr_bool(s, val_str, "cat", PSR_CAT); +parse_psr_bool(s, val_str, "cdp", PSR_CDP); if ( val_str && !strcmp(s, "rmid_max") ) opt_rmid_max = simple_strtoul(val_str, NULL, 0); @@ -262,7 +273,7 @@ static struct psr_cat_socket_info *get_cat_socket_info(unsigned int socket) } int psr_get_cat_l3_info(unsigned int socket, uint32_t *cbm_len, -uint32_t *cos_max) +uint32_t *cos_max, uint32_t *flags) { struct psr_cat_socket_info *info = get_cat_socket_info(socket); @@ -272,6 +283,10 @@ int psr_get_cat_l3_info(unsigned int socket, uint32_t *cbm_len, *cbm_len = info->cbm_len; *cos_max = info->cos_max; +*flags = 0; +if ( info->cdp_enabled ) +*flags |= PSR_CAT_FLAG_L3_CDP; + return 0; } @@ -282,7 +297,7 @@ int psr_get_l3_cbm(struct domain *d, unsigned int socket, uint64_t *cbm) if ( IS_ERR(info) ) return PTR_ERR(info); -*cbm = info->cos_to_cbm[d->arch.psr_cos_ids[socket]].cbm; +*cbm = info->cos_to_cbm[d->arch.psr_cos_ids[socket]].u.cbm; return 0; } @@ -313,19 +328,34 @@ static bool_t psr_check_cbm(unsigned int cbm_len, uint64_t cbm) struct cos_cbm_info { unsigned int cos; -uint64_t cbm; +uint64_t cbm_code; +uint64_t cbm_data; +bool_t cdp; }; static void do_write_l3_cbm(void *data) { struct cos_cbm_info *info = data; -wrmsrl(MSR_IA32_PSR_L3_MASK(info->cos), info->cbm); +if ( info->cdp ) +{ +wrmsrl(MSR_IA32_PSR_L3_MASK_CBM_CODE(info->cos), info->cbm_code); +wrmsrl(MSR_IA32_PSR_L3_MASK_CBM_DATA(info->cos), info->cbm_data); +} +else +wrmsrl(MSR_IA32_PSR_L3_MASK(info->cos), info->cbm_code); } -static int write_l3_cbm(unsigned int socket, unsigned int cos, uint64_t cbm) +static int write_l3_cbm(unsigned int socket, unsigned int cos, +uint64_t cbm_code, uint64_t cbm_data, bool_t cdp) { -struct cos_cbm_info info = { .cos = cos, .cbm = cbm }; +struct cos_cbm_info info = +{ + .cos = cos, + .cbm_code = cbm_code, + .cbm_data = cbm_data, + .cdp = cdp, +}; if ( socket == cpu_to_socket(smp_processor_id()) ) do_write_l3_cbm(); @@ -363,7 +393,7 @@ int psr_set_l3_cbm(struct domain *d, unsigned int socket, uint64_t cbm) /* If still not found, then keep unused one. */ if ( !found && cos != 0 && map[cos].ref == 0 ) found = map + cos; -else if ( map[cos].cbm == cbm ) +else if ( map[cos].u.cbm == cbm ) { if ( unlikely(cos == old_cos) ) { @@ -387,16 +417,16 @@ int psr_set_l3_cbm(struct domain *d, unsigned int socket, uint64_t cbm) } cos = found - map; -if ( found->cbm != cbm ) +if ( found->u.cbm != cbm ) { -int ret = write_l3_cbm(socket, cos, cbm); +int ret = write_l3_cbm(socket, cos, cbm, 0, 0); if ( ret ) { spin_unlock(>cbm_lock); return ret; } -found->cbm = cbm; +found->u.cbm = cbm; } found->ref++; @@ -470,6 +500,7 @@ static void