[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v10 05/25] x86: refactor psr: L3 CAT: implement CPU init and free flow.
>>> On 06.04.17 at 07:49, <yi.y.sun@xxxxxxxxxxxxxxx> wrote: > On 17-04-05 09:10:58, Jan Beulich wrote: >> >>> On 01.04.17 at 15:53, <yi.y.sun@xxxxxxxxxxxxxxx> wrote: >> > +static void free_socket_resources(unsigned int socket) >> > +{ >> > + unsigned int i; >> > + struct psr_socket_info *info = socket_info + socket; >> > + >> > + if ( !info ) >> > + return; >> > + >> > + /* >> > + * Free resources of features. The global feature object, e.g. >> > feat_l3_cat, >> > + * may not be freed here if it is not added into array. It is simply >> > being >> > + * kept until the next CPU online attempt. >> > + */ >> > + for ( i = 0; i < PSR_SOCKET_MAX_FEAT; i++ ) >> > + { >> > + if ( !info->features[i] ) >> > + continue; >> > + >> > + xfree(info->features[i]); >> > + info->features[i] = NULL; >> >> There's no need for the if() here. And I'm sure this was pointed out >> already (perhaps in a different context). >> > There may be NULL member in features array. Features array contains all > features, including L3 CAT, CDP and L2 CAT. But on some machines, they > may only support L3 CAT but do not support CDP and L2 CAT. So, the features > array only has L3 CAT member in it and all other members are all NULL. That > is the reason we must check if the member is NULL or not. No, and this has been explained before: xfree() happily accepts NULL pointers. >> > +static bool feat_init_done(const struct psr_socket_info *info) >> > +{ >> > + unsigned int i; >> > + >> > + for ( i = 0; i < PSR_SOCKET_MAX_FEAT; i++ ) >> > + { >> > + if ( !info->features[i] ) >> > + continue; >> > + >> > + return true; >> > + } >> > + >> > + return false; >> > +} >> >> At the first glance this is a very strange function. >> > I used 'feat_mask' before to check if any feature has been initialized. > Per your comment in later patch, I want to define a flag to represent it. > Is that acceptable to you? Excuse me, but if I suggested it there, how can it not be acceptable to me? >> > +/* CAT common functions implementation. */ >> > +static void cat_init_feature(const struct cpuid_leaf *regs, >> > + struct feat_node *feat, >> > + struct psr_socket_info *info, >> > + enum psr_feat_type type) >> > +{ >> > + unsigned int socket, i; >> > + >> > + /* No valid value so do not enable feature. */ >> > + if ( !regs->a || !regs->d ) >> > + return; >> > + >> > + feat->props->cbm_len = (regs->a & CAT_CBM_LEN_MASK) + 1; >> > + feat->props->cos_max = min(opt_cos_max, regs->d & CAT_COS_MAX_MASK); >> > + >> > + switch ( type ) >> > + { >> > + case PSR_SOCKET_L3_CAT: >> > + /* cos=0 is reserved as default cbm(all bits within cbm_len are >> > 1). */ >> > + feat->cos_reg_val[0] = cat_default_val(feat->props->cbm_len); >> > + >> > + /* >> > + * To handle cpu offline and then online case, we need restore >> > MSRs to >> > + * default values. >> > + */ >> > + for ( i = 1; i <= feat->props->cos_max; i++ ) >> > + { >> > + wrmsrl(MSR_IA32_PSR_L3_MASK(i), feat->cos_reg_val[0]); >> > + feat->cos_reg_val[i] = feat->cos_reg_val[0]; >> > + } >> >> I continue to have difficulty with this: Why is offline-then-online >> any different from first-time-online? Why wouldn't setting the > > May remove this comment. Per current codes, the MSRs are written to default > values no matter first time or not. > >> registers to their intended values not be taken care of by >> context switch code, once vCPU-s get scheduled onto the newly >> onlined CPU? >> > cat_init_feature is only called when the first CPU on a socket is online. > The MSRs to set are per socket. So, we only need set it once when socket > is online. This does not answer my question. Once again - why does this need doing here explicitly, rather than relying on the needed values being loaded when the first vCPU gets scheduled onto one of the pCPU-s of this socket? >> > static void psr_cpu_init(void) >> > { >> > + struct psr_socket_info *info; >> > + unsigned int socket; >> > + unsigned int cpu = smp_processor_id(); >> > + struct feat_node *feat; >> > + struct cpuid_leaf regs; >> > + >> > + if ( !psr_alloc_feat_enabled() || !boot_cpu_has(X86_FEATURE_PQE) ) >> > + goto assoc_init; >> > + >> > + if ( boot_cpu_data.cpuid_level < PSR_CPUID_LEVEL_CAT ) >> > + { >> > + setup_clear_cpu_cap(X86_FEATURE_PQE); >> > + goto assoc_init; >> > + } >> > + >> > + socket = cpu_to_socket(cpu); >> > + info = socket_info + socket; >> > + if ( feat_init_done(info) ) >> > + goto assoc_init; >> >> Hmm, so you bail here if any of the features was already set up. >> But you don't bail if none of the features were available as the >> reason for the setup not having been done before. I think this >> can be solved in a better way once we have the static props >> array: You need to do anything here only if the props slot is not >> NULL, but the feature slot is NULL. >> > As above comment, this check will be changed to check a flag if you have > no opinion. But, what is your conern here? Do you mind the 'goto'? Well, while with the intended flag introduction this discussion is mostly moot now - no, it's not the goto, it's the way of checking done. >> In any event you intentions are likely easier to understand for >> a reader if this single-use function was inlined here. >> > As you have observed, this 'feat_init_done' is used many times in later > patches. And (again mostly moot now) as expressed there, the further uses appear to want checks different from the one here. Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |