[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |