allocate HVM guest memory with NUMA in mind
PATCH 3/4 allocate HVM guest memory with NUMA in mind
Signed-off-by Andre Przywara <[email protected]>
# HG changeset patch
# User [email protected]
# Date 1186563732 -7200
# Node ID f5e9f20109d9dc3c82bfadcedd4af77a35e8c5fb # Parent e730c1207604414f6f2779cc6adb213e3c1362eb allocate HVM guest memory according to NUMA setup
tools/libxc/xc_hvm_build.c +116 -7
@@ -152,8 +152,101 @@ static int loadelfimage(return rc; } +#define MAX_CPU_ID 255 + +static int setup_numa_affinity (int xc_handle,uint32_t dom,int numanodes) +{ +xc_physinfo_t physinfo; +xc_cpu_to_node_t *cpumap; +uint64_t *nodemasks; + +int nrcpus, i, node; +xc_dominfo_t dominfo; + + cpumap=(xc_cpu_to_node_t *)malloc (sizeof (xc_cpu_to_node_t)*MAX_CPU_ID ); +set_xen_guest_handle (physinfo.cpu_to_node, cpumap); + +xc_physinfo (xc_handle,&physinfo); + nrcpus = physinfo.threads_per_core * physinfo.cores_per_socket * + physinfo.sockets_per_node * physinfo.nr_nodes; + + nodemasks=malloc (sizeof (uint64_t )*physinfo.nr_nodes); +memset (nodemasks,0 ,sizeof (uint64_t )*physinfo.nr_nodes); +for (i=0 ;i<nrcpus;i++) + { + nodemasks[cpumap[i]]|=(1 <<i); + } + +if (xc_domain_getinfo (xc_handle, dom,1 , &dominfo) !=1 ) + { +ERROR ("Unable to get platform info." ); +return -1 ; + } + +for (i=0 ;i<=dominfo.max_vcpu_id;i++) + { + node= ( i * numanodes ) / (dominfo.max_vcpu_id+1 ); +xc_vcpu_setaffinity (xc_handle, dom, i, nodemasks[node]); + } + +return 0 ; +} + +static int setup_numa_mem (int xc_handle,uint32_t dom,int nr_pages, +xen_pfn_t *page_array,int numanodes ) +{ +xc_physinfo_t physinfo; +xc_cpu_to_node_t *cpumap; + +int nrcpus, i, j, rc; +uint32_t firstcpu; +unsigned long offset; +unsigned long pages_per_node, curpages; + + cpumap=(xc_cpu_to_node_t *)malloc (sizeof (xc_cpu_to_node_t)*MAX_CPU_ID ); +set_xen_guest_handle (physinfo.cpu_to_node, cpumap); + + +xc_physinfo (xc_handle,&physinfo); + nrcpus = physinfo.threads_per_core * physinfo.cores_per_socket * + physinfo.sockets_per_node * physinfo.nr_nodes; + + offset =0xc0 ; + + pages_per_node=((nr_pages+0xFF )&(~0xFFUL ))/numanodes; + firstcpu=0 ; +for ( i=0 ; i<numanodes ; i++ ) + { +for ( j=0 ; j<nrcpus ; j++ ) + { +if ( cpumap[j] == i ) + { + firstcpu = j; +break ; + } + } + +if ( j == nrcpus ) firstcpu=0 ; + +if ( i == numanodes -1 ) + curpages = nr_pages - i * pages_per_node; +else curpages = pages_per_node; + +if ( i ==0 ) curpages -=0xc0 ; + + rc =xc_domain_memory_populate_physmap ( + xc_handle, dom, curpages,0 ,0 , firstcpu, + &page_array[offset]); + +if ( rc !=0 )return rc; + + offset+=curpages; + } +return 0 ; +} +static int setup_guest (int xc_handle, -uint32_t dom,int memsize, +uint32_t dom,int memsize,int numanodes,char *image,unsigned long image_size,vcpu_guest_context_either_t *ctxt) {
@@ -213,13 +306,24 @@ static int setup_guest(int xc_handle, rc =xc_domain_memory_populate_physmap ( xc_handle, dom,0xa0 ,0 ,0 ,XENMEM_DEFAULT_CPU , &page_array[0x00 ]);if ( rc ==0 ) - rc =xc_domain_memory_populate_physmap ( - xc_handle, dom, nr_pages -0xc0 ,0 ,0 ,XENMEM_DEFAULT_CPU , - &page_array[0xc0 ]); + { +if ( numanodes >0 ) + rc =setup_numa_mem (xc_handle, dom, nr_pages, page_array, + numanodes); +else + rc =xc_domain_memory_populate_physmap ( + xc_handle, dom, nr_pages -0xc0 ,0 ,0 ,XENMEM_DEFAULT_CPU , + &page_array[0xc0 ] ); + }if ( rc !=0 ) {PERROR ("Could not allocate memory for HVM guest.\n" ); goto error_out; + } + +if ( numanodes >0 ) + { +setup_numa_affinity (xc_handle, dom, numanodes); }if (loadelfimage (&elf, xc_handle, dom, page_array) !=0 )
@@ -288,6 +392,7 @@ static int xc_hvm_build_internal(int xc_static int xc_hvm_build_internal (int xc_handle,uint32_t domid,int memsize, +int numanodes,char *image,unsigned long image_size) {
@@ -303,7 +408,8 @@ static int xc_hvm_build_internal(int xc_memset (&ctxt,0 ,sizeof (ctxt)); -if (setup_guest (xc_handle, domid, memsize, image, image_size, &ctxt) <0 ) +if (setup_guest (xc_handle, domid, memsize, numanodes, + image, image_size, &ctxt) <0 ) { goto error_out; }
@@ -341,6 +447,7 @@ int xc_hvm_build(int xc_handle,int xc_hvm_build (int xc_handle,uint32_t domid,int memsize, +int numanodes,const char *image_name) {char *image;
@@ -351,7 +458,8 @@ int xc_hvm_build(int xc_handle, ((image = xc_read_image(image_name, &image_size)) == NULL) )return -1 ; - sts =xc_hvm_build_internal (xc_handle, domid, memsize, image, image_size); + sts =xc_hvm_build_internal (xc_handle, domid, memsize, numanodes, + image, image_size);free (image);
@@ -364,6 +472,7 @@ int xc_hvm_build_mem(int xc_handle,int xc_hvm_build_mem (int xc_handle,uint32_t domid,int memsize, +int numanodes,const char *image_buffer,unsigned long image_size) {
@@ -386,7 +495,7 @@ int xc_hvm_build_mem(int xc_handle,return -1 ; } - sts =xc_hvm_build_internal (xc_handle, domid, memsize, + sts =xc_hvm_build_internal (xc_handle, domid, memsize, numanodes, img, img_len);/* xc_inflate_buffer may return the original buffer pointer (for
tools/libxc/xenguest.h +2 -0
@@ -128,11 +128,13 @@ int xc_hvm_build(int xc_handle,int xc_hvm_build (int xc_handle,uint32_t domid,int memsize, +int numanodes,const char *image_name);int xc_hvm_build_mem (int xc_handle,uint32_t domid,int memsize, +int numanodes,const char *image_buffer,unsigned long image_size);
tools/libxc/xg_private.c +1 -0
@@ -192,6 +192,7 @@ __attribute__((weak))int xc_hvm_build (int xc_handle,uint32_t domid,int memsize, +int numanodes,const char *image_name) { errno =ENOSYS ;
tools/python/xen/lowlevel/xc/xc.c +1 -1
@@ -549,7 +549,7 @@ static PyObject *pyxc_hvm_build(XcObject &numanodes) )return NULL ; -if (xc_hvm_build (self->xc_handle, dom, memsize, image) !=0 ) +if (xc_hvm_build (self->xc_handle, dom, memsize, numanodes, image) !=0 )return pyxc_error_to_exception ();#if !defined(__ia64__)
xen/common/page_alloc.c +6 -2
@@ -806,8 +806,12 @@ struct page_info *__alloc_domheap_pages(if ( (zone_hi +PAGE_SHIFT ) >= dma_bitsize ) { - pg =alloc_heap_pages (dma_bitsize -PAGE_SHIFT , zone_hi, cpu, order); - +if (avail_heap_pages (dma_bitsize -PAGE_SHIFT , zone_hi, +cpu_to_node (cpu)) >= (1UL << order )) + { + pg =alloc_heap_pages (dma_bitsize -PAGE_SHIFT , zone_hi, + cpu, order); + }/* Failure? Then check if we can fall back to the DMA pool. */ if ( unlikely(pg == NULL) && ((order > MAX_ORDER) ||
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel