On Mon, May 11, 2015 at 8:11 AM, Dario Faggioli <dario.faggi...@citrix.com> wrote:
> On Thu, 2015-05-07 at 12:05 -0500, Chong Li wrote: > > Add two hypercalls(XEN_DOMCTL_SCHEDOP_getvcpuinfo/putvcpuinfo) to > get/set a domain's > > per-VCPU parameters. Hypercalls are handled in function rt_dom_cntl. > > > And that is because, right now, only code in sched_rt.c is able to deal > with per-vcpu parameters getting and setting. > > That's of course true, but these two new hypercalls are, potentially, > generic, i.e., other schedulers may want to use them at some point. So, > why not just put them in good shape for that from the beginning? > > To do so, you could with the new DOMCTLs in a similar way as > XEN_DOMCTL_SCHEDOP_{get,put}info are handled, and add a > new .adjust_vcpu(s?) hook in the scheduler interface. > > > diff --git a/xen/common/sched_rt.c b/xen/common/sched_rt.c > > index 7c39a9e..9add5a4 100644 > > --- a/xen/common/sched_rt.c > > +++ b/xen/common/sched_rt.c > > @@ -1085,6 +1085,9 @@ rt_dom_cntl( > > struct list_head *iter; > > unsigned long flags; > > int rc = 0; > > + xen_domctl_sched_rtds_params_t *local_sched; > > + int vcpu_index=0; > > > So, what's this vcpu_index intended meaning/usage? > The vcpu_index here equals vcpu_id. > > > @@ -1110,6 +1113,67 @@ rt_dom_cntl( > > } > > spin_unlock_irqrestore(&prv->lock, flags); > > break; > > + case XEN_DOMCTL_SCHEDOP_getvcpuinfo: > > + op->u.rtds.nr_vcpus = 0; > > + spin_lock_irqsave(&prv->lock, flags); > > + list_for_each( iter, &sdom->vcpu ) > > + vcpu_index++; > > > > + spin_unlock_irqrestore(&prv->lock, flags); > > > This gives you the number of vcpus of sdom, doesn't it? It feels rather > nasty (especially the lock being dropped and taken again below!). > > Aren't there other ways to get the same information that suits your > needs (e.g., d->max_vcpus)? If not, I think you should consider adding a > 'nr_vcpu' field in rt_dom, exactly as Credit2 is doing in csched2_dom. > > > + spin_lock_irqsave(&prv->lock, flags); > > + list_for_each( iter, &sdom->vcpu ) > > + { > > + struct rt_vcpu *svc = list_entry(iter, struct rt_vcpu, > sdom_elem); > > + > > + local_sched[vcpu_index].budget = svc->budget / MICROSECS(1); > > + local_sched[vcpu_index].period = svc->period / MICROSECS(1); > > + local_sched[vcpu_index].index = vcpu_index; > > + vcpu_index++; > > > And that's why I was asking about index. As Jan is pointing out already, > used like this, this index/vcpu_index is rather useless. > > I mean, you're passing up nr_vcpus structs in an array in which > the .index field of the i-eth element is equal to i. How is this > important? The caller could well iterate, count, and retrieve the > position of each elements by itself! > > What you probably are after, is the vcpu id, isn't it? > Yes, it is. Now I use vcpuid instead of vcpu_index. > > > + } > > + spin_unlock_irqrestore(&prv->lock, flags); > > + copy_to_guest(op->u.rtds.vcpus, local_sched, vcpu_index); > > > I'm sure we want some checks about whether we are overflowing the > userspace provided buffer (and something similar below, for put). I > appreciate that you, in this patch series, are only calling this from > libxl, which properly dimension things, etc., but that can not always be > the case. > > There are several examples in the code base on the route to take for > similar operations. For example, you can try to do some checks and only > fill as much elements as the buffer allows, or you can give a special > semantic to calling the hypercall with NULL/0 as parameters, i.e., use > that for asking Xen about the proper sizes, etc. > > Have a look at how XEN_SYSCTL_numainfo and XEN_SYSCTL_cputopoinfo are > implemented (in Xen, but also in libxc and libxl, to properly understand > things). > > > + case XEN_DOMCTL_SCHEDOP_putvcpuinfo: > > + local_sched = xzalloc_array(xen_domctl_sched_rtds_params_t, > > + op->u.rtds.nr_vcpus); > > + if( local_sched == NULL ) > > + { > > + return -ENOMEM; > > + } > > + copy_from_guest(local_sched, op->u.rtds.vcpus, > op->u.rtds.nr_vcpus); > > + > > + for( i = 0; i < op->u.rtds.nr_vcpus; i++ ) > > + { > > + vcpu_index = 0; > > + spin_lock_irqsave(&prv->lock, flags); > > + list_for_each( iter, &sdom->vcpu ) > > + { > > > But why the nested loop? I think this is still that 'index' thing > causing problems. If you use vcpu numbers/ids, you can just use the > d->vcpu[] array, and get rid of the one of the for-s! > > Look at, for instance, XEN_DOMCTL_{set,get}vcpuaffinity. You're after > something that is pretty similar (i.e., altering a per-vcpu property), > you just want to do it on more than one vcpu at a time. > > > + struct rt_vcpu *svc = list_entry(iter, struct rt_vcpu, > sdom_elem); > > + if ( local_sched[i].index == vcpu_index ) > > + { > > + if ( local_sched[i].period <= 0 || > local_sched[i].budget <= 0 ) > > + return -EINVAL; > > + > > + svc->period = MICROSECS(local_sched[i].period); > > + svc->budget = MICROSECS(local_sched[i].budget); > > + break; > > + } > > + vcpu_index++; > > + } > > + spin_unlock_irqrestore(&prv->lock, flags); > > > Lock dropping and reacquiring again... This is less scary than above, > but doing it is pretty much always asking for troubles. Of course there > are legitimate use case of such a pattern, but I'd always ask myself 6 > or 7 times whether I'm dealing with one of those before actually using > it. 99% of them, you aren't. :-P > > Anyway, if you go with vcpu ids instead than with index, that is not a > problem, as there will be only one loop. > > > diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h > > index 10b51ef..490a6b6 100644 > > --- a/xen/include/public/domctl.h > > +++ b/xen/include/public/domctl.h > > @@ -342,6 +342,16 @@ struct xen_domctl_max_vcpus { > > typedef struct xen_domctl_max_vcpus xen_domctl_max_vcpus_t; > > DEFINE_XEN_GUEST_HANDLE(xen_domctl_max_vcpus_t); > > > > +struct xen_domctl_sched_rtds_params { > > + /* vcpus' info */ > > + uint64_t period; > > + uint64_t budget; > > > We settled for uint32_t while reviewing RTDS patches, and nothing > changed since then, as far as I can tell, so you should just use that as > width. > > > + uint16_t index; > > + uint16_t padding[3]; > > +}; > > +typedef struct xen_domctl_sched_rtds_params > xen_domctl_sched_rtds_params_t; > > +DEFINE_XEN_GUEST_HANDLE(xen_domctl_sched_rtds_params_t); > > + > > > > /* XEN_DOMCTL_scheduler_op */ > > /* Scheduler types. */ > > @@ -351,9 +361,12 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_max_vcpus_t); > > #define XEN_SCHEDULER_ARINC653 7 > > #define XEN_SCHEDULER_RTDS 8 > > > > -/* Set or get info? */ > > +/* Set or get info */ > > #define XEN_DOMCTL_SCHEDOP_putinfo 0 > > #define XEN_DOMCTL_SCHEDOP_getinfo 1 > > +#define XEN_DOMCTL_SCHEDOP_getvcpuinfo 2 > > +#define XEN_DOMCTL_SCHEDOP_putvcpuinfo 3 > > + > > struct xen_domctl_scheduler_op { > > uint32_t sched_id; /* XEN_SCHEDULER_* */ > > uint32_t cmd; /* XEN_DOMCTL_SCHEDOP_* */ > > @@ -373,8 +386,11 @@ struct xen_domctl_scheduler_op { > > uint16_t weight; > > } credit2; > > struct xen_domctl_sched_rtds { > > - uint32_t period; > > - uint32_t budget; > > + uint64_t period; > > + uint64_t budget; > > > Ditto. > > > + XEN_GUEST_HANDLE_64(xen_domctl_sched_rtds_params_t) vcpus; > > + uint16_t nr_vcpus; > > + uint16_t padding[3]; > > } rtds; > > > I don't like this. I find it both confusing and redundant as an > interface. > > In fact, this way, we have both budget, period and an array of budget > and period. What is the meaning of this? What if one fills both the > budget and period members and a couple of array elements? > > You should either adapt xen_domctl_sched_rtds to be able to deal with > both per-domain ad per-vcpu parameter getting/setting, but with less > redundancy and a more clear and better defined semantic, or introduce a > new member of the union u to with the array (and the number of elements) > in it (e.g., xen_domctl_sched_rtds_vcpus), or (and that's what I like > most) just go with something completely new, e.g., > > #define XEN_DOMCTL_SCHEDOP_getvcpuinfo 2 > #define XEN_DOMCTL_SCHEDOP_putvcpuinfo 3 > struct xen_domctl_scheduler_vcpu_op { > uint32_t cmd; /* XEN_DOMCTL_SCHEDOP_{get,put}vcpuinfo */ > union { > struct xen_domctl_sched_rtds_vcpus { > XEN_GUEST_HANDLE_64(xen_domctl_sched_rtds_params_t) vcpus > uint16_t nr_vcpus; > uint16_t padding[3]; > } rtds; > } u; > } > Yes, I think so. These changes will appear in the next version of the patch. > > Regards, > Dario > > -- Chong Li Department of Computer Science and Engineering Washington University in St.louis
_______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel