aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxc/xc_private.h
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2010-01-22 10:59:03 +0000
committerKeir Fraser <keir.fraser@citrix.com>2010-01-22 10:59:03 +0000
commitd6aaa9ee0f8ba5d2d8ff1187b05ed9becee0b40c (patch)
tree3b69d194167117b66f08f86321756f58703a44e7 /tools/libxc/xc_private.h
parent379e63ed3da8f6d874d9bc5d6fa05a85afb60238 (diff)
downloadxen-d6aaa9ee0f8ba5d2d8ff1187b05ed9becee0b40c.tar.gz
xen-d6aaa9ee0f8ba5d2d8ff1187b05ed9becee0b40c.tar.bz2
xen-d6aaa9ee0f8ba5d2d8ff1187b05ed9becee0b40c.zip
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 <keir.fraser@citrix.com>
Diffstat (limited to 'tools/libxc/xc_private.h')
-rw-r--r--tools/libxc/xc_private.h46
1 files changed, 26 insertions, 20 deletions
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;