On Mon, Nov 16, 2009 at 04:49:30PM +0000, Daniel P. Berrange wrote: > The cpu_set_t type can only cope with NR_CPUS <= 1024, beyond this > it is neccessary to use alternate CPU_SET maps with a dynamically > allocated CPU map > > * src/util/processinfo.c: Support new unlimited size CPU set type > --- > src/util/processinfo.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 84 insertions(+), 0 deletions(-) > > diff --git a/src/util/processinfo.c b/src/util/processinfo.c > index aaffd88..a0dac34 100644 > --- a/src/util/processinfo.c > +++ b/src/util/processinfo.c > @@ -38,6 +38,48 @@ int virProcessInfoSetAffinity(pid_t pid, > int maxcpu) > { > int i; > +#ifdef CPU_ALLOC > + /* New method dynamically allocates cpu mask, allowing unlimted cpus */ > + int numcpus = 1024; > + size_t masklen; > + cpu_set_t *mask; > + > + /* Not only may the statically allocated cpu_set_t be too small, > + * but there is no way to ask the kernel what size is large enough. > + * So you have no option but to pick a size, try, catch EINVAL, > + * enlarge, and re-try. > + * > + * http://lkml.org/lkml/2009/7/28/620 > + */ Urgh .... > +realloc: > + masklen = CPU_ALLOC_SIZE(numcpus); > + mask = CPU_ALLOC(numcpus); > + > + if (!mask) { > + virReportOOMError(NULL); > + return -1; > + } > + > + CPU_ZERO_S(masklen, mask); > + for (i = 0 ; i < maxcpu ; i++) { > + if (VIR_CPU_USABLE(map, maplen, 0, i)) > + CPU_SET_S(i, masklen, mask); > + } > + > + if (sched_setaffinity(pid, masklen, mask) < 0) { > + CPU_FREE(mask); > + if (errno == EINVAL && > + numcpus < (1024 << 8)) { /* 262144 cpus ought to be enough for anyone */ > + numcpus = numcpus << 2; let's just numcpus *= 2; or numcpus *= 4; it's not like we want to shave a microsecond, makes code less readable. > + goto realloc; > + } > + virReportSystemError(NULL, errno, > + _("cannot set CPU affinity on process %d"), pid); > + return -1; > + } > + CPU_FREE(mask); > +#else > + /* Legacy method uses a fixed size cpu mask, only allows upto 1024 cpus */ > cpu_set_t mask; > > CPU_ZERO(&mask); > @@ -51,6 +93,7 @@ int virProcessInfoSetAffinity(pid_t pid, > _("cannot set CPU affinity on process %d"), pid); > return -1; > } > +#endif > > return 0; > } > @@ -61,6 +104,46 @@ int virProcessInfoGetAffinity(pid_t pid, > int maxcpu) > { > int i; > +#ifdef CPU_ALLOC > + /* New method dynamically allocates cpu mask, allowing unlimted cpus */ > + int numcpus = 1024; > + size_t masklen; > + cpu_set_t *mask; > + > + /* Not only may the statically allocated cpu_set_t be too small, > + * but there is no way to ask the kernel what size is large enough. > + * So you have no option but to pick a size, try, catch EINVAL, > + * enlarge, and re-try. > + * > + * http://lkml.org/lkml/2009/7/28/620 > + */ > +realloc: > + masklen = CPU_ALLOC_SIZE(numcpus); > + mask = CPU_ALLOC(numcpus); > + > + if (!mask) { > + virReportOOMError(NULL); > + return -1; > + } > + > + CPU_ZERO_S(masklen, mask); > + if (sched_getaffinity(pid, masklen, mask) < 0) { > + CPU_FREE(mask); > + if (errno == EINVAL && > + numcpus < (1024 << 8)) { /* 262144 cpus ought to be enough for anyone */ > + numcpus = numcpus << 2; same I would also make numcpus a static variable, so that you don't repeat he loop each time you go though one of those APIs. > + goto realloc; > + } > + virReportSystemError(NULL, errno, > + _("cannot set CPU affinity on process %d"), pid); > + return -1; > + } > + > + for (i = 0 ; i < maxcpu ; i++) > + if (CPU_ISSET_S(i, masklen, mask)) > + VIR_USE_CPU(map, i); > +#else > + /* Legacy method uses a fixed size cpu mask, only allows upto 1024 cpus */ > cpu_set_t mask; > > CPU_ZERO(&mask); > @@ -73,6 +156,7 @@ int virProcessInfoGetAffinity(pid_t pid, > for (i = 0 ; i < maxcpu ; i++) > if (CPU_ISSET(i, &mask)) > VIR_USE_CPU(map, i); > +#endif > > return 0; > } That patch sounds less urgent might be worth waiting past 0.7.3, ACK though Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@xxxxxxxxxxxx | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list