|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v9 03/25] x86: refactor psr: implement main data structures.
On 17-03-27 00:20:58, Jan Beulich wrote:
> >>> On 27.03.17 at 04:38, <yi.y.sun@xxxxxxxxxxxxxxx> wrote:
> > On 17-03-24 10:19:30, Jan Beulich wrote:
> >> >>> On 16.03.17 at 12:07, <yi.y.sun@xxxxxxxxxxxxxxx> wrote:
> >> > +struct psr_cat_hw_info {
> >> > + unsigned int cbm_len;
> >> > + unsigned int cos_max;
> >>
> >> So you have this field, and ...
> >>
> >> > +};
> >> > +
> >> > +/*
> >> > + * This structure represents one feature.
> >> > + * feat_ops - Feature operation callback functions.
> >> > + * info - Feature HW info.
> >> > + * 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.
> >> > + * For CDP, two entries correspond to one COS_ID. E.g.
> >> > + * COS_ID=0 corresponds to cos_reg_val[0] (Data) and
> >> > + * cos_reg_val[1] (Code).
> >> > + * cos_num - COS registers number that feature uses in one time
> >> > access.
> >> > + */
> >> > +struct feat_node {
> >> > + /*
> >> > + * This structure defines feature operation callback functions.
> >> > Every feature
> >> > + * enabled MUST implement such callback functions and register them
> >> > to ops.
> >> > + *
> >> > + * Feature specific behaviors will be encapsulated into these
> >> > callback
> >> > + * functions. Then, the main flows will not be changed when
> >> > introducing a new
> >> > + * feature.
> >> > + */
> >> > + struct feat_ops {
> >> > + /* get_cos_max is used to get feature's cos_max. */
> >> > + unsigned int (*get_cos_max)(const struct feat_node *feat);
> >>
> >> ... you have this op, suggesting that you expect all features
> >> to have a cos_max. Why don't you then store the value in a
> >> field which is not per-feature, just like ...
> >>
> >> > + } ops;
> >> > +
> >> > + /* Encapsulate feature specific HW info here. */
> >> > + union {
> >> > + struct psr_cat_hw_info cat_info;
> >> > + } info;
> >> > +
> >> > + uint32_t cos_reg_val[MAX_COS_REG_CNT];
> >> > + unsigned int cos_num;
> >>
> >> ... this. I'm pretty sure that during v8 review I did say that
> >> this approach should be extended to all pieces of information
> >> where it can be applied.
> >>
> > I thought this when implementing v9. As cos_max is part of feature HW info,
> > I
> > thought it would be better to keep it in hw_info structure. Different
> > features
> > may have different hw_info, so the callback function is needed to get
> > cos_max.
> > Of course, we can keep a copy in feat_node but it is redundant. How do you
> > think?
>
> I don't follow - as long as you have a universal get_cos_max()
> accesses, and as long as what that function returns depends
> only on invariable things like CPUID output, I don't see why
> this needs to be a function instead of a data field. If some
> (perhaps future, theoretical) feature didn't want/need a
> get_cos_max() function, the presence of that hook would
> become questionable, yet it could surely become an optional
> hook. However, the hook being optional could as well be
> represented by the data field getting assigned a value of 0.
>
> Bottom line: Data which can be calculated at initialization
> time should be stored in a date object, rather than re-
> calculating it over and over.
>
The purpose to use the function is just not to define a redundant member
in 'struct feat_node'.
The cos_max is got in cat_init_feature in patch 5 and kept in the feature's
hw_info. The 'get_cos_max' only returns DIFFERENT features' cos_max without
recalculation. E.g:
CAT/CDP:
static unsigned int cat_get_cos_max(const struct feat_node *feat)
{
return feat->info.cat_info.cos_max;
}
MBA:
static unsigned int mba_get_cos_max(const struct feat_node *feat)
{
return feat->info.mba_info.cos_max;
}
But I think it is ok to add a new member in 'struct feat_node' to keep
cos_max for the feature.
What do you prefer? Thanks!
> >> > +struct psr_socket_info {
> >> > + /*
> >> > + * It maps to values defined in 'enum psr_feat_type' below. Value
> >> > in 'enum
> >> > + * psr_feat_type' means the bit position.
> >> > + * bit 0: L3 CAT
> >> > + * bit 1: L3 CDP
> >> > + * bit 2: L2 CAT
> >> > + */
> >> > + unsigned int feat_mask;
> >>
> >> Comment or not I don't understand what use this mask is, and
> >> this is again something which I'm pretty sure I've mentioned in
> >> v8 review, when the switch to ...
> >>
> >> > + struct feat_node *features[PSR_SOCKET_MAX_FEAT];
> >> > + unsigned int cos_ref[MAX_COS_REG_CNT];
> >>
> >> ... this array was suggested by Roger. The pointers in the
> >> array being non-NULL can - afaict - easily fulfill the role of
> >> the mask bits, so the latter are redundant.
> >>
> > I thought 'feat_mask' can facilitate things handling. If we check feature
> > array
> > to know if any feature has been initialized, we have to iterate the array.
> > But
> > it is simple to check 'feat_mask'.
> > 1. In 'psr_cpu_init', we can use it to check if initialization on the socket
> > has been done.
> > if ( info->feat_mask )
> > goto assoc_init;
> > 2. Same purpose in 'psr_assoc_init'.
> > if ( info->feat_mask )
> > psra->cos_mask = ((1ull << get_count_order(cos_max)) - 1) <<
> > PSR_ASSOC_REG_SHIFT;
> > 3. Same purpose in 'get_socket_info'.
> > if ( !socket_info[socket].feat_mask )
> >
> > What is your advice? Thanks!
>
> My advice is: Avoid redundant data as much as possible. Any such
> instance poses the risk of the two pieces of information going out
> of sync. (That isn't to say that there aren't cases where redundancy
> is almost unavoidable, e.g. in order to not overly complicate code,
> but that's pretty clearly not the case here).
>
If so, I think I should define a function to iterate the function array
to return TRUE if any feature has been set into the array. Then, use
this function to replace above checking points.
> Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |