[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v9 09/25] x86: refactor psr: L3 CAT: set value: implement framework.



On 17-03-27 03:59:32, Jan Beulich wrote:
> >>> On 16.03.17 at 12:07, <yi.y.sun@xxxxxxxxxxxxxxx> wrote:
> > --- a/xen/arch/x86/domctl.c
> > +++ b/xen/arch/x86/domctl.c
> > @@ -1437,21 +1437,21 @@ long arch_do_domctl(
> >          switch ( domctl->u.psr_cat_op.cmd )
> >          {
> >          case XEN_DOMCTL_PSR_CAT_OP_SET_L3_CBM:
> > -            ret = psr_set_l3_cbm(d, domctl->u.psr_cat_op.target,
> > -                                 domctl->u.psr_cat_op.data,
> > -                                 PSR_CBM_TYPE_L3);
> > +            ret = psr_set_val(d, domctl->u.psr_cat_op.target,
> > +                              (uint32_t)domctl->u.psr_cat_op.data,
> 
> The cast here is pointless, but - along the lines of the comment
> on the earlier patch - indicates a problem: You silently ignore the
> upper 32-bit the caller handed you. I think for forward
> compatibility it would be better if you checked they're zero. And
> in such a check you could then use a cast which I would not
> grumble about:
> 
>     if ( domctl->u.psr_cat_op.data != (uint32_t)domctl->u.psr_cat_op.data )
>         return -E...;
> 
Thanks for the suggestion! I will check the 'data' for both get_val/set_val.

> > --- a/xen/arch/x86/psr.c
> > +++ b/xen/arch/x86/psr.c
[...]

> > +static int insert_new_val_to_array(uint32_t val[],
> 
> insert_new_val_into_array()?
>
> (and whether "new" needs to be part of the name is then even
> questionable)
> 
Hmm, will remove 'new'.
 
> > +static int find_cos(const uint32_t val[], uint32_t array_len,
> > +                    enum psr_feat_type feat_type,
> > +                    const struct psr_socket_info *info)
> > +{
> > +    ASSERT(spin_is_locked((spinlock_t *)(&info->ref_lock)));
> 
> Excuse me, but no, this is another of those really bad casts. I
> guess you've added it to deal with info being pointer-to-const.
> In such a case you should instead drop the const, unless the
> consuming function can be made take a pointer-to-const (which
> isn't the case here, as check_lock() wants to write into the
> structure).
> 
Sorry for this. Will pass '&info->ref_lock' as a parameter into the function
to check it.

[...]
> > +    ref = info->cos_ref;
> > +
> > +    /*
> > +     * Step 1:
> > +     * Gather a value array to store all features cos_reg_val[old_cos].
> > +     * And, set the input new val into array according to the feature's
> > +     * position in array.
> > +     */
> > +    array_len = get_cos_num(info);
> > +    val_array = xzalloc_array(uint32_t, array_len);
> > +    if ( !val_array )
> > +        return -ENOMEM;
> > +
> > +    if ( (ret = gather_val_array(val_array, array_len, info, old_cos)) != 
> > 0 )
> > +        goto free_array;
> > +
> > +    if ( (ret = insert_new_val_to_array(val_array, array_len, info,
> > +                                        feat_type, type, val)) != 0 )
> > +        goto free_array;
> > +
> > +    spin_lock(&info->ref_lock);
> 
> Am I right in understanding that up to here operations are not
> risking to race merely because they're inside the domctl lock? If so,
> this needs to be spelled out, so we have a chance of noticing the
> dependency when we break up that lock (which we have plans for
> doing).
> 
Yes, you are right. I will add comments.

> > +    /*
> > +     * Step 2:
> > +     * Try to find if there is already a COS ID on which all features' 
> > values
> 
> Btw., I think this spelling ("features' values") is the right one - please
> go through and make it consistent everywhere, including in the patch
> description(s).
> 
Sure, I will do it.

> > +     * are same as the array. Then, we can reuse this COS ID.
> > +     */
> > +    cos = find_cos(val_array, array_len, feat_type, info);
> > +    if ( cos == old_cos )
> > +    {
> > +        ret = 0;
> > +        goto unlock_free_array;
> > +    }
> > +    else if ( cos >= 0 )
> 
> Pointless "else".
> 
Ok.

> > +        goto cos_found;
> 
> I think it would be better not to use goto here, other than for the
> error handling parts (where I don't really like it either, but I do
> accept it since others think that's the least ugly way).
> 
Sorry, I don't understand your meaning here. DYM I should goto error handling
route? 'cos >= 0' means a valid cos id has been found. Then, we should do the
'cos_found' process to handle ref and set cos id into domain.

> > +    /*
> > +     * Step 3:
> > +     * If fail to find, we need pick an available COS ID.
> 
> I think you've corrected this somewhat strange wording at the start
> of the comment here elsewhere already. I can only repeat that
> respective comments given for one location should always be
> extended to the entire series.
> 
I will try best to check entire series to keep it consistent.

> > +     * In fact, only COS ID which ref is 1 or 0 can be picked for current
> > +     * domain. If old_cos is not 0 and its ref==1, that means only current
> > +     * domain is using this old_cos ID. So, this old_cos ID certainly can
> > +     * be reused by current domain. Ref==0 means there is no any domain
> > +     * using this COS ID. So it can be used for current domain too.
> > +     */
> > +    cos = pick_avail_cos(info, val_array, array_len, old_cos, feat_type);
> > +    if ( cos < 0 )
> > +    {
> > +        ret = cos;
> > +        goto unlock_free_array;
> > +    }
> > +
> > +    /*
> > +     * Step 4:
> > +     * Write all features MSRs according to the COS ID.
> > +     */
> > +    ret = write_psr_msr(socket, cos, val, type, feat_type);
> > +    if ( ret )
> > +        goto unlock_free_array;
> > +
> > +cos_found:
> 
> Style (also the other labels further down).
> 
Will correct all of them.

> > +    /*
> > +     * Step 5:
> > +     * Update ref according to COS ID.
> > +     */
> > +    ref[cos]++;
> > +    ASSERT(!cos || ref[cos]);
> > +    ASSERT(!old_cos || ref[old_cos]);
> > +    ref[old_cos]--;
> > +    spin_unlock(&info->ref_lock);
> > +
> > +    /*
> > +     * Step 6:
> > +     * Save the COS ID into current domain's psr_cos_ids[] so that we can 
> > know
> > +     * which COS the domain is using on the socket. One domain can only use
> > +     * one COS ID at same time on each socket.
> > +     */
> > +    d->arch.psr_cos_ids[socket] = cos;
> > +    goto free_array;
> > +
> > +unlock_free_array:
> > +    spin_unlock(&info->ref_lock);
> > +free_array:
> > +    xfree(val_array);
> > +    return ret;
> > +}
> 
> I think overall things would look better if the successful path was the
> straight (goto-free) one.
> 
DYM change 'free_array' to 'free'?

> >  /* Called with domain lock held, no extra lock needed for 'psr_cos_ids' */
> >  static void psr_free_cos(struct domain *d)
> >  {
> > +    unsigned int socket, cos;
> > +
> > +    if ( !socket_info || !d->arch.psr_cos_ids )
> > +        return;
> 
> Can d->arch.psr_cos_ids be non-NULL when !socket_info? If not,
> check only the former with an if(), and ASSERT() the latter.
> 
In normal case, 'psr_cos_ids' should not be NULL when entering this function.
So, I think ASSERT() is a good option. Thanks!

> > +    /* Domain is destroied so its cos_ref should be decreased. */
> > +    for ( socket = 0; socket < nr_sockets; socket++ )
> > +    {
> > +        struct psr_socket_info *info;
> > +
> > +        /* cos 0 is default one which does not need be handled. */
> > +        cos = d->arch.psr_cos_ids[socket];
> > +        if ( cos == 0 )
> > +            continue;
> > +
> > +        /*
> > +         * If domain uses other cos ids, all corresponding refs must have 
> > been
> > +         * increased 1 for this domain. So, we need decrease them.
> 
> ... by 1 ... need to ... I also question the presence of the word
> "must" in here.
> 
After considering this comments again, I think the purpose of this piece of
codes has been explained outer the circle. So, I think this comment can be
removed. Is that OK for you?

> 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®.