diff -r d6b7abf0d2d5 -r 6eba62092cb4 tools/libxc/xc_cpumap.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxc/xc_cpumap.c Thu Apr 01 13:06:14 2010 -0400 @@ -0,0 +1,88 @@ +#include "xc_cpumap.h" +#include + +/* Author : Dulloor (dulloor@xxxxxxxxxx) */ + +uint32_t xc_cpumap_next(int cpu, struct xenctl_cpumap *srcp) +{ + uint8_t *p, pos; + uint8_t *addr = xc_cpumap_bits(srcp); + uint32_t size = xc_cpumap_len(srcp); + uint32_t offset = cpu+1; /* Find the next set cpu */ + + if (offset >= size) + return size; + + p = addr + XC_BITMAP_BYTE(offset); + pos = XC_BITMAP_BYTE_OFFSET(offset); + + do { + for (; (pos < XC_BITS_PER_BYTE) && !((*p)&(1<> 1) & 0x55); + res = (res & 0x33) + ((res >> 2) & 0x33); + return (res & 0x0F) + ((res >> 4) & 0x0F); +} + +int __xc_cpumap_weight(struct xenctl_cpumap *srcp) +{ + const uint8_t *sp = xc_cpumap_bits(srcp); + int k, w = 0, lim = XC_BITS_TO_BYTES(xc_cpumap_len(srcp)); + for (k=0; k = 0; i -= CHUNKSZ) { + chunkmask = ((1ULL << chunksz) - 1); + word = i / XC_BITS_PER_BYTE; + bit = i % XC_BITS_PER_BYTE; + val = (maskp[word] >> bit) & chunkmask; + len += snprintf(buf+len, buflen-len, "%s%0*lx", sep, + (chunksz+3)/4, val); + chunksz = CHUNKSZ; + sep = ","; + } + return len; +} diff -r d6b7abf0d2d5 -r 6eba62092cb4 tools/libxc/xc_cpumap.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxc/xc_cpumap.h Thu Apr 01 13:06:14 2010 -0400 @@ -0,0 +1,144 @@ +#ifndef __XENCTL_CPUMAP_H +#define __XENCTL_CPUMAP_H + +#include "xc_private.h" +#include +#include + +#define XC_BITS_PER_BYTE 8 +#define XC_BITS_TO_BYTES(bits) \ + (((bits)+XC_BITS_PER_BYTE-1)/XC_BITS_PER_BYTE) +#define XC_BITMAP_BIT(nr) (1 << (nr)) +#define XC_BITMAP_BIT_MASK(nr) (1 << ((nr) % XC_BITS_PER_BYTE)) +#define XC_BITMAP_BYTE(nr) ((nr) / XC_BITS_PER_BYTE) +#define XC_BITMAP_BYTE_OFFSET(nr) ((nr) % XC_BITS_PER_BYTE) +#define XC_BITMAP_BYTE_MASK (0xFF) +#define XC_BITMAP_LAST_BYTE_MASK(nbits) \ + (((nbits) % XC_BITS_PER_BYTE) ? \ + ((1<<((nbits) % XC_BITS_PER_BYTE))-1) : \ + XC_BITMAP_BYTE_MASK) + +#define xc_cpumap_bits(maskp) \ + ({ uint8_t *bitmap; \ + get_xen_guest_handle(bitmap, (maskp)->bitmap); \ + bitmap; }) +#define xc_cpumap_len(maskp) ((maskp)->nr_cpus) + +/* For iterating over the cpus set in the cpumap */ +#define xc_for_each_cpu(cpu, mask) \ + __xc_for_each_cpu(cpu, &(mask)) +#define __xc_for_each_cpu(cpu, mask) \ + for ((cpu) = -1; \ + (cpu) = xc_cpumap_next((cpu), (mask)), \ + (cpu) < xc_cpumap_len(mask);) +extern uint32_t xc_cpumap_next(int n, struct xenctl_cpumap *srcp); + +#define xc_cpumap_set_cpu(cpu, dst) __xc_cpumap_set_cpu(cpu, &(dst)) +static inline void __xc_cpumap_set_cpu(int cpu, struct xenctl_cpumap *dstp) +{ + uint8_t mask = XC_BITMAP_BIT_MASK(cpu); + uint8_t *p = ((uint8_t *)xc_cpumap_bits(dstp)) + XC_BITMAP_BYTE(cpu); + *p |= mask; +} + +#define xc_cpumap_clear_cpu(cpu, dst) __xc_cpumap_clear_cpu(cpu, &(dst)) +static inline void __xc_cpumap_clear_cpu(int cpu, struct xenctl_cpumap *dstp) +{ + uint8_t mask = XC_BITMAP_BIT_MASK(cpu); + uint8_t *p = ((uint8_t *)xc_cpumap_bits(dstp)) + XC_BITMAP_BYTE(cpu); + *p &= ~mask; +} + +#define xc_cpumap_test_cpu(cpu, dst) __xc_cpumap_test_cpu(cpu, &(dst)) +static inline int __xc_cpumap_test_cpu(int cpu, struct xenctl_cpumap *dstp) +{ + uint8_t mask = XC_BITMAP_BIT_MASK(cpu); + uint8_t *p = ((uint8_t *)xc_cpumap_bits(dstp)) + XC_BITMAP_BYTE(cpu); + return *p & mask; +} + +#define xc_cpumap_setall(dst) __xc_cpumap_setall(&(dst)) +static inline void __xc_cpumap_setall(struct xenctl_cpumap *dstp) +{ + uint8_t *dp = xc_cpumap_bits(dstp); + int nbits = xc_cpumap_len(dstp); + size_t nbytes = XC_BITS_TO_BYTES(nbits); + if (nbytes > 1) + memset(dp, 0xff, nbytes); + dp[nbytes-1] = XC_BITMAP_LAST_BYTE_MASK(nbits); +} + +#define xc_cpumap_clearall(dst) __xc_cpumap_clearall(&(dst)) +static inline void __xc_cpumap_clearall(struct xenctl_cpumap *dstp) +{ + size_t nbytes = XC_BITS_TO_BYTES(xc_cpumap_len(dstp)); + if (nbytes > 1) + memset(xc_cpumap_bits(dstp), 0x00, nbytes); +} + +#define xc_cpumap_or(dst, src1, src2) \ + __xc_cpumap_or(&(dst), &(src1), &(src2)) +extern void __xc_cpumap_or(struct xenctl_cpumap *dstp, + struct xenctl_cpumap *src1p, struct xenctl_cpumap *src2p); + +#define xc_cpumap_weight(src) __xc_cpumap_weight(&(src)) +extern int __xc_cpumap_weight(struct xenctl_cpumap *srcp); + +#define xc_cpumap_snprintf(buf, len, src) \ + __xc_cpumap_snprintf((buf), (len), &(src)) +extern int __xc_cpumap_snprintf(char *buf, unsigned int len, + const struct xenctl_cpumap *srcp); + +/***********************************************************************/ + +static inline int +xc_cpumap_allocz_bitmap(int xc_handle, struct xenctl_cpumap *map) +{ + int nr_cpus; + uint8_t *bitmap; + xc_physinfo_t pinfo = { 0 }; + + if (xc_physinfo(xc_handle, &pinfo)) + goto failed; + nr_cpus = pinfo.max_cpu_id+1; + + if (!(bitmap = malloc(XC_BITS_TO_BYTES(nr_cpus)))) + goto failed; + memset(bitmap, 0x00, XC_BITS_TO_BYTES(nr_cpus)); + + map->nr_cpus = nr_cpus; + set_xen_guest_handle(map->bitmap, bitmap); + return 0; +failed: + return -1; +} + +static inline void +xc_cpumap_free_bitmap(struct xenctl_cpumap *map) +{ + uint8_t *bitmap; + get_xen_guest_handle(bitmap, map->bitmap); + free(bitmap); +} + +static inline int +xc_cpumap_lock_pages(struct xenctl_cpumap *map) +{ + uint8_t *bitmap; + uint32_t nr_bytes = XC_BITS_TO_BYTES(map->nr_cpus); + get_xen_guest_handle(bitmap, map->bitmap); + if (lock_pages(bitmap, nr_bytes)) + return -1; + return 0; +} + +static inline void +xc_cpumap_unlock_pages(struct xenctl_cpumap *map) +{ + uint8_t *bitmap; + uint32_t nr_bytes = XC_BITS_TO_BYTES(map->nr_cpus); + get_xen_guest_handle(bitmap, map->bitmap); + unlock_pages(bitmap, nr_bytes); +} + +#endif /* __XENCTL_CPUMAP_H */ diff -r d6b7abf0d2d5 -r 6eba62092cb4 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Wed Mar 31 19:39:58 2010 -0400 +++ b/tools/libxc/xenctrl.h Thu Apr 01 13:06:14 2010 -0400 @@ -309,13 +309,11 @@ int xc_vcpu_setaffinity(int xc_handle, uint32_t domid, int vcpu, - uint64_t *cpumap, - int cpusize); + struct xenctl_cpumap *cpumap); int xc_vcpu_getaffinity(int xc_handle, uint32_t domid, int vcpu, - uint64_t *cpumap, - int cpusize); + struct xenctl_cpumap *cpumap); /** * This function will return information about one or more domains. It is diff -r d6b7abf0d2d5 -r 6eba62092cb4 tools/python/xen/lowlevel/xc/xc.c --- a/tools/python/xen/lowlevel/xc/xc.c Wed Mar 31 19:39:58 2010 -0400 +++ b/tools/python/xen/lowlevel/xc/xc.c Thu Apr 01 13:06:14 2010 -0400 @@ -18,6 +18,7 @@ #include #include "xenctrl.h" +#include "xc_cpumap.h" #include #include #include "xc_dom.h" @@ -215,11 +216,8 @@ { uint32_t dom; int vcpu = 0, i; - uint64_t *cpumap; + struct xenctl_cpumap cpumap; PyObject *cpulist = NULL; - int nr_cpus, size; - xc_physinfo_t info = {0}; - uint64_t cpumap_size = sizeof(*cpumap); static char *kwd_list[] = { "domid", "vcpu", "cpumap", NULL }; @@ -227,36 +225,25 @@ &dom, &vcpu, &cpulist) ) return NULL; - if ( xc_physinfo(self->xc_handle, &info) != 0 ) + if (xc_cpumap_allocz_bitmap(self->xc_handle, &cpumap)) return pyxc_error_to_exception(); - nr_cpus = info.nr_cpus; - - size = (nr_cpus + cpumap_size * 8 - 1)/ (cpumap_size * 8); - cpumap = malloc(cpumap_size * size); - if(cpumap == NULL) - return pyxc_error_to_exception(); - if ( (cpulist != NULL) && PyList_Check(cpulist) ) { - for ( i = 0; i < size; i++) - { - cpumap[i] = 0ULL; - } for ( i = 0; i < PyList_Size(cpulist); i++ ) { long cpu = PyInt_AsLong(PyList_GetItem(cpulist, i)); - cpumap[cpu / (cpumap_size * 8)] |= (uint64_t)1 << (cpu % (cpumap_size * 8)); + xc_cpumap_set_cpu(cpu, cpumap); } - } - - if ( xc_vcpu_setaffinity(self->xc_handle, dom, vcpu, cpumap, size * cpumap_size) != 0 ) + } + + if ( xc_vcpu_setaffinity(self->xc_handle, dom, vcpu, &cpumap) != 0 ) { - free(cpumap); + xc_cpumap_free_bitmap(&cpumap); return pyxc_error_to_exception(); } Py_INCREF(zero); - free(cpumap); + xc_cpumap_free_bitmap(&cpumap); return zero; } @@ -375,10 +362,7 @@ uint32_t dom, vcpu = 0; xc_vcpuinfo_t info; int rc, i; - uint64_t *cpumap; - int nr_cpus, size; - xc_physinfo_t pinfo = { 0 }; - uint64_t cpumap_size = sizeof(*cpumap); + struct xenctl_cpumap cpumap; static char *kwd_list[] = { "domid", "vcpu", NULL }; @@ -386,23 +370,15 @@ &dom, &vcpu) ) return NULL; - if ( xc_physinfo(self->xc_handle, &pinfo) != 0 ) - return pyxc_error_to_exception(); - nr_cpus = pinfo.nr_cpus; - - rc = xc_vcpu_getinfo(self->xc_handle, dom, vcpu, &info); - if ( rc < 0 ) + if ( xc_cpumap_allocz_bitmap(self->xc_handle, &cpumap) ) return pyxc_error_to_exception(); - size = (nr_cpus + cpumap_size * 8 - 1)/ (cpumap_size * 8); - if((cpumap = malloc(cpumap_size * size)) == NULL) - return pyxc_error_to_exception(); - memset(cpumap, 0, cpumap_size * size); + if ((rc = xc_vcpu_getinfo(self->xc_handle, dom, vcpu, &info)) < 0) + return pyxc_error_to_exception(); - rc = xc_vcpu_getaffinity(self->xc_handle, dom, vcpu, cpumap, cpumap_size * size); - if ( rc < 0 ) + if ((rc = xc_vcpu_getaffinity(self->xc_handle, dom, vcpu, &cpumap)) < 0) { - free(cpumap); + xc_cpumap_free_bitmap(&cpumap); return pyxc_error_to_exception(); } @@ -413,18 +389,15 @@ "cpu_time", info.cpu_time, "cpu", info.cpu); cpulist = PyList_New(0); - for ( i = 0; i < nr_cpus; i++ ) + xc_for_each_cpu(i, cpumap) { - if (*(cpumap + i / (cpumap_size * 8)) & 1 ) { - PyObject *pyint = PyInt_FromLong(i); - PyList_Append(cpulist, pyint); - Py_DECREF(pyint); - } - cpumap[i / (cpumap_size * 8)] >>= 1; + PyObject *pyint = PyInt_FromLong(i); + PyList_Append(cpulist, pyint); + Py_DECREF(pyint); } PyDict_SetItemString(info_dict, "cpumap", cpulist); Py_DECREF(cpulist); - free(cpumap); + xc_cpumap_free_bitmap(&cpumap); return info_dict; }