Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
No build reason found for images:x86_64
openSUSE:12.2:ARM
xen
xen-unstable.misc.linux_privcmd_map_foreign_bul...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File xen-unstable.misc.linux_privcmd_map_foreign_bulk.retry_paged.patch of Package xen
# HG changeset patch # Parent aa0d678fece208975984e8e59ca223c07fc50c06 tools/libxc: send page-in requests in batches in linux_privcmd_map_foreign_bulk One of the bottlenecks with foreign page-in request is the poor retry handling in linux_privcmd_map_foreign_bulk(). It sends one request per paged gfn at a time and it waits until the gfn is accessible. This causes long delays in mmap requests from qemu-dm and xc_save. Instead of sending one request at a time, walk the entire gfn list and send batches of mmap requests. They will eventually end up in the pagers request ring (if it has room again), and will fill up this ring so that in turn the pager can also process page-in in batches. Signed-off-by: Olaf Hering <olaf@aepfle.de> --- tools/libxc/xc_linux_osdep.c | 72 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 15 deletions(-) Index: xen-4.1.2-testing/tools/libxc/xc_linux_osdep.c =================================================================== --- xen-4.1.2-testing.orig/tools/libxc/xc_linux_osdep.c +++ xen-4.1.2-testing/tools/libxc/xc_linux_osdep.c @@ -167,6 +167,59 @@ static void *linux_privcmd_map_foreign_b return addr; } +/* + * Retry mmap of paged gfns in batches + * retuns < 0 on fatal error + * returns 0 if all gfns left paging state + * returns > 0 if some gfns are still in paging state + * + * Walk all gfns are assemble blocks of gfns in paging state. + * This will keep the request ring full and avoids delays. + */ +static int retry_paged(int fd, uint32_t dom, void *addr, + const xen_pfn_t *arr, int *err, unsigned int num) +{ + privcmd_mmapbatch_v2_t ioctlx; + int rc, paged = 0, i = 0; + + do + { + /* Skip gfns not in paging state */ + if ( err[i] != -ENOENT ) + { + i++; + continue; + } + + paged++; + + /* At least one gfn is still in paging state */ + ioctlx.num = 1; + ioctlx.dom = dom; + ioctlx.addr = (unsigned long)addr + ((unsigned long)i<<XC_PAGE_SHIFT); + ioctlx.arr = arr + i; + ioctlx.err = err + i; + + /* Assemble a batch of requests */ + while ( ++i < num ) + { + if ( err[i] != -ENOENT ) + break; + ioctlx.num++; + } + + /* Send request and abort on fatal error */ + rc = ioctl(fd, IOCTL_PRIVCMD_MMAPBATCH_V2, &ioctlx); + if ( rc < 0 && errno != ENOENT ) + goto out; + + } while ( i < num ); + + rc = paged; +out: + return rc; +} + static void *linux_privcmd_map_foreign_bulk(xc_interface *xch, xc_osdep_handle h, uint32_t dom, int prot, const xen_pfn_t *arr, int *err, unsigned int num) @@ -196,21 +249,10 @@ static void *linux_privcmd_map_foreign_b /* Command was recognized, some gfn in arr are in paging state */ if ( rc < 0 && errno == ENOENT ) { - for ( i = rc = 0; rc == 0 && i < num; i++ ) - { - if ( err[i] != -ENOENT ) - continue; - - ioctlx.num = 1; - ioctlx.dom = dom; - ioctlx.addr = (unsigned long)addr + ((unsigned long)i<<XC_PAGE_SHIFT); - ioctlx.arr = arr + i; - ioctlx.err = err + i; - do { - usleep(100); - rc = ioctl(fd, IOCTL_PRIVCMD_MMAPBATCH_V2, &ioctlx); - } while ( rc < 0 && errno == ENOENT && err[i] == -ENOENT ); - } + do { + usleep(100); + rc = retry_paged(fd, dom, addr, arr, err, num); + } while ( rc > 0 ); } /* Command was not recognized, use fall back */ else if ( rc < 0 && errno == EINVAL && (int)num > 0 )
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor