mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 02:30:03 +01:00
Per page operations in the paging, sharing, and access tracking subsystems are all implemented with domctls (e.g. a domctl to evict one page, or to share one page). Under heavy load, the domctl path reveals a lack of scalability. The domctl lock serializes dom0's vcpus in the hypervisor. When performing thousands of per-page operations on dozens of domains, these vcpus will spin in the hypervisor. Beyond the aggressive locking, an added inefficiency of blocking vcpus in the domctl lock is that dom0 is prevented from re-scheduling any of its other work-starved processes. We retain the domctl interface for setting up and tearing down paging/sharing/mem access for a domain. But we migrate all the per page operations to use the memory_op hypercalls (e.g XENMEM_*). Signed-off-by: Andres Lagar-Cavilla <andres@lagarcavilla> Signed-off-by: Adin Scannell <adin@scannell.ca> Acked-by: Tim Deegan <tim@xen.org> Acked-by: Ian Jackson <ian.jackson@eu.citrix.com> Committed-by: Tim Deegan <tim@xen.org>
113 lines
3.5 KiB
C
113 lines
3.5 KiB
C
/******************************************************************************
|
|
*
|
|
* tools/libxc/xc_mem_paging.c
|
|
*
|
|
* Interface to low-level memory paging functionality.
|
|
*
|
|
* Copyright (c) 2009 by Citrix Systems, Inc. (Patrick Colp)
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include "xc_private.h"
|
|
|
|
|
|
int xc_mem_paging_enable(xc_interface *xch, domid_t domain_id,
|
|
void *shared_page, void *ring_page)
|
|
{
|
|
return xc_mem_event_control(xch, domain_id,
|
|
XEN_DOMCTL_MEM_EVENT_OP_PAGING_ENABLE,
|
|
XEN_DOMCTL_MEM_EVENT_OP_PAGING,
|
|
shared_page, ring_page);
|
|
}
|
|
|
|
int xc_mem_paging_disable(xc_interface *xch, domid_t domain_id)
|
|
{
|
|
return xc_mem_event_control(xch, domain_id,
|
|
XEN_DOMCTL_MEM_EVENT_OP_PAGING_DISABLE,
|
|
XEN_DOMCTL_MEM_EVENT_OP_PAGING,
|
|
NULL, NULL);
|
|
}
|
|
|
|
int xc_mem_paging_nominate(xc_interface *xch, domid_t domain_id, unsigned long gfn)
|
|
{
|
|
return xc_mem_event_memop(xch, domain_id,
|
|
XENMEM_paging_op_nominate,
|
|
XENMEM_paging_op,
|
|
gfn, NULL);
|
|
}
|
|
|
|
int xc_mem_paging_evict(xc_interface *xch, domid_t domain_id, unsigned long gfn)
|
|
{
|
|
return xc_mem_event_memop(xch, domain_id,
|
|
XENMEM_paging_op_evict,
|
|
XENMEM_paging_op,
|
|
gfn, NULL);
|
|
}
|
|
|
|
int xc_mem_paging_prep(xc_interface *xch, domid_t domain_id, unsigned long gfn)
|
|
{
|
|
return xc_mem_event_memop(xch, domain_id,
|
|
XENMEM_paging_op_prep,
|
|
XENMEM_paging_op,
|
|
gfn, NULL);
|
|
}
|
|
|
|
int xc_mem_paging_load(xc_interface *xch, domid_t domain_id,
|
|
unsigned long gfn, void *buffer)
|
|
{
|
|
int rc, old_errno;
|
|
|
|
errno = -EINVAL;
|
|
|
|
if ( !buffer )
|
|
return -1;
|
|
|
|
if ( ((unsigned long) buffer) & (XC_PAGE_SIZE - 1) )
|
|
return -1;
|
|
|
|
if ( mlock(buffer, XC_PAGE_SIZE) )
|
|
return -1;
|
|
|
|
rc = xc_mem_event_memop(xch, domain_id,
|
|
XENMEM_paging_op_prep,
|
|
XENMEM_paging_op,
|
|
gfn, buffer);
|
|
|
|
old_errno = errno;
|
|
munlock(buffer, XC_PAGE_SIZE);
|
|
errno = old_errno;
|
|
|
|
return rc;
|
|
}
|
|
|
|
int xc_mem_paging_resume(xc_interface *xch, domid_t domain_id, unsigned long gfn)
|
|
{
|
|
return xc_mem_event_memop(xch, domain_id,
|
|
XENMEM_paging_op_resume,
|
|
XENMEM_paging_op,
|
|
gfn, NULL);
|
|
}
|
|
|
|
|
|
/*
|
|
* Local variables:
|
|
* mode: C
|
|
* c-set-style: "BSD"
|
|
* c-basic-offset: 4
|
|
* indent-tabs-mode: nil
|
|
* End:
|
|
*/
|