From mboxrd@z Thu Jan 1 00:00:00 1970 From: Dulloor Subject: Re: [PATCH 10/11] [PVOPS] Use enlightenment to setup nodes Date: Tue, 6 Apr 2010 01:19:05 -0400 Message-ID: References: <20100405141648.GC1227@phenom.dumpdata.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Return-path: In-Reply-To: <20100405141648.GC1227@phenom.dumpdata.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: Konrad Rzeszutek Wilk Cc: xen-devel@lists.xensource.com List-Id: xen-devel@lists.xenproject.org > It looks as the comments I provided in > <20100216174900.GB21067@phenom.dumpdata.com> were ignored. I incorporated a number of your comments, but obviously missed some. Sorry, wasn't intentional. Comments inline. On Mon, Apr 5, 2010 at 10:16 AM, Konrad Rzeszutek Wilk wrote: > > It looks as the comments I provided in > <20100216174900.GB21067@phenom.dumpdata.com> were ignored. > > http://article.gmane.org/gmane.comp.emulators.xen.devel/78118 > > Here I am repeating some of them and adding some new ones. > Please address/answer them. > > .. snip.. > >> - =A0 =A0 acpi_numa_init(); >> + =A0 =A0if (acpi_numa > 0) >> + =A0 =A0 =A0 =A0 acpi_numa_init(); > > The style guide is to use tabs, not spaces. It looks out-off-place? I had set the darn "expandtab" set in my vimrc. I have run the patch through checkpatch.pl and will fix the indentation issues. > Why not just do acpi_numa_init() by itself? > With pv kernels, we know well ahead that numa acpi is irrelevant, same as when booting linux with noacpi. I thought it is unnecessary to even parse the numa acpi tables in that case. > >> =A0#endif >> >> =A0 =A0 =A0 initmem_init(0, max_pfn); >> diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c >> index 459913b..3a856dc 100644 >> --- a/arch/x86/mm/numa_64.c >> +++ b/arch/x86/mm/numa_64.c >> @@ -11,7 +11,11 @@ >> =A0#include >> =A0#include >> =A0#include >> +#include >> =A0#include >> +#include >> +#include >> +#include >> >> =A0#include >> =A0#include >> @@ -19,6 +23,8 @@ >> =A0#include >> =A0#include >> =A0#include >> +#include >> +#include >> >> =A0struct pglist_data *node_data[MAX_NUMNODES] __read_mostly; >> =A0EXPORT_SYMBOL(node_data); >> @@ -428,7 +434,6 @@ static int __init numa_emulation(unsigned long start= _pfn, unsigned long last_pfn >> =A0 =A0 =A0 =A0*/ >> =A0 =A0 =A0 if (!strchr(cmdline, '*') && !strchr(cmdline, ',')) { >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 long n =3D simple_strtol(cmdline, NULL, 0); >> - > > Uhh, why? By mistake ! :) >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 num_nodes =3D split_nodes_equally(nodes, &ad= dr, max_addr, 0, n); >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (num_nodes < 0) >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return num_nodes; >> @@ -522,6 +527,246 @@ out: >> =A0 =A0 =A0 numa_init_array(); >> =A0 =A0 =A0 return 0; >> =A0} >> + >> +/**********************************************************************= **/ >> +#ifdef CONFIG_XEN_NUMA_GUEST > > Yikes. Can you move all of this code in it is own file so that there is > no need to sprinkle this with #ifdefs? I agree with you. I will also take care of the few xen header files I have added to the file. > >> +/* XEN PV GUEST NUMA */ >> +struct xen_domain_numa_layout HYPERVISOR_pv_numa_layout; >> + >> +static inline void __init >> +bitmap_byte_to_long(unsigned long *lp, const uint8_t *bp, int nbits) >> +{ >> + =A0 =A0 /* We may need to pad the final longword with zeroes. */ >> + =A0 =A0 if (nbits & (BITS_PER_LONG-1)) >> + =A0 =A0 =A0 =A0 =A0 =A0 lp[BITS_TO_LONGS(nbits)-1] =3D 0; >> + =A0 =A0 memcpy(lp, bp, (nbits+7)/8); >> +} >> + >> +static void __init >> +xenctl_cpumask_to_cpumask(cpumask_t *cpumask, struct xenctl_cpumask *xc= pumask) >> +{ >> + =A0 =A0unsigned int nr_cpus; >> + =A0 =A0uint8_t *bytemap; >> + >> + =A0 =A0bytemap =3D xcpumask->bits; >> + >> + =A0 =A0nr_cpus =3D >> + =A0 =A0 =A0 =A0min_t(unsigned int, XENCTL_NR_CPUS, NR_CPUS); >> + >> + =A0 =A0cpumask_clear(cpumask); >> + =A0 =A0bitmap_byte_to_long(cpus_addr(*cpumask), bytemap, nr_cpus); >> +} >> + >> +static void __init >> +xen_dump_numa_layout(struct xen_domain_numa_layout *layout) >> +{ >> + =A0 =A0unsigned int i, j; >> + =A0 =A0char vcpumaskstr[128]; >> + =A0 =A0printk("NUMA-LAYOUT : vcpus(%u), vnodes(%u), ", >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0layout->max_vcp= us, layout->max_vnodes); > > No good. You need printk(KERN_DEBUG .. Missed these from your previous comments. Will take care of these. >> + =A0 =A0switch (layout->type) >> + =A0 =A0{ >> + =A0 =A0 =A0 =A0case XEN_DOM_NUMA_CONFINED: >> + =A0 =A0 =A0 =A0 =A0 =A0printk("type(CONFINED)\n"); > ditoo. >> + =A0 =A0 =A0 =A0 =A0 =A0break; >> + =A0 =A0 =A0 =A0case XEN_DOM_NUMA_SPLIT: >> + =A0 =A0 =A0 =A0 =A0 =A0printk("type(SPLIT)\n"); > ditto. >> + =A0 =A0 =A0 =A0 =A0 =A0break; >> + =A0 =A0 =A0 =A0case XEN_DOM_NUMA_STRIPED: >> + =A0 =A0 =A0 =A0 =A0 =A0printk("type(STRIPED)\n"); > ditto. >> + =A0 =A0 =A0 =A0 =A0 =A0break; >> + =A0 =A0 =A0 =A0default: >> + =A0 =A0 =A0 =A0 =A0 =A0printk("type(UNDEFINED)\n"); > > ditto. >> + =A0 =A0} >> + >> + =A0 =A0for (i =3D 0; i < layout->max_vnodes; i++) >> + =A0 =A0{ >> + =A0 =A0 =A0 =A0cpumask_t vcpu_mask; >> + =A0 =A0 =A0 =A0struct xenctl_cpumask *xvcpumask; >> + =A0 =A0 =A0 =A0struct xen_vnode_data *vnode_data =3D &layout->vnode_da= ta[i]; >> + =A0 =A0 =A0 =A0xvcpumask =3D &vnode_data->vcpu_mask; >> + =A0 =A0 =A0 =A0xenctl_cpumask_to_cpumask(&vcpu_mask, xvcpumask); >> + =A0 =A0 =A0 =A0cpumask_scnprintf(vcpumaskstr, sizeof(vcpumaskstr), &vc= pu_mask); >> + =A0 =A0 =A0 =A0printk("vnode[%u]:mnode(%u), node_nr_pages(%lx), vcpu_m= ask(%s)\n", > ditto >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0vnode_data->vnode_id, vnode_data->mnode= _id, >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(unsigned long)vnode_data->nr_pages, vc= pumaskstr); >> + =A0 =A0} >> + >> + =A0 =A0printk("vnode distances :\n"); > ditoo >> + =A0 =A0for (i =3D 0; i < layout->max_vnodes; i++) >> + =A0 =A0 =A0 =A0printk("\tvnode[%u]", i); > ditto >> + =A0 =A0for (i =3D 0; i < layout->max_vnodes; i++) >> + =A0 =A0{ >> + =A0 =A0 =A0 =A0printk("\nvnode[%u]", i); > ditoo >> + =A0 =A0 =A0 =A0for (j =3D 0; j < layout->max_vnodes; j++) >> + =A0 =A0 =A0 =A0 =A0 =A0printk("\t%u", layout->vnode_distance[i*layout-= >max_vnodes + j]); >> + =A0 =A0 =A0 =A0printk("\n"); > ditto >> + =A0 =A0} >> + =A0 =A0return; >> +} >> + >> +static void __init xen_init_slit_table(struct xen_domain_numa_layout *l= ayout) >> +{ >> + =A0 =A0/* Construct a slit table (using layout->vnode_distance). >> + =A0 =A0 * Copy it to acpi_slit. */ >> + =A0 =A0return; >> +} >> + >> +/* Distribute the vcpus over the vnodes according to their affinity */ >> +static void __init xen_init_numa_array(struct xen_domain_numa_layout *l= ayout) >> +{ >> + =A0 =A0 int vcpu, vnode; >> + >> + =A0 =A0 printk(KERN_INFO "xen_numa_init_array - cpu_to_node initializa= tion\n"); >> + >> + >> + =A0 =A0for (vnode =3D 0; vnode < layout->max_vnodes; vnode++) >> + =A0 =A0{ >> + =A0 =A0 =A0 =A0struct xen_vnode_data *vnode_data =3D &layout->vnode_da= ta[vnode]; >> + =A0 =A0 =A0 =A0struct xenctl_cpumask *xvcpu_mask =3D &vnode_data->vcpu= _mask; >> + =A0 =A0 =A0 =A0cpumask_t vcpu_mask; >> + >> + =A0 =A0 =A0 =A0xenctl_cpumask_to_cpumask(&vcpu_mask, xvcpu_mask); >> + >> + =A0 =A0 =A0 =A0for (vcpu =3D 0; vcpu < layout->max_vcpus; vcpu++) >> + =A0 =A0 =A0 =A0{ >> + =A0 =A0 =A0 =A0 =A0 =A0if (cpu_isset(vcpu, vcpu_mask)) >> + =A0 =A0 =A0 =A0 =A0 =A0{ >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (early_cpu_to_node(vcpu) !=3D NUMA_N= O_NODE) >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0{ >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0printk(KERN_INFO "EARLY vcpu[%d= ] on vnode[%d]\n", >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0vcpu, early_cpu_to_node(vcpu)); >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0continue; >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0printk(KERN_INFO "vcpu[%d] on vnode[%d]= \n", vcpu, vnode); >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 numa_set_node(vcpu, vnode); >> + =A0 =A0 =A0 =A0 =A0 =A0} >> + =A0 =A0 =A0 =A0} >> + =A0 =A0} >> + =A0 =A0return; >> +} >> + >> +static int __init xen_numa_emulation(struct xen_domain_numa_layout *lay= out, >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0unsigned long s= tart_pfn, unsigned long last_pfn) >> +{ >> + =A0 =A0 int num_vnodes, i; >> + =A0 =A0u64 node_start_addr, node_end_addr, max_addr; >> + >> + =A0 =A0printk(KERN_INFO "xen_numa_emulation : max_vnodes(%d), max_vcpu= s(%d)", >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0layout->max_vnodes, layout->max_vcpus); >> + >> + =A0 =A0if (layout->type !=3D XEN_DOM_NUMA_SPLIT) >> + =A0 =A0{ >> + =A0 =A0 =A0 =A0printk(KERN_INFO "xen_numa_emulation : Invalid layout t= ype"); >> + =A0 =A0 =A0 =A0return -1; >> + =A0 =A0} >> + >> + =A0 =A0 memset(&nodes, 0, sizeof(nodes)); >> + >> + =A0 =A0num_vnodes =3D layout->max_vnodes; >> + =A0 =A0BUG_ON(num_vnodes > MAX_NUMNODES); >> + >> + =A0 =A0max_addr =3D last_pfn << PAGE_SHIFT; >> + >> + =A0 =A0node_start_addr =3D start_pfn << PAGE_SHIFT; >> + =A0 =A0for (i =3D 0; i < num_vnodes; i++) >> + =A0 =A0{ >> + =A0 =A0 =A0 =A0struct xen_vnode_data *vnode_data =3D &layout->vnode_da= ta[i]; >> + =A0 =A0 =A0 =A0u64 node_size =3D vnode_data->nr_pages << PAGE_SHIFT; >> + >> + =A0 =A0 =A0 =A0 =A0 =A0 node_size &=3D FAKE_NODE_MIN_HASH_MASK; /* 64M= B aligned */ >> + >> + =A0 =A0 =A0 =A0 =A0 =A0 if (i =3D=3D (num_vnodes-1)) >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 node_end_addr =3D max_addr; >> + =A0 =A0 =A0 =A0 =A0 =A0 else >> + =A0 =A0 =A0 =A0 =A0 =A0node_end_addr =3D node_start_addr + node_size; >> + =A0 =A0 =A0 =A0/* node_start_addr updated inside the function */ >> + =A0 =A0 =A0 =A0if (setup_node_range(i, nodes, &node_start_addr, >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(node_end_addr-node_start_addr)= , max_addr+1)) >> + =A0 =A0 =A0 =A0 =A0 =A0goto failed; >> + =A0 =A0} >> + >> + =A0 =A0 printk(KERN_INFO "XEN domain numa emulation - setup nodes\n"); >> + >> + =A0 =A0memnode_shift =3D compute_hash_shift(nodes, num_vnodes, NULL); >> + =A0 =A0if (memnode_shift < 0) { >> + =A0 =A0 =A0 =A0 printk(KERN_ERR "No NUMA hash function found.\n"); >> + =A0 =A0 =A0 =A0goto failed; >> + =A0 =A0} >> + =A0 =A0/* XXX: Shouldn't be needed because we disabled acpi_numa very = early ! */ >> + =A0 =A0 /* >> + =A0 =A0 =A0* We need to vacate all active ranges that may have been re= gistered by >> + =A0 =A0 =A0* SRAT and set acpi_numa to -1 so that srat_disabled() alwa= ys returns >> + =A0 =A0 =A0* true. =A0NUMA emulation has succeeded so we will not scan= ACPI nodes. >> + =A0 =A0 =A0*/ >> + =A0 =A0 remove_all_active_ranges(); >> + >> + =A0 =A0BUG_ON(acpi_numa >=3D 0); >> + =A0 =A0 for_each_node_mask(i, node_possible_map) { >> + =A0 =A0 =A0 =A0 =A0 =A0 e820_register_active_regions(i, nodes[i].start= >> PAGE_SHIFT, >> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 nodes[i].end >> PAGE_SHIFT); >> + =A0 =A0 =A0 =A0 =A0 =A0 setup_node_bootmem(i, nodes[i].start, nodes[i]= .end); >> + =A0 =A0 } >> + =A0 =A0xen_init_slit_table(layout); >> + =A0 =A0 xen_init_numa_array(layout); >> + =A0 =A0 return 0; >> +failed: >> + =A0 =A0return -1; >> +} >> + >> +static int __init >> +xen_get_domain_numa_layout(struct xen_domain_numa_layout *pv_layout) >> +{ >> + =A0 =A0int rc; >> + =A0 =A0struct xenmem_numa_op memop; >> + =A0 =A0memop.cmd =3D XENMEM_get_domain_numa_layout; >> + =A0 =A0memop.u.dinfo.domid =3D DOMID_SELF; >> + =A0 =A0memop.u.dinfo.version =3D XEN_DOM_NUMA_INTERFACE_VERSION; >> + =A0 =A0memop.u.dinfo.bufsize =3D sizeof(*pv_layout); >> + =A0 =A0set_xen_guest_handle(memop.u.dinfo.buf, pv_layout); >> + >> + =A0 =A0if ((rc =3D HYPERVISOR_memory_op(XENMEM_numa_op, &memop))) >> + =A0 =A0{ >> + =A0 =A0 =A0 =A0printk(KERN_INFO "XEN NUMA GUEST:xen_get_domain_numa_la= yout failed\n"); >> + =A0 =A0 =A0 =A0xen_start_info->flags &=3D ~SIF_NUMA_DOMAIN; >> + =A0 =A0 =A0 =A0goto done; >> + =A0 =A0} >> + >> + =A0 =A0if (pv_layout->version !=3D XEN_DOM_NUMA_INTERFACE_VERSION) >> + =A0 =A0{ >> + =A0 =A0 =A0 =A0printk(KERN_INFO "XEN NUMA GUEST: version mismatch (dis= abling)\n"); >> + =A0 =A0 =A0 =A0xen_start_info->flags &=3D ~SIF_NUMA_DOMAIN; >> + =A0 =A0 =A0 =A0rc =3D -1; >> + =A0 =A0} >> + =A0 =A0xen_dump_numa_layout(pv_layout); >> +done: >> + =A0 =A0return rc; >> +} >> + >> +static int __init >> +xen_pv_numa(unsigned long start_pfn, unsigned long last_pfn) >> +{ >> + =A0 =A0int rc =3D 0; >> + =A0 =A0if (!xen_pv_domain() || !(xen_start_info->flags & SIF_NUMA_DOMA= IN)) >> + =A0 =A0{ >> + =A0 =A0 =A0 =A0rc =3D -1; >> + =A0 =A0 =A0 =A0 printk(KERN_INFO "xen numa emulation disabled\n"); >> + =A0 =A0 =A0 =A0goto done; > > The tabs/spaces don't look right. Can you run this patch through > checkpatch.pl? Ok. > >> + =A0 =A0} >> + =A0 =A0if ((rc =3D xen_get_domain_numa_layout(&HYPERVISOR_pv_numa_layo= ut))) >> + =A0 =A0 =A0 =A0goto done; >> + =A0 =A0rc =3D xen_numa_emulation(&HYPERVISOR_pv_numa_layout, start_pfn= , last_pfn); >> +done: >> + =A0 =A0return rc; >> +} >> +#else >> +static inline int __init >> +xen_pv_numa(unsigned long start_pfn, unsigned long last_pfn) >> +{ >> + =A0 =A0return -1; >> +} >> +#endif /* CONFIG_XEN_NUMA_GUEST */ >> +/**********************************************************************= **/ >> =A0#endif /* CONFIG_NUMA_EMU */ >> >> =A0void __init initmem_init(unsigned long start_pfn, unsigned long last_= pfn) >> @@ -532,6 +777,9 @@ void __init initmem_init(unsigned long start_pfn, un= signed long last_pfn) >> =A0 =A0 =A0 nodes_clear(node_online_map); >> >> =A0#ifdef CONFIG_NUMA_EMU >> + =A0 =A0if (!xen_pv_numa(start_pfn, last_pfn)) >> + =A0 =A0 =A0 =A0return; >> + >> =A0 =A0 =A0 if (cmdline && !numa_emulation(start_pfn, last_pfn)) >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 return; >> =A0 =A0 =A0 nodes_clear(node_possible_map); >> diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig >> index 7675f9b..7cf6a4f 100644 >> --- a/arch/x86/xen/Kconfig >> +++ b/arch/x86/xen/Kconfig >> @@ -73,3 +73,12 @@ config XEN_PCI_PASSTHROUGH >> =A0 =A0 =A0 =A0 help >> =A0 =A0 =A0 =A0 =A0 Enable support for passing PCI devices through to >> =A0 =A0 =A0 =A0unprivileged domains. (COMPLETELY UNTESTED) >> + >> +config XEN_NUMA_GUEST >> + =A0 =A0bool "Enable support NUMA aware Xen domains" >> + =A0 =A0depends on XEN && X86_64 && NUMA && NUMA_EMU >> + =A0 =A0help >> + =A0 =A0 =A0 =A0Enable support for NUMA aware Xen domains. With this >> + =A0 =A0 =A0 =A0option, if the memory for the domain is allocated >> + =A0 =A0 =A0 =A0from different memory nodes, the domain is made aware >> + =A0 =A0 =A0 =A0of this through a Virtual NUMA enlightenment. >> diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c >> index df3e84c..2ee9f0b 100644 >> --- a/arch/x86/xen/setup.c >> +++ b/arch/x86/xen/setup.c >> @@ -285,6 +285,8 @@ void __init xen_arch_setup(void) >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 printk(KERN_INFO "ACPI in unprivileged domai= n disabled\n"); >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 disable_acpi(); >> =A0 =A0 =A0 } >> + =A0 =A0acpi_numa =3D -1; >> + =A0 =A0numa_off =3D 1; >> =A0#endif >> >> =A0 =A0 =A0 /* >> diff --git a/include/xen/interface/memory.h b/include/xen/interface/memo= ry.h >> index 32ab005..7f5b85e 100644 >> --- a/include/xen/interface/memory.h >> +++ b/include/xen/interface/memory.h >> @@ -240,6 +240,102 @@ DEFINE_GUEST_HANDLE_STRUCT(xen_memory_map); >> =A0 */ >> =A0#define XENMEM_machine_memory_map =A0 10 >> >> +/* xen guest numa operations */ >> +#define XENMEM_numa_op =A0 =A0 =A0 =A0 =A0 15 >> + >> +#define XEN_DOM_NUMA_INTERFACE_VERSION =A00x00000001 >> +#define XENCTL_NR_CPUS 64 >> +#define XENCTL_BITS_PER_BYTE 8 >> +#define XENCTL_BITS_TO_BYTES(bits) \ >> + =A0 =A0(((bits)+XENCTL_BITS_PER_BYTE-1)/XENCTL_BITS_PER_BYTE) >> + >> +#define XENCTL_DECLARE_BITMAP(name,bits) \ >> + =A0 =A0uint8_t name[XENCTL_BITS_TO_BYTES(bits)] >> +struct xenctl_cpumask{ XENCTL_DECLARE_BITMAP(bits, XENCTL_NR_CPUS); }; >> + >> +/* Not used in guest */ >> +#define XENMEM_machine_numa_layout 0x01 >> +struct xenmem_node_data { >> + =A0 =A0uint32_t node_id; >> + =A0 =A0uint64_t node_memsize; >> + =A0 =A0uint64_t node_memfree; >> + =A0 =A0struct xenctl_cpumask cpu_mask; /* node_to_cpumask */ >> +}; >> + >> +/* NUMA layout for the machine. >> + * Structure has to fit within a page. */ >> +struct xenmem_machine_numa_layout { >> + =A0 =A0uint32_t max_nodes; >> + =A0 =A0/* Only (max_nodes*max_nodes) entries are filled */ >> + =A0 =A0GUEST_HANDLE(uint32_t) node_distance; >> + =A0 =A0/* max_vnodes entries of xenmem_node_data type */ >> + =A0 =A0GUEST_HANDLE(void) node_data; >> +}; >> +DEFINE_GUEST_HANDLE_STRUCT(xenmem_machine_numa_layout); >> + >> + >> +#define XENMEM_machine_nodemap =A00x02 >> +struct xenmem_machine_nodemap { >> + =A0 =A0/* On call the size of the available buffer */ >> + =A0 =A0uint32_t bufsize; >> + >> + =A0 =A0/* memnode map parameters */ >> + =A0 =A0int32_t shift; >> + =A0 =A0uint32_t mapsize; >> + =A0 =A0GUEST_HANDLE(void) map; >> +}; >> +DEFINE_GUEST_HANDLE_STRUCT(xenmem_machine_nodemap); >> + >> +/* NUMA layout for the domain at the time of startup. >> + * Structure has to fit within a page. */ >> +#define XENMEM_set_domain_numa_layout 0x03 >> +#define XENMEM_get_domain_numa_layout 0x04 >> + >> +/* NUMA layout for the domain at the time of startup. >> + * Structure has to fit within a page. */ >> +#define XEN_MAX_VNODES 8 >> + >> +struct xen_vnode_data { >> + =A0 =A0uint32_t vnode_id; >> + =A0 =A0uint32_t mnode_id; >> + =A0 =A0uint64_t nr_pages; >> + =A0 =A0struct xenctl_cpumask vcpu_mask; /* vnode_to_vcpumask */ >> +}; >> + >> +#define XEN_DOM_NUMA_CONFINED =A0 =A0 =A0 0x01 >> +#define XEN_DOM_NUMA_SPLIT =A0 =A0 =A0 =A0 =A00x02 >> +#define XEN_DOM_NUMA_STRIPED =A0 =A0 =A0 =A0 0x03 >> +struct xen_domain_numa_layout { >> + =A0 =A0uint32_t version; >> + =A0 =A0uint32_t type; >> + >> + =A0 =A0uint32_t max_vcpus; >> + =A0 =A0uint32_t max_vnodes; >> + >> + =A0 =A0/* Only (max_vnodes*max_vnodes) entries are filled */ >> + =A0 =A0uint32_t vnode_distance[XEN_MAX_VNODES * XEN_MAX_VNODES]; >> + =A0 =A0/* Only (max_vnodes) entries are filled */ >> + =A0 =A0struct xen_vnode_data vnode_data[XEN_MAX_VNODES]; >> +}; >> + >> +struct xenmem_domain_numa_layout { >> + =A0 =A0domid_t domid; >> + =A0 =A0uint32_t version; >> + >> + =A0 =A0uint32_t bufsize; >> + =A0 =A0GUEST_HANDLE(void) buf; >> +}; >> +DEFINE_GUEST_HANDLE_STRUCT(xenmem_domain_numa_layout); >> + >> +struct xenmem_numa_op { >> + =A0 =A0uint32_t cmd; >> + =A0 =A0union { >> + =A0 =A0 =A0 =A0struct xenmem_machine_numa_layout minfo; >> + =A0 =A0 =A0 =A0struct xenmem_machine_nodemap mnodemap; >> + =A0 =A0 =A0 =A0struct xenmem_domain_numa_layout dinfo; >> + =A0 =A0} u; >> +}; >> +DEFINE_GUEST_HANDLE_STRUCT(xenmem_numa_op); >> >> =A0/* >> =A0 * Prevent the balloon driver from changing the memory reservation >> diff --git a/include/xen/interface/xen.h b/include/xen/interface/xen.h >> index 9ffaee0..17cb17d 100644 >> --- a/include/xen/interface/xen.h >> +++ b/include/xen/interface/xen.h >> @@ -494,6 +494,8 @@ struct dom0_vga_console_info { >> =A0/* These flags are passed in the 'flags' field of start_info_t. */ >> =A0#define SIF_PRIVILEGED =A0 =A0(1<<0) =A0/* Is the domain privileged? = */ >> =A0#define SIF_INITDOMAIN =A0 =A0(1<<1) =A0/* Is this the initial contro= l domain? */ >> +#define SIF_MULTIBOOT_MOD (1<<2) =A0/* Is mod_start a multiboot module?= */ >> +#define SIF_NUMA_DOMAIN =A0 (1<<3) =A0/* Is the domain NUMA aware ? */ >> =A0#define SIF_PM_MASK =A0 =A0 =A0 (0xFF<<8) /* reserve 1 byte for xen-p= m options */ >> >> =A0typedef uint64_t cpumap_t; >> @@ -504,6 +506,7 @@ typedef uint8_t xen_domain_handle_t[16]; >> =A0#define __mk_unsigned_long(x) x ## UL >> =A0#define mk_unsigned_long(x) __mk_unsigned_long(x) >> >> +DEFINE_GUEST_HANDLE(uint32_t); >> =A0DEFINE_GUEST_HANDLE(uint64_t); >> >> =A0#else /* __ASSEMBLY__ */ > >> _______________________________________________ >> Xen-devel mailing list >> Xen-devel@lists.xensource.com >> http://lists.xensource.com/xen-devel > >