Skip to contentSkip to conversation

cpumask handling in libxc and python/xc

PATCH New Juergen Gross 1 participant 1 message Aug 3, 2010 Arm/actions semi architecture

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 cpumask handling in libxc and python/xc

Hi,

attached patch is a replacement for the patch I sent yesterday (use full-size cpumask for vcpu-pin), see

http://lists.xensource.com/archives/html/xen-devel/2010-08/msg00024.html

I found some more cpumask limitations to 64 cpus and some wrong usage (mix of bits/bytes at interfaces).

I'll post another patch based on this one soon to add cpupools to xl.

Juergen

Signature · 5 lines
Juergen Gross                 Principal Developer Operating Systems
TSP ES&S SWE OS6                       Telephone: +49 (0) 89 3222 2967
Fujitsu Technology Solutions              e-mail: [email protected]
Domagkstr. 28                           Internet: ts.fujitsu.com
D-80807 Muenchen                 Company details: ts.fujitsu.com/imprint.html
Signed-off-by [email protected]
tools/libxc/xc_cpupool.c +66 -40
diff -r 9f49667fec71 tools/libxc/xc_cpupool.c
@@ -18,6 +18,20 @@ static int do_sysctl_save(xc_interface *
     } while ( (ret < 0) && (errno == EAGAIN) );
 
     return ret;
+}
+
+static int get_cpumap_size(xc_interface *xch)
+{
+    static int max_phys_cpus = 0;
+    xc_physinfo_t physinfo;
+
+    if ( max_phys_cpus )
+        return max_phys_cpus;
+
+    if ( !xc_physinfo(xch, &physinfo) )
+        max_phys_cpus = physinfo.max_phys_cpus;
+
+    return max_phys_cpus;
 }
 
 int xc_cpupool_create(xc_interface *xch,
@@ -50,50 +64,58 @@ int xc_cpupool_destroy(xc_interface *xch
     return do_sysctl_save(xch, &sysctl);
 }
 
-int xc_cpupool_getinfo(xc_interface *xch, 
-                       uint32_t first_poolid,
-                       uint32_t n_max, 
-                       xc_cpupoolinfo_t *info)
+xc_cpupoolinfo_t *xc_cpupool_getinfo(xc_interface *xch, 
+                       uint32_t first_poolid)
 {
     int err = 0;
-    int p;
-    uint32_t poolid = first_poolid;
-    uint8_t local[sizeof (info->cpumap)];
+    xc_cpupoolinfo_t *info;
+    uint8_t *local;
+    int local_size;
+    int cpumap_size;
+    int n_cpu;
+    int size;
     DECLARE_SYSCTL;
 
-    memset(info, 0, n_max * sizeof(xc_cpupoolinfo_t));
+    n_cpu = get_cpumap_size(xch);
+    local_size = (n_cpu + 8) / 8;
+    cpumap_size = (n_cpu + 63) / 64;
+    size = sizeof(xc_cpupoolinfo_t) + cpumap_size * 8 + local_size;
+    info = malloc(size);
+    if ( !info )
+        return NULL;
 
-    for (p = 0; p < n_max; p++)
+    memset(info, 0, size);
+    info->cpumap_size = n_cpu;
+    info->cpumap = (uint64_t *)(info + 1);
+    local = (uint8_t *)(info->cpumap + cpumap_size);
+
+    sysctl.cmd = XEN_SYSCTL_cpupool_op;
+    sysctl.u.cpupool_op.op = XEN_SYSCTL_CPUPOOL_OP_INFO;
+    sysctl.u.cpupool_op.cpupool_id = first_poolid;
+    set_xen_guest_handle(sysctl.u.cpupool_op.cpumap.bitmap, local);
+    sysctl.u.cpupool_op.cpumap.nr_cpus = n_cpu;
+
+    if ( (err = lock_pages(local, local_size)) != 0 )
     {
-        sysctl.cmd = XEN_SYSCTL_cpupool_op;
-        sysctl.u.cpupool_op.op = XEN_SYSCTL_CPUPOOL_OP_INFO;
-        sysctl.u.cpupool_op.cpupool_id = poolid;
-        set_xen_guest_handle(sysctl.u.cpupool_op.cpumap.bitmap, local);
-        sysctl.u.cpupool_op.cpumap.nr_cpus = sizeof(info->cpumap) * 8;
+        PERROR("Could not lock memory for Xen hypercall");
+        free(info);
+        return NULL;
+    }
+    err = do_sysctl_save(xch, &sysctl);
+    unlock_pages(local, local_size);
 
-        if ( (err = lock_pages(local, sizeof(local))) != 0 )
-        {
-            PERROR("Could not lock memory for Xen hypercall");
-            break;
-        }
-        err = do_sysctl_save(xch, &sysctl);
-        unlock_pages(local, sizeof (local));
-
-        if ( err < 0 )
-            break;
-
-        info->cpupool_id = sysctl.u.cpupool_op.cpupool_id;
-        info->sched_id = sysctl.u.cpupool_op.sched_id;
-        info->n_dom = sysctl.u.cpupool_op.n_dom;
-        bitmap_byte_to_64(&(info->cpumap), local, sizeof(local) * 8);
-        poolid = sysctl.u.cpupool_op.cpupool_id + 1;
-        info++;
+    if ( err < 0 )
+    {
+        free(info);
+        return NULL;
     }
 
-    if ( p == 0 )
-        return err;
+    info->cpupool_id = sysctl.u.cpupool_op.cpupool_id;
+    info->sched_id = sysctl.u.cpupool_op.sched_id;
+    info->n_dom = sysctl.u.cpupool_op.n_dom;
+    bitmap_byte_to_64(info->cpumap, local, local_size * 8);
 
-    return p;
+    return info;
 }
 
 int xc_cpupool_addcpu(xc_interface *xch,
@@ -136,30 +158,34 @@ int xc_cpupool_movedomain(xc_interface *
 }
 
 int xc_cpupool_freeinfo(xc_interface *xch,
-                        uint64_t *cpumap)
+                        uint64_t *cpumap,
+                        int cpusize)
 {
     int err;
-    uint8_t local[sizeof (*cpumap)];
+    uint8_t *local;
+    int loc_size;
     DECLARE_SYSCTL;
 
+    loc_size = (cpusize + 7) / 8;
+    local = malloc(loc_size);
     sysctl.cmd = XEN_SYSCTL_cpupool_op;
     sysctl.u.cpupool_op.op = XEN_SYSCTL_CPUPOOL_OP_FREEINFO;
     set_xen_guest_handle(sysctl.u.cpupool_op.cpumap.bitmap, local);
-    sysctl.u.cpupool_op.cpumap.nr_cpus = sizeof(*cpumap) * 8;
+    sysctl.u.cpupool_op.cpumap.nr_cpus = cpusize;
 
-    if ( (err = lock_pages(local, sizeof(local))) != 0 )
+    if ( (err = lock_pages(local, loc_size)) != 0 )
     {
         PERROR("Could not lock memory for Xen hypercall");
         return err;
     }
 
     err = do_sysctl_save(xch, &sysctl);
-    unlock_pages(local, sizeof (local));
+    unlock_pages(local, loc_size);
 
     if (err < 0)
         return err;
 
-    bitmap_byte_to_64(cpumap, local, sizeof(local) * 8);
+    bitmap_byte_to_64(cpumap, local, cpusize);
 
     return 0;
 }
tools/libxc/xc_domain.c +15 -10
diff -r 9f49667fec71 tools/libxc/xc_domain.c
@@ -102,7 +102,10 @@ int xc_vcpu_setaffinity(xc_interface *xc
 {
     DECLARE_DOMCTL;
     int ret = -1;
-    uint8_t *local = malloc(cpusize); 
+    uint8_t *local;
+    int loc_size = (cpusize + 7) / 8;
+
+    local = malloc(loc_size);
 
     if(local == NULL)
     {
@@ -113,13 +116,13 @@ int xc_vcpu_setaffinity(xc_interface *xc
     domctl.domain = (domid_t)domid;
     domctl.u.vcpuaffinity.vcpu    = vcpu;
 
-    bitmap_64_to_byte(local, cpumap, cpusize * 8);
+    bitmap_64_to_byte(local, cpumap, cpusize);
 
     set_xen_guest_handle(domctl.u.vcpuaffinity.cpumap.bitmap, local);
 
-    domctl.u.vcpuaffinity.cpumap.nr_cpus = cpusize * 8;
+    domctl.u.vcpuaffinity.cpumap.nr_cpus = cpusize;
     
-    if ( lock_pages(local, cpusize) != 0 )
+    if ( lock_pages(local, loc_size) != 0 )
     {
         PERROR("Could not lock memory for Xen hypercall");
         goto out;
@@ -127,7 +130,7 @@ int xc_vcpu_setaffinity(xc_interface *xc
 
     ret = do_domctl(xch, &domctl);
 
-    unlock_pages(local, cpusize);
+    unlock_pages(local, loc_size);
 
  out:
     free(local);
@@ -142,8 +145,10 @@ int xc_vcpu_getaffinity(xc_interface *xc
 {
     DECLARE_DOMCTL;
     int ret = -1;
-    uint8_t * local = malloc(cpusize);
+    uint8_t *local;
+    int loc_size = (cpusize + 7) / 8;
 
+    local = malloc(loc_size);
     if(local == NULL)
     {
         PERROR("Could not alloc memory for Xen hypercall");
@@ -156,9 +161,9 @@ int xc_vcpu_getaffinity(xc_interface *xc
 
 
     set_xen_guest_handle(domctl.u.vcpuaffinity.cpumap.bitmap, local);
-    domctl.u.vcpuaffinity.cpumap.nr_cpus = cpusize * 8;
+    domctl.u.vcpuaffinity.cpumap.nr_cpus = cpusize;
     
-    if ( lock_pages(local, sizeof(local)) != 0 )
+    if ( lock_pages(local, loc_size) != 0 )
     {
         PERROR("Could not lock memory for Xen hypercall");
         goto out;
@@ -166,8 +171,8 @@ int xc_vcpu_getaffinity(xc_interface *xc
 
     ret = do_domctl(xch, &domctl);
 
-    unlock_pages(local, sizeof (local));
-    bitmap_byte_to_64(cpumap, local, cpusize * 8);
+    unlock_pages(local, loc_size);
+    bitmap_byte_to_64(cpumap, local, cpusize);
 out:
     free(local);
     return ret;
tools/libxc/xenctrl.h +9 -10
diff -r 9f49667fec71 tools/libxc/xenctrl.h
@@ -547,7 +547,8 @@ typedef struct xc_cpupoolinfo {
     uint32_t cpupool_id;
     uint32_t sched_id;
     uint32_t n_dom;
-    uint64_t cpumap;
+    uint32_t cpumap_size;     /* max number of cpus in map */
+    uint64_t *cpumap;
 } xc_cpupoolinfo_t;
 
 /**
@@ -573,18 +574,14 @@ int xc_cpupool_destroy(xc_interface *xch
                        uint32_t poolid);
 
 /**
- * Get cpupool info. Returns info for up to the specified number of cpupools
+ * Get cpupool info. Returns info for next cpupool
  * starting at the given id.
  * @parm xc_handle a handle to an open hypervisor interface
  * @parm first_poolid lowest id for which info is returned
- * @parm n_max maximum number of cpupools to return info
- * @parm info pointer to xc_cpupoolinfo_t array
- * return number of cpupool infos
+ * return cpupool info ptr (obtained by malloc)
  */
-int xc_cpupool_getinfo(xc_interface *xch,
-                       uint32_t first_poolid,
-                       uint32_t n_max,
-                       xc_cpupoolinfo_t *info);
+xc_cpupoolinfo_t *xc_cpupool_getinfo(xc_interface *xch,
+                       uint32_t first_poolid);
 
 /**
  * Add cpu to a cpupool. cpu may be -1 indicating the first unassigned.
@@ -627,10 +624,12 @@ int xc_cpupool_movedomain(xc_interface *
  *
  * @parm xc_handle a handle to an open hypervisor interface
  * @parm cpumap pointer where to store the cpumap
+ * @parm cpusize size of cpumap array
  * return 0 on success, -1 on failure
  */
 int xc_cpupool_freeinfo(xc_interface *xch,
-                        uint64_t *cpumap);
+                        uint64_t *cpumap,
+                        int cpusize);
 
 
 /*
tools/libxl/libxl.c +14 -11
diff -r 9f49667fec71 tools/libxl/libxl.c
@@ -526,9 +526,10 @@ libxl_poolinfo * libxl_list_pool(libxl_c
 libxl_poolinfo * libxl_list_pool(libxl_ctx *ctx, int *nb_pool)
 {
     libxl_poolinfo *ptr;
-    int i, ret;
-    xc_cpupoolinfo_t info[256];
+    int i;
+    xc_cpupoolinfo_t *info;
     int size = 256;
+    uint32_t poolid;
 
     ptr = calloc(size, sizeof(libxl_poolinfo));
     if (!ptr) {
@@ -536,16 +537,17 @@ libxl_poolinfo * libxl_list_pool(libxl_c
         return NULL;
     }
 
-    ret = xc_cpupool_getinfo(ctx->xch, 0, 256, info);
-    if (ret<0) {
-        XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "getting cpupool info");
-        return NULL;
+    poolid = 0;
+    for (i = 0; i < size; i++) {
+        info = xc_cpupool_getinfo(ctx->xch, poolid);
+        if (info == NULL)
+            break;
+        ptr[i].poolid = info->cpupool_id;
+        poolid = info->cpupool_id + 1;
+        free(info);
     }
 
-    for (i = 0; i < ret; i++) {
-        ptr[i].poolid = info[i].cpupool_id;
-    }
-    *nb_pool = ret;
+    *nb_pool = i;
     return ptr;
 }
 
@@ -2480,6 +2482,7 @@ int libxl_get_physinfo(libxl_ctx *ctx, l
     physinfo->max_cpu_id = xcphysinfo.max_cpu_id;
     physinfo->nr_cpus = xcphysinfo.nr_cpus;
     physinfo->cpu_khz = xcphysinfo.cpu_khz;
+    physinfo->max_phys_cpus = xcphysinfo.max_phys_cpus;
     physinfo->total_pages = xcphysinfo.total_pages;
     physinfo->free_pages = xcphysinfo.free_pages;
     physinfo->scrub_pages = xcphysinfo.scrub_pages;
@@ -2551,7 +2554,7 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ct
         XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "getting physinfo");
         return NULL;
     }
-    *cpusize = physinfo.max_cpu_id + 1;
+    *cpusize = physinfo.max_phys_cpus;
     ptr = libxl_calloc(ctx, domaininfo.max_vcpu_id + 1, sizeof (libxl_vcpuinfo));
     if (!ptr) {
         return NULL;
tools/libxl/libxl.h +1 -0
diff -r 9f49667fec71 tools/libxl/libxl.h
@@ -582,6 +582,7 @@ typedef struct {
     uint32_t max_cpu_id;
     uint32_t nr_cpus;
     uint32_t cpu_khz;
+    uint32_t max_phys_cpus;
 
     uint64_t total_pages;
     uint64_t free_pages;
tools/libxl/xl_cmdimpl.c +4 -4
diff -r 9f49667fec71 tools/libxl/xl_cmdimpl.c
@@ -3341,7 +3341,7 @@ void vcpupin(char *d, const char *vcpu, 
         goto vcpupin_out1;
     }
 
-    cpumap = calloc(physinfo.max_cpu_id + 1, sizeof (uint64_t));
+    cpumap = calloc(physinfo.max_phys_cpus + 1, sizeof (uint64_t));
     if (!cpumap) {
         goto vcpupin_out1;
     }
@@ -3369,12 +3369,12 @@ void vcpupin(char *d, const char *vcpu, 
         }
     }
     else {
-        memset(cpumap, -1, sizeof (uint64_t) * (physinfo.max_cpu_id + 1));
+        memset(cpumap, -1, sizeof (uint64_t) * (physinfo.max_phys_cpus + 1));
     }
 
     if (vcpuid != -1) {
         if (libxl_set_vcpuaffinity(&ctx, domid, vcpuid,
-                                   cpumap, physinfo.max_cpu_id + 1) == -1) {
+                                   cpumap, physinfo.max_phys_cpus + 1) == -1) {
             fprintf(stderr, "Could not set affinity for vcpu `%u'.\n", vcpuid);
         }
     }
@@ -3385,7 +3385,7 @@ void vcpupin(char *d, const char *vcpu, 
         }
         for (; nb_vcpu > 0; --nb_vcpu, ++vcpuinfo) {
             if (libxl_set_vcpuaffinity(&ctx, domid, vcpuinfo->vcpuid,
-                                       cpumap, physinfo.max_cpu_id + 1) == -1) {
+                                       cpumap, physinfo.max_phys_cpus + 1) == -1) {
                 fprintf(stderr, "libxl_list_vcpu failed on vcpu `%u'.\n", vcpuinfo->vcpuid);
             }
         }
tools/python/xen/lowlevel/xc/xc.c +46 -36

152 lines not on this page · raw message

xen/arch/x86/sysctl.c +1 -0
diff -r 9f49667fec71 xen/arch/x86/sysctl.c
@@ -68,6 +68,7 @@ long arch_do_sysctl(
         pi->free_pages = avail_domheap_pages();
         pi->scrub_pages = 0;
         pi->cpu_khz = cpu_khz;
+        pi->max_phys_cpus = NR_CPUS;
         memcpy(pi->hw_cap, boot_cpu_data.x86_capability, NCAPINTS*4);
         if ( hvm_enabled )
             pi->capabilities |= XEN_SYSCTL_PHYSCAP_hvm;
xen/include/public/sysctl.h +1 -0
diff -r 9f49667fec71 xen/include/public/sysctl.h
@@ -96,6 +96,7 @@ struct xen_sysctl_physinfo {
     uint32_t nr_cpus, max_cpu_id;
     uint32_t nr_nodes, max_node_id;
     uint32_t cpu_khz;
+    uint32_t max_phys_cpus;
     uint64_aligned_t total_pages;
     uint64_aligned_t free_pages;
     uint64_aligned_t scrub_pages;

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel