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

[Xen-devel] [PATCH] XENMEM_memory_map and DOMCTL_set_memmap_limit implementation



Keir,

Here follows the hopefully end revision. If you think it needs more
rework, just please warn me ASAP.


-- 
Glauber de Oliveira Costa
Red Hat Inc.
"Free as in Freedom"
# HG changeset patch
# User gcosta@xxxxxxxxxx
# Date 1164812939 18000
# Node ID 0d6e4c983718a41b651bb8504ff5949a623b4e09
# Parent  71ea8d34e818c7aed76e77edcf7a23a7e6e9e71e
Implement memory_map hypercall + set_memmap_limit domctl and friends

This patch implements two new interfaces:

XENMEM_memory_map hypercall, currently defined, but not implemented.
It provides a way to inform guests about how should their physical
memory mapping look like.

DOMCTL_set_memmap_limit domctl and proper tools, which allows us
to inform the hypervisor about the maximum size guest's physical
mapping can grow to.

Signed-off-by: Glauber de Oliveira Costa <gcosta@xxxxxxxxxx>

diff -r 71ea8d34e818 -r 0d6e4c983718 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c   Wed Nov 29 08:36:41 2006 -0500
+++ b/tools/libxc/xc_domain.c   Wed Nov 29 10:08:59 2006 -0500
@@ -313,6 +313,17 @@ int xc_domain_setmaxmem(int xc_handle,
     domctl.cmd = XEN_DOMCTL_max_mem;
     domctl.domain = (domid_t)domid;
     domctl.u.max_mem.max_memkb = max_memkb;
+    return do_domctl(xc_handle, &domctl);
+}
+
+int xc_domain_set_memmap_limit(int xc_handle,
+                            uint32_t domid,
+                            unsigned int map_limitkb)
+{
+    DECLARE_DOMCTL;
+    domctl.cmd = XEN_DOMCTL_memmap_limit;
+    domctl.domain = (domid_t)domid;
+    domctl.u.memmap_limit.map_limitkb = map_limitkb;
     return do_domctl(xc_handle, &domctl);
 }
 
diff -r 71ea8d34e818 -r 0d6e4c983718 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Wed Nov 29 08:36:41 2006 -0500
+++ b/tools/libxc/xenctrl.h     Wed Nov 29 10:08:59 2006 -0500
@@ -415,6 +415,10 @@ int xc_domain_setmaxmem(int xc_handle,
                         uint32_t domid,
                         unsigned int max_memkb);
 
+int xc_domain_set_memmap_limit(int xc_handle,
+                            uint32_t domid,
+                            unsigned int map_limitkb);
+
 int xc_domain_set_time_offset(int xc_handle,
                               uint32_t domid,
                               int32_t time_offset_seconds);
diff -r 71ea8d34e818 -r 0d6e4c983718 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Wed Nov 29 08:36:41 2006 -0500
+++ b/tools/python/xen/lowlevel/xc/xc.c Wed Nov 29 10:08:59 2006 -0500
@@ -741,6 +741,21 @@ static PyObject *pyxc_domain_setmaxmem(X
     return zero;
 }
 
+static PyObject *pyxc_domain_set_memmap_limit(XcObject *self, PyObject *args)
+{
+    uint32_t dom;
+    unsigned int maplimit_kb;
+
+    if (!PyArg_ParseTuple(args, "ii", &dom, &maplimit_kb))
+        return NULL;
+
+    if (xc_domain_set_memmap_limit(self->xc_handle, dom, maplimit_kb) != 0)
+        return PyErr_SetFromErrno(xc_error);
+    
+    Py_INCREF(zero);
+    return zero;
+}
+
 static PyObject *pyxc_domain_memory_increase_reservation(XcObject *self,
                                                          PyObject *args,
                                                          PyObject *kwds)
