[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 2/6] x86: add support for COS/CBM manangement
>>> On 13.03.15 at 11:13, <chao.p.peng@xxxxxxxxxxxxxxx> wrote: > --- a/xen/arch/x86/domctl.c > +++ b/xen/arch/x86/domctl.c > @@ -1324,6 +1324,24 @@ long arch_do_domctl( > } > break; > > + case XEN_DOMCTL_psr_cat_op: > + 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); > + break; > + case XEN_DOMCTL_PSR_CAT_OP_GET_L3_CBM: > + ret = psr_get_l3_cbm(d, domctl->u.psr_cat_op.target, > + &domctl->u.psr_cat_op.data); > + copyback = 1; > + break; > + default: > + ret = -ENOSYS; > + break; Please leave -ENOSYS to unimplemented hypercalls. -EOPNOTSUPP or -EINVAL seem to be better candidates here. > +static bool_t psr_check_cbm(unsigned int cbm_len, uint64_t cbm) > +{ > + unsigned int first_bit, zero_bit; > + > + /* Set bits should only in the range of [0, cbm_len) */ > + if ( cbm & (~0ull << cbm_len) ) > + return 0; > + > + /* At least two contiguous bits need to be set */ > + if ( hweight_long(cbm) < 2 ) > + return 0; > + > + first_bit = find_first_bit(&cbm, cbm_len); > + zero_bit = find_next_zero_bit(&cbm, cbm_len, first_bit); > + > + /* Set bits should be contiguous */ > + if ( find_next_bit(&cbm, cbm_len, zero_bit) < cbm_len ) You can't reliably invoke this without having checked that zero_bit is less than cbm_len (undefined behavior may result). > +static void write_l3_cbm(unsigned int socket, unsigned int cos, uint64_t cbm) > +{ > + struct cos_cbm_info info = {.cos = cos, .cbm = cbm }; > + > + if ( socket == cpu_to_socket(smp_processor_id()) ) > + do_write_l3_cbm(&info); > + else > + { > + unsigned int cpu = cpumask_check(get_socket_cpu(socket)); Isn't this going to trigger an assertion when the socket count got specified on the command line? > +int psr_set_l3_cbm(struct domain *d, unsigned int socket, uint64_t cbm) > +{ > + unsigned int old_cos, cos; > + struct psr_cat_cbm *map, *find; > + struct psr_cat_socket_info *info; > + int ret = get_cat_socket_info(socket, &info); > + > + if ( ret ) > + return ret; > + > + if ( !psr_check_cbm(info->cbm_len, cbm) ) > + return -EINVAL; > + > + old_cos = d->arch.psr_cos_ids[socket]; > + map = info->cos_cbm_map; > + find = NULL; > + > + for ( cos = 0; cos <= info->cos_max; cos++ ) > + { > + /* If still no found, then keep this unused one */ > + if ( !find && cos != 0 && map[cos].ref == 0 ) > + find = map + cos; > + else if ( map[cos].cbm == cbm ) > + { > + if ( unlikely(cos == old_cos) ) > + return -EEXIST; > + find = map + cos; > + break; > + } > + } Please add a comment explaining that this is implicitly serialized via the domctl lock. > +static void psr_free_cos(struct domain *d) > +{ > + unsigned int socket; > + unsigned int cos; > + struct psr_cat_cbm *map; > + > + if( !d->arch.psr_cos_ids ) > + return; Considering this check ... > + for ( socket = 0; socket < opt_socket_num; socket++) > + { > + cos = d->arch.psr_cos_ids[socket]; > + if ( cos == 0 ) > + continue; > + > + map = cat_socket_info[socket].cos_cbm_map; > + if ( map ) > + map[cos].ref--; > + } > + > + xfree(d->arch.psr_cos_ids); ... I think you want to clear the pointer here. > @@ -222,6 +422,17 @@ static void do_cat_cpu_init(void* data) > info->cbm_len = (eax & 0x1f) + 1; This means cbm_len <= 32. Why is cos_cbm_map[].cbm then a uint64_t? Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |