[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 1/7] xen: vNUMA support for PV guests
Defines XENMEM subop hypercall for PV vNUMA enabled guests and data structures that provide vNUMA topology information from per-domain vnuma topology build info. Signed-off-by: Elena Ufimtseva <ufimtseva@xxxxxxxxx> --- Changes since RFC v2: - fixed code style; - the memory copying in hypercall happens in one go for arrays; - fixed error codes logic; --- xen/common/domain.c | 10 ++++++ xen/common/domctl.c | 72 +++++++++++++++++++++++++++++++++++++++++++ xen/common/memory.c | 41 ++++++++++++++++++++++++ xen/include/public/domctl.h | 14 +++++++++ xen/include/public/memory.h | 8 +++++ xen/include/xen/domain.h | 11 +++++++ xen/include/xen/sched.h | 1 + xen/include/xen/vnuma.h | 18 +++++++++++ 8 files changed, 175 insertions(+) create mode 100644 xen/include/xen/vnuma.h diff --git a/xen/common/domain.c b/xen/common/domain.c index 5999779..d084292 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -539,6 +539,7 @@ int domain_kill(struct domain *d) tmem_destroy(d->tmem); domain_set_outstanding_pages(d, 0); d->tmem = NULL; + domain_vnuma_destroy(&d->vnuma); /* fallthrough */ case DOMDYING_dying: rc = domain_relinquish_resources(d); @@ -1287,6 +1288,15 @@ int continue_hypercall_on_cpu( return 0; } +void domain_vnuma_destroy(struct domain_vnuma_info *v) +{ + v->nr_vnodes = 0; + xfree(v->vnuma_memblks); + xfree(v->vcpu_to_vnode); + xfree(v->vdistance); + xfree(v->vnode_to_pnode); +} + /* * Local variables: * mode: C diff --git a/xen/common/domctl.c b/xen/common/domctl.c index 870eef1..042e2d2 100644 --- a/xen/common/domctl.c +++ b/xen/common/domctl.c @@ -29,6 +29,7 @@ #include <asm/page.h> #include <public/domctl.h> #include <xsm/xsm.h> +#include <xen/vnuma.h> static DEFINE_SPINLOCK(domctl_lock); DEFINE_SPINLOCK(vcpu_alloc_lock); @@ -871,6 +872,77 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) } break; + case XEN_DOMCTL_setvnumainfo: + { + unsigned int i, j, nr_vnodes, dist_size; + unsigned int dist; + + ret = -EFAULT; + dist = i = j = 0; + + nr_vnodes = op->u.vnuma.nr_vnodes; + if ( nr_vnodes == 0 ) + goto err_dom; + dist_size = nr_vnodes * nr_vnodes; + + d->vnuma.vdistance = xmalloc_bytes( + sizeof(*d->vnuma.vdistance) * dist_size); + d->vnuma.vnuma_memblks = xmalloc_bytes( + sizeof(*d->vnuma.vnuma_memblks) * nr_vnodes); + d->vnuma.vcpu_to_vnode = xmalloc_bytes( + sizeof(*d->vnuma.vcpu_to_vnode) * d->max_vcpus); + d->vnuma.vnode_to_pnode = xmalloc_bytes( + sizeof(*d->vnuma.vnode_to_pnode) * nr_vnodes); + + if ( d->vnuma.vdistance == NULL || d->vnuma.vnuma_memblks == NULL || + d->vnuma.vcpu_to_vnode == NULL || + d->vnuma.vnode_to_pnode == NULL ) + { + ret = -ENOMEM; + goto err_dom; + } + + d->vnuma.nr_vnodes = nr_vnodes; + if ( !guest_handle_is_null(op->u.vnuma.vdistance) ) + if ( unlikely(copy_from_guest(d->vnuma.vdistance, + op->u.vnuma.vdistance, + dist_size)) ) + goto err_dom; + + if ( !guest_handle_is_null(op->u.vnuma.vnuma_memblks) ) + if ( unlikely(copy_from_guest(d->vnuma.vnuma_memblks, + op->u.vnuma.vnuma_memblks, + nr_vnodes))) + goto err_dom; + + if ( !guest_handle_is_null(op->u.vnuma.vcpu_to_vnode) ) + if ( unlikely(copy_from_guest(d->vnuma.vcpu_to_vnode, + op->u.vnuma.vcpu_to_vnode, + d->max_vcpus)) ) + goto err_dom; + + if ( !guest_handle_is_null(op->u.vnuma.vnode_to_pnode) ) + { + if ( unlikely(copy_from_guest(d->vnuma.vnode_to_pnode, + op->u.vnuma.vnode_to_pnode, + nr_vnodes)) ) + goto err_dom; + + } + else + for( i = 0; i < nr_vnodes; i++ ) + d->vnuma.vnode_to_pnode[i] = NUMA_NO_NODE; + ret = 0; +err_dom: + if (ret != 0) { + d->vnuma.nr_vnodes = 0; + xfree( d->vnuma.vdistance ); + xfree( d->vnuma.vnuma_memblks ); + xfree( d->vnuma.vnode_to_pnode ); + } + } + break; + default: ret = arch_do_domctl(op, d, u_domctl); break; diff --git a/xen/common/memory.c b/xen/common/memory.c index 50b740f..e8915e4 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -28,6 +28,7 @@ #include <public/memory.h> #include <xsm/xsm.h> #include <xen/trace.h> +#include <xen/vnuma.h> struct memop_args { /* INPUT */ @@ -732,7 +733,47 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg) rcu_unlock_domain(d); break; + case XENMEM_get_vnuma_info: + { + struct vnuma_topology_info mtopology; + struct domain *d; + unsigned int max_vcpus, nr_vnodes = 0; + rc = -EINVAL; + + if( copy_from_guest(&mtopology, arg, 1) ) + return -EFAULT; + if ( (d = rcu_lock_domain_by_any_id(mtopology.domid)) == NULL ) + return -ESRCH; + + nr_vnodes = d->vnuma.nr_vnodes; + max_vcpus = d->max_vcpus; + + if ((nr_vnodes == 0) || (nr_vnodes > max_vcpus)) + goto vnumaout; + + mtopology.nr_vnodes = nr_vnodes; + + if (copy_to_guest(arg , &mtopology, 1) != 0) + goto vnumaout; + + if (copy_to_guest(mtopology.vnuma_memblks, + d->vnuma.vnuma_memblks, + nr_vnodes) != 0) + goto vnumaout; + if (copy_to_guest(mtopology.vdistance, + d->vnuma.vdistance, + nr_vnodes * nr_vnodes) != 0) + goto vnumaout; + if (copy_to_guest(mtopology.vcpu_to_vnode, + d->vnuma.vcpu_to_vnode, + max_vcpus) != 0) + goto vnumaout; + rc = 0; +vnumaout: + rcu_unlock_domain(d); + break; + } default: rc = arch_memory_op(op, arg); break; diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h index d4e479f..1adab25 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -35,6 +35,7 @@ #include "xen.h" #include "grant_table.h" #include "hvm/save.h" +#include "memory.h" #define XEN_DOMCTL_INTERFACE_VERSION 0x00000009 @@ -863,6 +864,17 @@ struct xen_domctl_set_max_evtchn { typedef struct xen_domctl_set_max_evtchn xen_domctl_set_max_evtchn_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_max_evtchn_t); +struct xen_domctl_vnuma { + uint16_t nr_vnodes; + XEN_GUEST_HANDLE_64(uint) vdistance; + XEN_GUEST_HANDLE_64(uint) vcpu_to_vnode; + XEN_GUEST_HANDLE_64(uint) vnode_to_pnode; + XEN_GUEST_HANDLE_64(vnuma_memblk_t) vnuma_memblks; +}; + +typedef struct xen_domctl_vnuma xen_domctl_vnuma_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_vnuma_t); + struct xen_domctl { uint32_t cmd; #define XEN_DOMCTL_createdomain 1 @@ -932,6 +944,7 @@ struct xen_domctl { #define XEN_DOMCTL_setnodeaffinity 68 #define XEN_DOMCTL_getnodeaffinity 69 #define XEN_DOMCTL_set_max_evtchn 70 +#define XEN_DOMCTL_setvnumainfo 71 #define XEN_DOMCTL_gdbsx_guestmemio 1000 #define XEN_DOMCTL_gdbsx_pausevcpu 1001 #define XEN_DOMCTL_gdbsx_unpausevcpu 1002 @@ -992,6 +1005,7 @@ struct xen_domctl { struct xen_domctl_set_broken_page_p2m set_broken_page_p2m; struct xen_domctl_gdbsx_pauseunp_vcpu gdbsx_pauseunp_vcpu; struct xen_domctl_gdbsx_domstatus gdbsx_domstatus; + struct xen_domctl_vnuma vnuma; uint8_t pad[128]; } u; }; diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h index 7a26dee..93a17e9 100644 --- a/xen/include/public/memory.h +++ b/xen/include/public/memory.h @@ -459,6 +459,14 @@ DEFINE_XEN_GUEST_HANDLE(xen_mem_sharing_op_t); * The zero value is appropiate. */ +struct vnuma_memblk { + uint64_t start, end; +}; +typedef struct vnuma_memblk vnuma_memblk_t; +DEFINE_XEN_GUEST_HANDLE(vnuma_memblk_t); + +#define XENMEM_get_vnuma_info 25 + #endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ #endif /* __XEN_PUBLIC_MEMORY_H__ */ diff --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h index a057069..c9d53e3 100644 --- a/xen/include/xen/domain.h +++ b/xen/include/xen/domain.h @@ -4,6 +4,7 @@ #include <public/xen.h> #include <asm/domain.h> +#include <public/memory.h> typedef union { struct vcpu_guest_context *nat; @@ -89,4 +90,14 @@ extern unsigned int xen_processor_pmbits; extern bool_t opt_dom0_vcpus_pin; +struct domain_vnuma_info { + uint16_t nr_vnodes; + uint *vdistance; + uint *vcpu_to_vnode; + uint *vnode_to_pnode; + vnuma_memblk_t *vnuma_memblks; +}; + +void domain_vnuma_destroy(struct domain_vnuma_info *v); + #endif /* __XEN_DOMAIN_H__ */ diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 25bf637..6693b35 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -408,6 +408,7 @@ struct domain nodemask_t node_affinity; unsigned int last_alloc_node; spinlock_t node_affinity_lock; + struct domain_vnuma_info vnuma; }; struct domain_setup_info diff --git a/xen/include/xen/vnuma.h b/xen/include/xen/vnuma.h new file mode 100644 index 0000000..2637476 --- /dev/null +++ b/xen/include/xen/vnuma.h @@ -0,0 +1,18 @@ +#ifndef _VNUMA_H +#define _VNUMA_H +#include <public/memory.h> + +/* DEFINE_XEN_GUEST_HANDLE(vnuma_memblk_t); */ + +struct vnuma_topology_info { + domid_t domid; + uint16_t nr_vnodes; + uint32_t _pad; + XEN_GUEST_HANDLE_64(uint) vdistance; + XEN_GUEST_HANDLE_64(uint) vcpu_to_vnode; + XEN_GUEST_HANDLE_64(vnuma_memblk_t) vnuma_memblks; +}; +typedef struct vnuma_topology_info vnuma_topology_info_t; +DEFINE_XEN_GUEST_HANDLE(vnuma_topology_info_t); + +#endif -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |