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

[Xen-devel] [PATCH/RFC] memory_map + set_memmap_limit hypercall/domctl



Here's a new shot of the memory map related hypercall/domctl

As previously requested by Keir, I'm adding a new hypercall,
(set_memmap_limit), whose purpose is to inform hypervisor about the 
maximum value the physical limit of a domain can grow to.

I consider it close to a final version, but I'd still like to receive
comments on some specific points (besides any other that you see fit,
for sure ;-) )

* I'm assuming that a (int) representation of max_pages being negative
will always means it's unlimited for this guest, and we don't want to
rely on this for stabilishing our phys map. Keir, can it be granted?

* I'm assuming that the domctl to set the physicall mapping cannot be
called more than once, and returning an EINVAL in such a case. Is it
reasonable?

Thanks!

-- 
Glauber de Oliveira Costa
Red Hat Inc.
"Free as in Freedom"
--- ./xen/arch/x86/mm.c.orig    2006-11-24 09:15:25.000000000 -0500
+++ ./xen/arch/x86/mm.c 2006-11-27 14:52:55.000000000 -0500
@@ -2974,7 +2974,45 @@ 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 we were not supplied with proper information, we try to use  
+         * current max_pages information as an upper bound. If it's zero or
+         * unlimited, tot_pages is all that is left for us */ / 
+        if ( d->memmap_limit ) 
+            map.size = d->memmap_limit;
+        else if ( (int)d->max_pages > 0 )
+            map.size = d->max_pages << PAGE_SHIFT;
+               else
+            map.size = d->tot_pages << PAGE_SHIFT;
+
+        /* 8MB slack (to balance backend allocations). */
+        map.size += 8 << 20;
+        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:
--- ./xen/include/xen/sched.h.orig      2006-11-24 09:15:33.000000000 -0500
+++ ./xen/include/xen/sched.h   2006-11-27 13:59:33.000000000 -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/include/public/domctl.h.orig  2006-11-24 09:16:17.000000000 -0500
+++ ./xen/include/public/domctl.h       2006-11-27 13:55:18.000000000 -0500
@@ -348,6 +348,14 @@ 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 */
@@ -373,9 +381,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);
 
--- ./xen/common/domctl.c.orig  2006-11-24 09:16:03.000000000 -0500
+++ ./xen/common/domctl.c       2006-11-27 13:54:27.000000000 -0500
@@ -546,6 +546,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;
--- ./tools/libxc/xenctrl.h.orig        2006-11-24 09:23:07.000000000 -0500
+++ ./tools/libxc/xenctrl.h     2006-11-27 13:53:09.000000000 -0500
@@ -407,6 +407,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);
--- ./tools/libxc/xc_domain.c.orig      2006-11-24 09:18:08.000000000 -0500
+++ ./tools/libxc/xc_domain.c   2006-11-27 13:57:25.000000000 -0500
@@ -313,6 +313,17 @@ int xc_domain_setmaxmem(int xc_handle,
     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);
+}
+
 int xc_domain_set_time_offset(int xc_handle,
                               uint32_t domid,
                               int32_t time_offset_seconds)
--- ./tools/python/xen/lowlevel/xc/xc.c.orig    2006-11-27 12:54:49.000000000 
-0500
+++ ./tools/python/xen/lowlevel/xc/xc.c 2006-11-27 14:05:25.000000000 -0500
@@ -705,6 +705,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)
@@ -1082,6 +1097,14 @@ static PyMethodDef pyxc_methods[] = {
       " 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", 
       (PyCFunction)pyxc_domain_memory_increase_reservation, 
       METH_VARARGS | METH_KEYWORDS, "\n"
--- ./tools/python/xen/xend/XendDomainInfo.py.orig      2006-11-27 
12:57:15.000000000 -0500
+++ ./tools/python/xen/xend/XendDomainInfo.py   2006-11-27 13:58:47.000000000 
-0500
@@ -1330,6 +1330,9 @@ class XendDomainInfo:
 
             # set memory limit
             xc.domain_setmaxmem(self.domid, maxmem)
+       
+            # set physical mapping limit
+            xc.domain_set_memmap_limit(self.domid, maxmem)
 
             # Make sure there's enough RAM available for the domain
             balloon.free(memory + shadow)
_______________________________________________
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®.