[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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.