[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 04/15] x86: implement data structure and CPU init flow for MBA
On Thu, Aug 24, 2017 at 09:14:38AM +0800, Yi Sun wrote: > This patch implements main data structures of MBA. > > Like CAT features, MBA HW info has cos_max which means the max thrtl > register number, and thrtl_max which means the max throttle value > (delay value). It also has a flag to represent if the throttle > value is linear or not. > > One thrtl register of MBA stores a throttle value for one or more > domains. The throttle value means the transaction time between L2 > cache and next level memory to be delayed. > > This patch also implements init flow for MBA and register stub > callback functions. > > Signed-off-by: Yi Sun <yi.y.sun@xxxxxxxxxxxxxxx> > --- > v2: > - modify commit message to replace 'cos register' to 'thrtl register' to > make it accurate. > (suggested by Chao Peng) > - restore the place of the sentence to assign value to 'feat->cbm_len' > because the MBA init flow is splitted out as a separate function in v1. > (suggested by Chao Peng) > - add comment to explain what the MBA thrtl defaul value '0' stands for. > (suggested by Chao Peng) > - check 'thrtl_max' under linear mode. It could not be euqal or larger > than > 100. > (suggested by Chao Peng) > v1: > - rebase codes onto L2 CAT v15. > - move comment to appropriate place. > (suggested by Chao Peng) > - implement 'mba_init_feature' and keep 'cat_init_feature'. > (suggested by Chao Peng) > - keep 'regs.b' into a local variable to avoid reading CPUID every time. > (suggested by Chao Peng) > --- > xen/arch/x86/psr.c | 141 > +++++++++++++++++++++++++++++++++++----- > xen/include/asm-x86/msr-index.h | 1 + > xen/include/asm-x86/psr.h | 2 + > 3 files changed, 126 insertions(+), 18 deletions(-) > > diff --git a/xen/arch/x86/psr.c b/xen/arch/x86/psr.c > index da62f81..f5e99ce 100644 > --- a/xen/arch/x86/psr.c > +++ b/xen/arch/x86/psr.c > @@ -27,13 +27,16 @@ > * - CMT Cache Monitoring Technology > * - COS/CLOS Class of Service. Also mean COS registers. > * - COS_MAX Max number of COS for the feature (minus 1) > + * - MBA Memory Bandwidth Allocation > * - MSRs Machine Specific Registers > * - PSR Intel Platform Shared Resource > + * - THRTL_MAX Max throttle value (delay value) of MBA > */ > > #define PSR_CMT (1u << 0) > #define PSR_CAT (1u << 1) > #define PSR_CDP (1u << 2) > +#define PSR_MBA (1u << 3) > > #define CAT_CBM_LEN_MASK 0x1f > #define CAT_COS_MAX_MASK 0xffff > @@ -60,10 +63,14 @@ > */ > #define MAX_COS_NUM 2 > > +#define MBA_LINEAR (1u << 2) Why is this shifted by 2? > +#define MBA_THRTL_MAX_MASK 0xfff > + > enum psr_feat_type { > FEAT_TYPE_L3_CAT, > FEAT_TYPE_L3_CDP, > FEAT_TYPE_L2_CAT, > + FEAT_TYPE_MBA, > FEAT_TYPE_NUM, > FEAT_TYPE_UNKNOWN, > }; > @@ -71,7 +78,6 @@ enum psr_feat_type { > /* > * This structure represents one feature. > * cos_max - The max COS registers number got through CPUID. > - * cbm_len - The length of CBM got through CPUID. > * cos_reg_val - Array to store the values of COS registers. One entry stores > * the value of one COS register. > * For L3 CAT and L2 CAT, one entry corresponds to one COS_ID. > @@ -80,9 +86,23 @@ enum psr_feat_type { > * cos_reg_val[1] (Code). > */ > struct feat_node { > - /* cos_max and cbm_len are common values for all features so far. */ > + /* cos_max is common values for all features so far. */ > unsigned int cos_max; > - unsigned int cbm_len; > + > + /* Feature specific HW info. */ > + union { > + struct { > + /* The length of CBM got through CPUID. */ > + unsigned int cbm_len; > + } cat_info; > + > + struct { > + /* The max throttling value got through CPUID. */ > + unsigned int thrtl_max; > + unsigned int linear; This seems like it wants to be a boolean? > + } mba_info; Just naming the fields 'cat' and 'mba' would probably be enough IMHO, but that's just taste I think, and I won't argue if you prefer to leave them with the _info suffix. > + }; > + > uint32_t cos_reg_val[MAX_COS_REG_CNT]; > }; > > @@ -161,6 +181,7 @@ static DEFINE_PER_CPU(struct psr_assoc, psr_assoc); > */ > static struct feat_node *feat_l3; > static struct feat_node *feat_l2_cat; > +static struct feat_node *feat_mba; > > /* Common functions */ > #define cat_default_val(len) (0xffffffff >> (32 - (len))) > @@ -273,7 +294,7 @@ static bool psr_check_cbm(unsigned int cbm_len, unsigned > long cbm) > return true; > } > > -/* CAT common functions implementation. */ > +/* Implementation of allocation features' functions. */ > static int cat_init_feature(const struct cpuid_leaf *regs, > struct feat_node *feat, > struct psr_socket_info *info, > @@ -289,8 +310,8 @@ static int cat_init_feature(const struct cpuid_leaf *regs, > if ( !regs->a || !regs->d ) > return -ENOENT; > > - feat->cbm_len = (regs->a & CAT_CBM_LEN_MASK) + 1; > feat->cos_max = min(opt_cos_max, regs->d & CAT_COS_MAX_MASK); > + feat->cat_info.cbm_len = (regs->a & CAT_CBM_LEN_MASK) + 1; > > switch ( type ) > { > @@ -300,12 +321,12 @@ static int cat_init_feature(const struct cpuid_leaf > *regs, > return -ENOENT; > > /* We reserve cos=0 as default cbm (all bits within cbm_len are 1). > */ > - feat->cos_reg_val[0] = cat_default_val(feat->cbm_len); > + feat->cos_reg_val[0] = cat_default_val(feat->cat_info.cbm_len); > > wrmsrl((type == FEAT_TYPE_L3_CAT ? > MSR_IA32_PSR_L3_MASK(0) : > MSR_IA32_PSR_L2_MASK(0)), > - cat_default_val(feat->cbm_len)); > + cat_default_val(feat->cat_info.cbm_len)); > > break; > > @@ -320,11 +341,13 @@ static int cat_init_feature(const struct cpuid_leaf > *regs, > feat->cos_max = (feat->cos_max - 1) >> 1; > > /* We reserve cos=0 as default cbm (all bits within cbm_len are 1). > */ > - get_cdp_code(feat, 0) = cat_default_val(feat->cbm_len); > - get_cdp_data(feat, 0) = cat_default_val(feat->cbm_len); > + get_cdp_code(feat, 0) = cat_default_val(feat->cat_info.cbm_len); > + get_cdp_data(feat, 0) = cat_default_val(feat->cat_info.cbm_len); > > - wrmsrl(MSR_IA32_PSR_L3_MASK(0), cat_default_val(feat->cbm_len)); > - wrmsrl(MSR_IA32_PSR_L3_MASK(1), cat_default_val(feat->cbm_len)); > + wrmsrl(MSR_IA32_PSR_L3_MASK(0), > + cat_default_val(feat->cat_info.cbm_len)); > + wrmsrl(MSR_IA32_PSR_L3_MASK(1), > + cat_default_val(feat->cat_info.cbm_len)); > rdmsrl(MSR_IA32_PSR_L3_QOS_CFG, val); > wrmsrl(MSR_IA32_PSR_L3_QOS_CFG, > val | (1ull << PSR_L3_QOS_CDP_ENABLE_BIT)); > @@ -344,7 +367,51 @@ static int cat_init_feature(const struct cpuid_leaf > *regs, > > printk(XENLOG_INFO "%s: enabled on socket %u, cos_max:%u, cbm_len:%u\n", > cat_feat_name[type], cpu_to_socket(smp_processor_id()), > - feat->cos_max, feat->cbm_len); > + feat->cos_max, feat->cat_info.cbm_len); > + > + return 0; > +} > + > +static int mba_init_feature(const struct cpuid_leaf *regs, > + struct feat_node *feat, > + struct psr_socket_info *info, > + enum psr_feat_type type) > +{ > + /* No valid value so do not enable feature. */ > + if ( !regs->a || !regs->d ) > + return -ENOENT; > + > + if ( type != FEAT_TYPE_MBA ) > + return -ENOENT; > + > + feat->cos_max = min(opt_cos_max, regs->d & CAT_COS_MAX_MASK); > + if ( feat->cos_max < 1 ) > + return -ENOENT; > + > + feat->mba_info.thrtl_max = (regs->a & MBA_THRTL_MAX_MASK) + 1; > + > + if ( regs->c & MBA_LINEAR ) > + { > + feat->mba_info.linear = 1; > + > + if ( feat->mba_info.thrtl_max >= 100 ) > + return -ENOENT; > + } > + > + /* We reserve cos=0 as default thrtl (0) which means no delay. */ > + feat->cos_reg_val[0] = 0; > + wrmsrl(MSR_IA32_PSR_MBA_MASK(0), 0); > + > + /* Add this feature into array. */ > + info->features[type] = feat; > + > + if ( !opt_cpu_info ) > + return 0; > + > + printk(XENLOG_INFO "MBA: enabled on socket %u, cos_max:%u," > + "thrtl_max:%u, linear:%u.\n", Please try to avoid splitting messages, it makes it hard to grep for them afterward. > + cpu_to_socket(smp_processor_id()), > + feat->cos_max, feat->mba_info.thrtl_max, feat->mba_info.linear); > > return 0; > } > @@ -356,7 +423,7 @@ static bool cat_get_feat_info(const struct feat_node > *feat, > return false; > > data[PSR_INFO_IDX_COS_MAX] = feat->cos_max; > - data[PSR_INFO_IDX_CAT_CBM_LEN] = feat->cbm_len; > + data[PSR_INFO_IDX_CAT_CBM_LEN] = feat->cat_info.cbm_len; > data[PSR_INFO_IDX_CAT_FLAG] = 0; > > return true; > @@ -422,6 +489,26 @@ static const struct feat_props l2_cat_props = { > .write_msr = l2_cat_write_msr, > }; > > +/* MBA props */ > +static bool mba_get_feat_info(const struct feat_node *feat, > + uint32_t data[], unsigned int array_len) > +{ > + return false; > +} Shouldn't this return thrtl_max and whether it's linear? > + > +static void mba_write_msr(unsigned int cos, uint32_t val, > + enum psr_val_type type) > +{ And this perform the MSR write? (MSR_IA32_PSR_MBA_MASK...) Roger. _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |