cpumask handling in libxc and python/xc
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
@@ -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 *xchreturn 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
@@ -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 *xcset_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
@@ -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
@@ -526,9 +526,10 @@ libxl_poolinfo * libxl_list_pool(libxl_clibxl_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_creturn 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_ctXL_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
@@ -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
@@ -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
@@ -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
@@ -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