Patch for accessing available memory. -- Elizabeth Kon (Beth) IBM Linux Technology Center Open Hypervisor Team email: eak@xxxxxxxxxx
diff -urpN libvirt.danielpatch/include/libvirt/libvirt.h.in libvirt.cellsMemory/include/libvirt/libvirt.h.in --- libvirt.danielpatch/include/libvirt/libvirt.h.in 2007-09-11 15:29:43.000000000 -0400 +++ libvirt.cellsMemory/include/libvirt/libvirt.h.in 2007-09-27 18:39:52.000000000 -0400 @@ -586,8 +586,9 @@ int virDomainDetachDevice(virDomainPtr d */ int virNodeGetCellsFreeMemory(virConnectPtr conn, - unsigned long *freeMems, - int nbCells); + unsigned long long *freeMems, + int startCell, + int maxCells); /* * Virtual Networks API diff -urpN libvirt.danielpatch/src/driver.h libvirt.cellsMemory/src/driver.h --- libvirt.danielpatch/src/driver.h 2007-09-11 15:29:43.000000000 -0400 +++ libvirt.cellsMemory/src/driver.h 2007-09-27 18:39:52.000000000 -0400 @@ -258,8 +258,9 @@ typedef virDriver *virDriverPtr; typedef int (*virDrvNodeGetCellsFreeMemory) (virConnectPtr conn, - unsigned long *freeMems, - int nbCells); + long long *freeMems, + int startCell, + int maxCells); /** * _virDriver: diff -urpN libvirt.danielpatch/src/libvirt.c libvirt.cellsMemory/src/libvirt.c --- libvirt.danielpatch/src/libvirt.c 2007-09-11 15:29:43.000000000 -0400 +++ libvirt.cellsMemory/src/libvirt.c 2007-09-27 18:44:45.000000000 -0400 @@ -2651,35 +2651,37 @@ virDomainDetachDevice(virDomainPtr domai /** * virNodeGetCellFreeMemory: * @conn: pointer to the hypervisor connection - * @freeMems: pointer to the array of unsigned long - * @nbCells: number of entries available in freeMems + * @freeMems: pointer to the array of unsigned long long + * @startCell: index of first cell to return freeMems info on. + * @maxCells: Maximum number of cells for which freeMems information can + * be returned. * - * This call allows to ask the amount of free memory in each NUMA cell. + * This call returns the amount of free memory in one or more NUMA cells. * The @freeMems array must be allocated by the caller and will be filled - * with the amounts of free memory in kilobytes for each cell starting - * from cell #0 and up to @nbCells -1 or the number of cell in the Node - * (which can be found using virNodeGetInfo() see the nodes entry in the - * structure). + * with the amount of free memory in kilobytes for each cell requested, + * starting with startCell (in freeMems[0]), up to either + * (startCell + maxCells), or the number of additional cells in the node, + * whichever is smaller. * * Returns the number of entries filled in freeMems, or -1 in case of error. */ int -virNodeGetCellsFreeMemory(virConnectPtr conn, unsigned long *freeMems, - int nbCells) +virNodeGetCellsFreeMemory(virConnectPtr conn, unsigned long long *freeMems, + int startCell, int maxCells) { if (!VIR_IS_CONNECT(conn)) { virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__); return (-1); } - if ((freeMems == NULL) || (nbCells <= 0)) { + if ((freeMems == NULL) || (maxCells <= 0)) { virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); return (-1); } if (conn->driver->nodeGetCellsFreeMemory) - return conn->driver->nodeGetCellsFreeMemory (conn, freeMems, nbCells); + return conn->driver->nodeGetCellsFreeMemory (conn, freeMems, startCell, maxCells); virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); return -1; diff -urpN libvirt.danielpatch/src/libvirt_sym.version libvirt.cellsMemory/src/libvirt_sym.version --- libvirt.danielpatch/src/libvirt_sym.version 2007-09-10 17:35:39.000000000 -0400 +++ libvirt.cellsMemory/src/libvirt_sym.version 2007-09-27 18:45:48.000000000 -0400 @@ -20,6 +20,7 @@ virDomainGetUUID; virDomainGetUUIDString; virDomainGetInfo; + virNodeGetCellsFreeMemory; virDomainGetMaxMemory; virDomainGetName; virDomainGetOSType; diff -urpN libvirt.danielpatch/src/xend_internal.c libvirt.cellsMemory/src/xend_internal.c --- libvirt.danielpatch/src/xend_internal.c 2007-09-10 17:35:39.000000000 -0400 +++ libvirt.cellsMemory/src/xend_internal.c 2007-09-27 18:39:52.000000000 -0400 @@ -1954,6 +1954,8 @@ xenDaemonOpen(virConnectPtr conn, const { xmlURIPtr uri = NULL; int ret; + + virNodeInfo nodeInfo; /* If the name is just "xen" (it might originally have been NULL, * see xenUnifiedOpen) or any URI beginning with "xen:///" then diff -urpN libvirt.danielpatch/src/xen_internal.c libvirt.cellsMemory/src/xen_internal.c --- libvirt.danielpatch/src/xen_internal.c 2007-09-11 15:29:44.000000000 -0400 +++ libvirt.cellsMemory/src/xen_internal.c 2007-09-27 19:00:28.000000000 -0400 @@ -28,6 +28,7 @@ #include <errno.h> #include <sys/utsname.h> #include "xs_internal.h" +#include "xend_internal.h" /* required for dom0_getdomaininfo_t */ #include <xen/dom0_ops.h> @@ -201,6 +202,15 @@ union xen_getschedulerid { }; typedef union xen_getschedulerid xen_getschedulerid; +struct xen_v2s4_availheap { + uint32_t min_bitwidth; /* Smallest address width (zero if don't care). */ + uint32_t max_bitwidth; /* Largest address width (zero if don't care). */ + int32_t node; /* NUMA node (-1 for sum across all nodes). */ + uint64_t avail_bytes; /* Bytes available in the specified region. */ +}; + +typedef struct xen_v2s4_availheap xen_v2s4_availheap; + #define XEN_GETDOMAININFOLIST_ALLOC(domlist, size) \ (hypervisor_version < 2 ? \ @@ -524,6 +534,11 @@ typedef struct xen_v2d5_setvcpumap xen_v #define XEN_V2_OP_GETSCHEDULERID 4 /* + * from V2 we get the available heap information + */ +#define XEN_V2_OP_GETAVAILHEAP 9 + +/* * from V2 we get the scheduler parameter */ #define XEN_V2_OP_SCHEDULER 16 @@ -584,6 +599,7 @@ struct xen_op_v2_sys { xen_v2_getdomaininfolistop getdomaininfolist; xen_v2s3_getdomaininfolistop getdomaininfolists3; xen_v2_getschedulerid getschedulerid; + xen_v2s4_availheap availheap; uint8_t padding[128]; } u; }; @@ -2012,7 +2028,7 @@ xenHypervisorInit(void) #endif return(-1); } - /* Currently consider RHEL5.0 Fedora7 and xen-unstable */ + /* Currently consider RHEL5.0 Fedora7, xen-3.1, and xen-unstable */ sys_interface_version = 2; /* XEN_SYSCTL_INTERFACE_VERSION */ if (virXen_getdomaininfo(fd, 0, &info) == 1) { /* RHEL 5.0 */ @@ -2035,7 +2051,7 @@ xenHypervisorInit(void) sys_interface_version = 3; /* XEN_SYSCTL_INTERFACE_VERSION */ if (virXen_getdomaininfo(fd, 0, &info) == 1) { - /* xen-unstable */ + /* xen-3.1 */ dom_interface_version = 5; /* XEN_DOMCTL_INTERFACE_VERSION */ if (virXen_getvcpusinfo(fd, 0, 0, ipt, NULL, 0) == 0){ #ifdef DEBUG @@ -2045,6 +2061,18 @@ xenHypervisorInit(void) } } + sys_interface_version = 4; /* XEN_SYSCTL_INTERFACE_VERSION */ + if (virXen_getdomaininfo(fd, 0, &info) == 1) { + /* xen-unstable */ + dom_interface_version = 5; /* XEN_DOMCTL_INTERFACE_VERSION */ + if (virXen_getvcpusinfo(fd, 0, 0, ipt, NULL, 0) == 0){ +#ifdef DEBUG + fprintf(stderr, "Using hypervisor call v2, sys ver4 dom ver5\n"); +#endif + goto done; + } + } + hypervisor_version = 1; sys_interface_version = -1; if (virXen_getdomaininfo(fd, 0, &info) == 1) { @@ -2937,41 +2965,80 @@ xenHypervisorGetDomainInfo(virDomainPtr } +#ifndef PROXY /** * xenHypervisorNodeGetCellsFreeMemory: * @conn: pointer to the hypervisor connection - * @freeMems: pointer to the array of unsigned long - * @nbCells: number of entries available in freeMems + * @freeMems: pointer to the array of unsigned long long + * @startCell: index of first cell to return freeMems info on. + * @maxCells: Maximum number of cells for which freeMems information can + * be returned. * - * This call allows to ask the amount of free memory in each NUMA cell. + * This call returns the amount of free memory in one or more NUMA cells. * The @freeMems array must be allocated by the caller and will be filled - * with the amounts of free memory in kilobytes for each cell starting - * from cell #0 and up to @nbCells -1 or the number of cell in the Node - * (which can be found using virNodeGetInfo() see the nodes entry in the - * structure). + * with the amount of free memory in kilobytes for each cell requested, + * starting with startCell (in freeMems[0]), up to either + * (startCell + maxCells), or the number of additional cells in the node, + * whichever is smaller. * * Returns the number of entries filled in freeMems, or -1 in case of error. */ int -xenHypervisorNodeGetCellsFreeMemory(virConnectPtr conn, unsigned long *freeMems, - int nbCells) +xenHypervisorNodeGetCellsFreeMemory(virConnectPtr conn, unsigned long long *freeMems, + int startCell, int maxCells) { - if ((conn == NULL) || (freeMems == NULL) || (nbCells < 0)) - return -1; + xen_op_v2_sys op_sys; + int i, j, ret; + xenUnifiedPrivatePtr priv; + static int nbNodeCells = -1; + virNodeInfo nodeInfo; + + + if (nbNodeCells == -1) { + if (xenDaemonNodeGetInfo(conn, &nodeInfo)) { + virXenErrorFunc (VIR_ERR_XEN_CALL, __FUNCTION__, + "cannot determine actual number of cells",0); + return -1; + } + nbNodeCells = nodeInfo.nodes; + } + if ((conn == NULL) || (maxCells < 1) || (startCell >= nbNodeCells)) { + virXenErrorFunc (VIR_ERR_INVALID_ARG, __FUNCTION__, + "invalid argument", 0); + return -1; + } /* - * TODO: - * - get the number of cell in the node - * - if not NUMA returns the available memeoy directly in freeMems[0] - * return 1 - * - if NUMA iterates over the cells using a specific hypercall - * filling up entries until full or at the end of the NUMA cells + * Support only sys_interface_version >=4 */ - return(-1); + if (sys_interface_version < 4) { + virXenErrorFunc (VIR_ERR_XEN_CALL, __FUNCTION__, + "unsupported in sys interface < 4", 0); + return -1; + } + + priv = (xenUnifiedPrivatePtr) conn->privateData; + if (priv->handle < 0) { + virXenErrorFunc (VIR_ERR_INTERNAL_ERROR, __FUNCTION__, + "priv->handle invalid", 0); + return -1; + } + + memset(&op_sys, 0, sizeof(op_sys)); + op_sys.cmd = XEN_V2_OP_GETAVAILHEAP; + + for (i = startCell, j = 0;(i < nbNodeCells) && (j < maxCells);i++,j++) { + op_sys.u.availheap.node = i; + ret = xenHypervisorDoV2Sys(priv->handle, &op_sys); + if (ret < 0) { + return(-1); + } + freeMems[j] = op_sys.u.availheap.avail_bytes; + } + return (j); } -#ifndef PROXY /** * xenHypervisorPauseDomain: * @domain: pointer to the domain block diff -urpN libvirt.danielpatch/src/xen_internal.h libvirt.cellsMemory/src/xen_internal.h --- libvirt.danielpatch/src/xen_internal.h 2007-09-11 15:29:44.000000000 -0400 +++ libvirt.cellsMemory/src/xen_internal.h 2007-09-27 18:43:52.000000000 -0400 @@ -94,8 +94,9 @@ int xenHypervisorDomainInterfaceStat struct _virDomainInterfaceStats *stats); int xenHypervisorNodeGetCellsFreeMemory(virConnectPtr conn, - unsigned long *freeMems, - int nbCells); + unsigned long long *freeMems, + int startCell, + int maxCells); #ifdef __cplusplus } #endif diff -urpN libvirt.danielpatch/src/xen_unified.c libvirt.cellsMemory/src/xen_unified.c --- libvirt.danielpatch/src/xen_unified.c 2007-09-11 15:29:44.000000000 -0400 +++ libvirt.cellsMemory/src/xen_unified.c 2007-09-27 18:39:52.000000000 -0400 @@ -1050,13 +1050,14 @@ xenUnifiedDomainInterfaceStats (virDomai } static int -xenUnifiedNodeGetCellsFreeMemory (virConnectPtr conn, unsigned long *freeMems, - int nbCells) +xenUnifiedNodeGetCellsFreeMemory (virConnectPtr conn, unsigned long long *freeMems, + int startCell, int maxCells) { GET_PRIVATE (conn); if (priv->opened[XEN_UNIFIED_HYPERVISOR_OFFSET]) - return xenHypervisorNodeGetCellsFreeMemory (conn, freeMems, nbCells); + return xenHypervisorNodeGetCellsFreeMemory (conn, freeMems, + startCell, maxCells); xenUnifiedError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); return -1;
-- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list