From d6aaa9ee0f8ba5d2d8ff1187b05ed9becee0b40c Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Fri, 22 Jan 2010 10:59:03 +0000 Subject: libxc: New hcall_buf_{prep,release} pre-mlock interface Allow certain performance-critical hypercall wrappers to register data buffers via a new interface which allows them to be 'bounced' into a pre-mlock'ed page-sized per-thread data area. This saves the cost of mlock/munlock on every such hypercall, which can be very expensive on modern kernels. Signed-off-by: Keir Fraser --- tools/libxc/xc_private.h | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) (limited to 'tools/libxc/xc_private.h') diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h index dc88add9c8..fba384cc73 100644 --- a/tools/libxc/xc_private.h +++ b/tools/libxc/xc_private.h @@ -78,9 +78,14 @@ void xc_set_error(int code, const char *fmt, ...); #define PERROR(_m, _a...) xc_set_error(XC_INTERNAL_ERROR, _m " (%d = %s)", \ ## _a , errno, safe_strerror(errno)) +void *xc_memalign(size_t alignment, size_t size); + int lock_pages(void *addr, size_t len); void unlock_pages(void *addr, size_t len); +int hcall_buf_prep(void **addr, size_t len); +void hcall_buf_release(void **addr, size_t len); + static inline void safe_munlock(const void *addr, size_t len) { int saved_errno = errno; @@ -101,21 +106,22 @@ static inline int do_xen_version(int xc_handle, int cmd, void *dest) return do_xen_hypercall(xc_handle, &hypercall); } -static inline int do_physdev_op(int xc_handle, int cmd, void *op) +static inline int do_physdev_op(int xc_handle, int cmd, void *op, size_t len) { int ret = -1; DECLARE_HYPERCALL; - hypercall.op = __HYPERVISOR_physdev_op; - hypercall.arg[0] = (unsigned long) cmd; - hypercall.arg[1] = (unsigned long) op; - if ( lock_pages(op, sizeof(*op)) != 0 ) + if ( hcall_buf_prep(&op, len) != 0 ) { PERROR("Could not lock memory for Xen hypercall"); goto out1; } + hypercall.op = __HYPERVISOR_physdev_op; + hypercall.arg[0] = (unsigned long) cmd; + hypercall.arg[1] = (unsigned long) op; + if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 ) { if ( errno == EACCES ) @@ -123,7 +129,7 @@ static inline int do_physdev_op(int xc_handle, int cmd, void *op) " rebuild the user-space tool set?\n"); } - unlock_pages(op, sizeof(*op)); + hcall_buf_release(&op, len); out1: return ret; @@ -134,17 +140,17 @@ static inline int do_domctl(int xc_handle, struct xen_domctl *domctl) int ret = -1; DECLARE_HYPERCALL; - domctl->interface_version = XEN_DOMCTL_INTERFACE_VERSION; - - hypercall.op = __HYPERVISOR_domctl; - hypercall.arg[0] = (unsigned long)domctl; - - if ( lock_pages(domctl, sizeof(*domctl)) != 0 ) + if ( hcall_buf_prep((void **)&domctl, sizeof(*domctl)) != 0 ) { PERROR("Could not lock memory for Xen hypercall"); goto out1; } + domctl->interface_version = XEN_DOMCTL_INTERFACE_VERSION; + + hypercall.op = __HYPERVISOR_domctl; + hypercall.arg[0] = (unsigned long)domctl; + if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 ) { if ( errno == EACCES ) @@ -152,7 +158,7 @@ static inline int do_domctl(int xc_handle, struct xen_domctl *domctl) " rebuild the user-space tool set?\n"); } - unlock_pages(domctl, sizeof(*domctl)); + hcall_buf_release((void **)&domctl, sizeof(*domctl)); out1: return ret; @@ -163,17 +169,17 @@ static inline int do_sysctl(int xc_handle, struct xen_sysctl *sysctl) int ret = -1; DECLARE_HYPERCALL; - sysctl->interface_version = XEN_SYSCTL_INTERFACE_VERSION; - - hypercall.op = __HYPERVISOR_sysctl; - hypercall.arg[0] = (unsigned long)sysctl; - - if ( lock_pages(sysctl, sizeof(*sysctl)) != 0 ) + if ( hcall_buf_prep((void **)&sysctl, sizeof(*sysctl)) != 0 ) { PERROR("Could not lock memory for Xen hypercall"); goto out1; } + sysctl->interface_version = XEN_SYSCTL_INTERFACE_VERSION; + + hypercall.op = __HYPERVISOR_sysctl; + hypercall.arg[0] = (unsigned long)sysctl; + if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 ) { if ( errno == EACCES ) @@ -181,7 +187,7 @@ static inline int do_sysctl(int xc_handle, struct xen_sysctl *sysctl) " rebuild the user-space tool set?\n"); } - unlock_pages(sysctl, sizeof(*sysctl)); + hcall_buf_release((void **)&sysctl, sizeof(*sysctl)); out1: return ret; -- cgit v1.2.3