@@ -1122,6 +1137,14 @@ static PyMethodDef pyxc_methods[] = {
       "Set a domain's memory limit\n"
       " dom [int]: Identifier of domain.\n"
       " maxmem_kb [int]: .\n"
+      "Returns: [int] 0 on success; -1 on error.\n" },
+
+    { "domain_set_memmap_limit", 
+      (PyCFunction)pyxc_domain_set_memmap_limit, 
+      METH_VARARGS, "\n"
+      "Set a domain's physical memory mappping limit\n"
+      " dom [int]: Identifier of domain.\n"
+      " map_limitkb [int]: .\n"
       "Returns: [int] 0 on success; -1 on error.\n" },
 
     { "domain_memory_increase_reservation", 
diff -r 71ea8d34e818 -r 0d6e4c983718 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Wed Nov 29 08:36:41 2006 -0500
+++ b/tools/python/xen/xend/XendDomainInfo.py   Wed Nov 29 10:08:59 2006 -0500
@@ -1297,6 +1297,10 @@ class XendDomainInfo:
 
             # set memory limit
             xc.domain_setmaxmem(self.domid, maxmem)
+       
+            # set physical mapping limit
+            # add an 8MB slack to balance backend allocations.
+            xc.domain_set_memmap_limit(self.domid, maxmem + (8 << 20))
 
             # Make sure there's enough RAM available for the domain
             balloon.free(memory + shadow)
diff -r 71ea8d34e818 -r 0d6e4c983718 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Wed Nov 29 08:36:41 2006 -0500
+++ b/xen/arch/x86/mm.c Wed Nov 29 10:08:59 2006 -0500
@@ -2976,7 +2976,40 @@ long arch_memory_op(int op, XEN_GUEST_HA
 
     case XENMEM_memory_map:
     {
-        return -ENOSYS;
+        struct xen_memory_map memmap;
+        struct domain *d;
+        XEN_GUEST_HANDLE(e820entry_t) buffer;
+        struct e820entry map;
+    
+
+        d = current->domain;
+
+        if ( copy_from_guest(&memmap, arg, 1) )
+            return -EFAULT;
+
+        buffer = guest_handle_cast(memmap.buffer, e820entry_t);
+        if ( unlikely(guest_handle_is_null(buffer)) ) 
+            return -EFAULT;
+
+        memmap.nr_entries = 1;
+
+        if ( d->memmap_limit ) 
+            map.size = d->memmap_limit;
+               else
+                       /* Don know how to implement the mapping. Act as if it 
were not 
+             * implemented */
+                       return -ENOSYS;
+
+        map.addr = 0ULL;
+        map.type = E820_RAM;
+
+        if ( copy_to_guest(arg, &memmap, 1) )
+            return -EFAULT;
+
+        if ( copy_to_guest(buffer, &map, 1) < 0 )
+            return -EFAULT;
+
+        return 0;
     }
 
     case XENMEM_machine_memory_map:
diff -r 71ea8d34e818 -r 0d6e4c983718 xen/common/domctl.c
--- a/xen/common/domctl.c       Wed Nov 29 08:36:41 2006 -0500
+++ b/xen/common/domctl.c       Wed Nov 29 10:08:59 2006 -0500
@@ -552,6 +552,29 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
     }
     break;
 
+    case XEN_DOMCTL_memmap_limit:
+    {
+        struct domain *d;
+        unsigned long new_limit; 
+
+        ret = -ESRCH;
+        d = find_domain_by_id(op->domain);
+        if ( d == NULL )
+            break;
+
+        ret = -EINVAL;
+        new_limit = op->u.memmap_limit.map_limitkb << 10; 
+
+        /* No point in neither calling it more than once, nor
+         * setting physical map limit to zero */
+        if ( (d->memmap_limit == 0) && (new_limit != 0) )
+        {
+            d->memmap_limit = new_limit;
+            ret = 0;
+        }
+
+        put_domain(d);
+    }
     case XEN_DOMCTL_setdomainhandle:
     {
         struct domain *d;
diff -r 71ea8d34e818 -r 0d6e4c983718 xen/include/public/domctl.h
--- a/xen/include/public/domctl.h       Wed Nov 29 08:36:41 2006 -0500
+++ b/xen/include/public/domctl.h       Wed Nov 29 10:08:59 2006 -0500
@@ -385,6 +385,14 @@ typedef struct xen_domctl_settimeoffset 
 typedef struct xen_domctl_settimeoffset xen_domctl_settimeoffset_t;
 DEFINE_XEN_GUEST_HANDLE(xen_domctl_settimeoffset_t);
 
+#define XEN_DOMCTL_memmap_limit       26
+struct xen_domctl_memmap_limit {
+    /* IN variables. */
+    uint64_t map_limitkb;
+};
+typedef struct xen_domctl_memory_map_limit xen_domctl_map_limit_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_map_limit_t);
+
 struct xen_domctl {
     uint32_t cmd;
     uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */
@@ -410,9 +418,11 @@ struct xen_domctl {
         struct xen_domctl_hypercall_init    hypercall_init;
         struct xen_domctl_arch_setup        arch_setup;
         struct xen_domctl_settimeoffset     settimeoffset;
-        uint8_t                             pad[128];
+        struct xen_domctl_memmap_limit      memmap_limit;
+        uint8_t                             pad[120];
     } u;
 };
+
 typedef struct xen_domctl xen_domctl_t;
 DEFINE_XEN_GUEST_HANDLE(xen_domctl_t);
 
diff -r 71ea8d34e818 -r 0d6e4c983718 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h   Wed Nov 29 08:36:41 2006 -0500
+++ b/xen/include/xen/sched.h   Wed Nov 29 10:08:59 2006 -0500
@@ -112,6 +112,7 @@ struct domain
     struct list_head xenpage_list;    /* linked list, of size xenheap_pages */
     unsigned int     tot_pages;       /* number of pages currently possesed */
     unsigned int     max_pages;       /* maximum value for tot_pages        */
+    unsigned int     memmap_limit;    /* the higher our memory map can go   */ 
     unsigned int     xenheap_pages;   /* # pages allocated from Xen heap    */
 
     /* Scheduling. */
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.