<br><font size=2 face="sans-serif">I hope I will find a way to post the patches prepared by Michel Ponceau before the end of the week.</font>
<br><font size=2 face="sans-serif">Jean-Paul</font>
<br>
<br>
<br>
<br>
<table width=100%>
<tr valign=top>
<td>
<td><font size=1 face="sans-serif"><b>"Daniel P. Berrange" <berrange@redhat.com></b></font>
<br><font size=1 face="sans-serif">Envoyé par : libvir-list-bounces@redhat.com</font>
<p><font size=1 face="sans-serif">29/07/2006 09:35</font>
<br><font size=1 face="sans-serif">Veuillez répondre à "Daniel P. Berrange"</font>
<br>
<td><font size=1 face="Arial">        </font>
<br><font size=1 face="sans-serif">        Pour :        Jim Fehlig <jfehlig@novell.com></font>
<br><font size=1 face="sans-serif">        cc :        libvir-list@redhat.com</font>
<br><font size=1 face="sans-serif">        Objet :        Re: [Libvir] Re: Proposal : add 3 functions to Libvirt API,        for virtual CPUs</font></table>
<br>
<br><font size=2 face="Courier New">On Fri, Jul 28, 2006 at 03:18:17PM -0600, Jim Fehlig wrote:<br>
> Has any progress been made on this proposal?  I don't see anything in <br>
> current CVS.  This functionality would be useful for Xen-CIM project.<br>
<br>
IIRC Michel Ponceau might have started on some prototype code, but he<br>
didn't post it to the list yet & is apparently on vacation for another<br>
couple of weeks (according to his email auto-responder). If no one else<br>
has started work on it in the meantime, I'm planning to get working on<br>
it when I return from vacation Aug 4th since I also need it for the<br>
virt-manager application.<br>
<br>
Regards,<br>
Dan.<br>
<br>
> michel.ponceau@bull.net wrote:<br>
> ><br>
> >Corrections on proposal:<br>
> >1) PinVcpus<br>
> >Replace:<br>
> > * @cpumap: pointer to a bit map of real CPUs (format in virVcpuInfo)<br>
> >* @maplen: length of cpumap, in 8-bit bytes<br>
> >by:<br>
> > * @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes).<br>
> > *        Each bit set to 1 means that corresponding CPU is usable.<br>
> > *        Bytes are stored in little-endian order: CPU0-7, 8-15...<br>
> > *        In each byte, lowest CPU number is least significant bit.<br>
> > * @maplen: number of bytes in cpumap, from 1 up to size of CPU map in<br>
> > *        underlying virtualization system (Xen...).<br>
> > *        If maplen < size, missing bytes are set to zero.<br>
> > *        If maplen > size, failure code is returned.<br>
> ><br>
> >2) GetVcpu<br>
> >Add 4rth argument:<br>
> > * @maplen: number of bytes in cpumap field of virVcpuInfo<br>
> >virDomainGetVcpus(virDomainPtr domain, virVcpuInfoPtr info, int <br>
> >maxinfo, int maplen)<br>
> ><br>
> >3) Structure VcpuInfo<br>
> >Suppress:  #define VIR_MAX_CPUS        256<br>
> >Replace:<br>
> >    unsigned char cpumap[VIR_MAX_CPUS/8]; /* Bit map of usable real CPUs.<br>
> >by:<br>
> >    unsigned char cpumap[];        /* Bit map of usable real CPUs.<br>
> >        Variable length: it may be less or greater than size of CPU <br>
> >map in<br>
> >        underlying virtualization system (Xen...).<br>
> ><br>
> >4) Accessor macros: to be defined later.<br>
> ><br>
> >Veuillez répondre à veillard@redhat.com<br>
> ><br>
> >Pour :        michel.ponceau@bull.net<br>
> >cc :        libvir-list@redhat.com<br>
> >Objet :        Re: Proposal : add 3 functions to Libvirt API, for <br>
> >virtual CPUs<br>
> ><br>
> >On Fri, Jun 30, 2006 at 04:00:45PM +0200, michel.ponceau@bull.net wrote:<br>
> >> For our administration, we need the following actions, while concerned<br>
> >> domain is running:<br>
> >> 1) Change the number of virtual CPUs.<br>
> >> 2) Change the pinning (affinity) of a virtual CPU on real CPUs.<br>
> >> 3) Get detailed information for each virtual CPU.<br>
> >> Currently there is no Libvirt function provided for that. We suggest to<br>
> >> add the following 3 functions (in libvirt.c):<br>
> >> /**<br>
> >>  * virDomainSetVcpus:<br>
> >>  * @domain: pointer to domain object, or NULL for Domain0<br>
> >>  * @nvcpus: the new number of virtual CPUs for this domain<br>
> >>  *<br>
> >>  * Dynamically change the number of virtual CPUs used by the domain.<br>
> >>  * Note that this call may fail if the underlying virtualization<br>
> >> hypervisor<br>
> >>  * does not support it or if growing the number is arbitrary limited.<br>
> >>  * This function requires priviledged access to the hypervisor.<br>
> >>  *<br>
> >>  * Returns 0 in case of success, -1 in case of failure.<br>
> >>  */<br>
> >> int virDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)<br>
> ><br>
> > okay<br>
> ><br>
> >> /**<br>
> >>  * virDomainPinVcpu:<br>
> >>  * @domain: pointer to domain object, or NULL for Domain0<br>
> >>  * @vcpu: virtual CPU number<br>
> >>  * @cpumap: pointer to a bit map of real CPUs (format in virVcpuInfo)<br>
> >>  * @maplen: length of cpumap, in 8-bit bytes<br>
> >>  *<br>
> >>  * Dynamically change the real CPUs which can be allocated to a virtual<br>
> >> CPU.<br>
> >>  * This function requires priviledged access to the hypervisor.<br>
> >>  *<br>
> >>  * Returns 0 in case of success, -1 in case of failure.<br>
> >>  */<br>
> >> int virDomainPinVcpu(virDomainPtr domain, unsigned int vcpu,<br>
> >>                  unsigned char *cpumap, int maplen)<br>
> ><br>
> > Can you explain more clearly what is the format of cpumap ? An example<br>
> >would be welcome, and that would be needed for the doc and maybe testing.<br>
> >What would happen if maplen is < or > than the number of CPU divided <br>
> >by 8 ?<br>
> ><br>
> >> /**<br>
> >>  * virDomainGetVcpus:<br>
> >>  * @domain: pointer to domain object, or NULL for Domain0<br>
> >>  * @info: pointer to an array of virVcpuInfo structures<br>
> >>  * @maxinfo: number of structures in info array<br>
> >>  *<br>
> >>  * Extract information about virtual CPUs of a domain, store it in info<br>
> >> array.<br>
> >>  *<br>
> >>  * Returns the number of info filled in case of success, -1 in case of<br>
> >> failure.<br>
> >>  */<br>
> >> int virDomainGetVcpus(virDomainPtr domain, virVcpuInfoPtr info, int<br>
> >> maxinfo)<br>
> ><br>
> > Hum ... now the problem with that API entry point is that we 'burn' the<br>
> >maximum 256 processors in the ABI, i.e. if we ever need to go past 256<br>
> >client and servers need to be recompiled. Maybe this is not a real problem<br>
> >in practice but that's annoying. Is there existing APIs doing this kind<br>
> >of things (in POSIX for example), and what hard limit did they use ?<br>
> > Maybe<br>
> > int virDomainGetVcpusNr(virDomainPtr domain, int nr, virVcpuInfoPtr info,<br>
> >                         int maxCPU);<br>
> >Where the maxCPU is defined by the client as the number of real CPU<br>
> >it defined in its virVcpuInfoPtr and then an iteration over the virtual<br>
> >CPU defined in the domain is possible too.<br>
> >Of course if the domain uses many virtual CPUs this would become expensive<br>
> >but somehow I don't see that being the common use, I would rather guess<br>
> >the domains created use a few CPUs even if instantiated on a very <br>
> >large machine.<br>
> >This<br>
> ><br>
> ><br>
> >> with the following structure (in libvirt.h):<br>
> >> /**<br>
> >>  * virVcpuInfo: structure for information about a virtual CPU in a <br>
> >domain.<br>
> >>  */<br>
> >> #define VIR_MAX_CPUS            256<br>
> ><br>
> > Hum, there is already NUMA machines with more than 256 processors,<br>
> >it's annoying to define an API limit when you know it is already <br>
> >breakable.<br>
> ><br>
> >> typedef enum {<br>
> >>     VIR_VCPU_OFFLINE    = 0,    /* the virtual CPU is offline */<br>
> >>     VIR_VCPU_RUNNING    = 1,    /* the virtual CPU is running */<br>
> >>     VIR_VCPU_BLOCKED    = 2,    /* the virtual CPU is blocked on <br>
> >resource<br>
> >> */<br>
> >> } virVcpuState;<br>
> >><br>
> >> typedef struct _virVcpuInfo virVcpuInfo;<br>
> >> struct _virVcpuInfo {<br>
> >>     unsigned int number;        /* virtual CPU number */<br>
> >>     int state;                  /* value from virVcpuState */<br>
> >>     unsigned long long cpuTime; /* CPU time used, in nanoseconds */<br>
> >>     int cpu;                    /* real CPU number, or -1 if offline */<br>
> >>     unsigned char cpumap[VIR_MAX_CPUS/8]; /* Bit map of usable real <br>
> >CPUs.</font>
<br><font size=2 face="Courier New">> >>                 Each bit set to 1 means that corresponding CPU is <br>
> >usable.<br>
> >>                 Bytes are stored in little-endian order: CPU0-7, 8-15...<br>
> >>                 In each byte, lowest CPU number is least significant <br>
> >bit<br>
> >> */<br>
> >> };<br>
> >> typedef virVcpuInfo *virVcpuInfoPtr;<br>
> ><br>
> > Hum, maybe some accessors should be provided in the API, letting the <br>
> >client<br>
> >code handle access and having to take care of indianness issues <br>
> >doesn't feel<br>
> >very nice. Something like the FD_CLR/FD_ISSET/FD_SET/FD_ZERO equivalents<br>
> >when using the select() POSIx call.<br>
> ><br>
> >> I have successfully tried those functions via Xen hypervisor, except <br>
> >for<br>
> >> the first (SetVcpus) where hypervisor operation DOM0_MAX_VCPUS fails<br>
> >> (maybe it is not possible on a running domain ?). That function was<br>
> >> successful via Xen daemon.<br>
> ><br>
> >Maybe that operation requires more than one hypervisor call to <br>
> >actually enable<br>
> >the processors. The simpler would be to look at the code in xend about <br>
> >what's<br>
> >needed there, maybe the kernel need to be made aware of that and I <br>
> >would expect<br>
> >this to be a xenstore operation.<br>
> >At least we know we can fallback to xend if the hypervisor call <br>
> >doesn't work<br>
> >directly.<br>
> >I don't know if virDomainGetVcpus should really be mutated into<br>
> >virDomainGetVcpusNr, I would certainly like to be able to keep that API<br>
> >extensible for more than 256 CPUs. Maybe I'm just too cautious there,<br>
> ><br>
> > I would really like feedback from others on this issue !<br>
> >In the meantime sending the current set of patches you developped could<br>
> >allow to look closely at the 2 calls that I feel okay with.<br>
> ><br>
> >  thanks and sorry it took so long !<br>
> ><br>
> >Daniel<br>
> ><br>
> >-- <br>
> >Daniel Veillard      | Red Hat http://redhat.com/<br>
> >veillard@redhat.com  | libxml GNOME XML XSLT toolkit  http://xmlsoft.org/<br>
> >http://veillard.com/ | Rpmfind RPM search engine http://rpmfind.net/<br>
> ><br>
> >------------------------------------------------------------------------<br>
> ><br>
> >--<br>
> >Libvir-list mailing list<br>
> >Libvir-list@redhat.com<br>
> >https://www.redhat.com/mailman/listinfo/libvir-list<br>
> >  <br>
> <br>
> --<br>
> Libvir-list mailing list<br>
> Libvir-list@redhat.com<br>
> https://www.redhat.com/mailman/listinfo/libvir-list<br>
<br>
-- <br>
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|<br>
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|<br>
|=-               Projects: http://freshmeat.net/~danielpb/               -=|<br>
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| <br>
<br>
--<br>
Libvir-list mailing list<br>
Libvir-list@redhat.com<br>
https://www.redhat.com/mailman/listinfo/libvir-list<br>
</font>
<br>
<br>