[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Libvir] [RFC][PATCH 1/2] NUMA memory and topology patches



[PATCH 1/2] - add capability to access free memory information on each NUMA cell.

Signed-off-by: Beth Kon (eak us ibm com)

--
Elizabeth Kon (Beth)
IBM Linux Technology Center
Open Hypervisor Team
email: eak us ibm com

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-20 14:11:32.000000000 -0400
@@ -586,8 +586,9 @@ int virDomainDetachDevice(virDomainPtr d
  */
 
 int			 virNodeGetCellsFreeMemory(virConnectPtr conn,
-						   unsigned long *freeMems,
-						   int nbCells);
+						   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-20 14:16:41.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-24 22:01:51.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 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, 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/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-24 21:51:30.000000000 -0400
@@ -108,6 +108,10 @@ struct xenUnifiedDriver xenDaemonDriver 
     NULL, /* domainSetSchedulerParameters */
 };
 
+
+/* number of cells in the node will be saved for later use */
+int nbNodeCells;
+
 /**
  * xenDaemonInit:
  *
@@ -1954,6 +1958,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
@@ -2018,6 +2024,14 @@ xenDaemonOpen(virConnectPtr conn, const 
     }
 
  done:
+    /* get number of cells on the node for future use*/
+    if (xenDaemonNodeGetInfo(conn, &nodeInfo)) {
+    /* BETH - not sure what would be the appropriate error type. should I add one for xend? */
+        virXendError(conn, VIR_ERR_XEN_CALL, " cannot determine actual number of cells");
+        return -1;
+    }
+    nbNodeCells = nodeInfo.nodes;
+
     if (uri != NULL)
         xmlFreeURI(uri);
     return(ret);
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-24 22:04:05.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,69 @@ 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 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, 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;
+    
 
+    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_NO_XEN, __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-24 22:12:11.000000000 -0400
@@ -94,9 +94,11 @@ int     xenHypervisorDomainInterfaceStat
 					 struct _virDomainInterfaceStats *stats);
 
 int	xenHypervisorNodeGetCellsFreeMemory(virConnectPtr conn,
-					  unsigned long *freeMems,
-					  int nbCells);
+					  long long *freeMems,
+					  int startCell,
+					  int maxCells);
 #ifdef __cplusplus
 }
 #endif
+extern int nbNodeCells;
 #endif                          /* __VIR_XEN_INTERNAL_H__ */
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-20 13:18:08.000000000 -0400
@@ -1050,13 +1050,14 @@ xenUnifiedDomainInterfaceStats (virDomai
 }
 
 static int
-xenUnifiedNodeGetCellsFreeMemory (virConnectPtr conn, unsigned long *freeMems,
-                                  int nbCells)
+xenUnifiedNodeGetCellsFreeMemory (virConnectPtr conn, 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;

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]