mirror of https://gitlab.com/qemu-project/qemu
xen-block: avoid repeated memory allocation
The xen-block dataplane currently allocates memory to hold the data for each request as that request is used, and frees it afterwards. Because it requires page-aligned blocks, this interacts poorly with non-page- aligned allocations and balloons the heap. Instead, allocate the maximum possible buffer size required for the protocol, which is BLKIF_MAX_SEGMENTS_PER_REQUEST (currently 11) pages when the request structure is created, and keep that buffer until it is destroyed. Since the requests are re-used via a free list, this should actually improve memory usage. Signed-off-by: Tim Smith <tim.smith@citrix.com> Re-based and commit comment adjusted. Signed-off-by: Paul Durrant <paul.durrant@citrix.com> Acked-by: Anthony PERARD <anthony.perard@citrix.com> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
This commit is contained in:
parent
bfd0d63660
commit
c6025bd197
|
@ -70,7 +70,6 @@ static void reset_request(XenBlockRequest *request)
|
||||||
memset(&request->req, 0, sizeof(request->req));
|
memset(&request->req, 0, sizeof(request->req));
|
||||||
request->status = 0;
|
request->status = 0;
|
||||||
request->start = 0;
|
request->start = 0;
|
||||||
request->buf = NULL;
|
|
||||||
request->size = 0;
|
request->size = 0;
|
||||||
request->presync = 0;
|
request->presync = 0;
|
||||||
|
|
||||||
|
@ -95,6 +94,14 @@ static XenBlockRequest *xen_block_start_request(XenBlockDataPlane *dataplane)
|
||||||
/* allocate new struct */
|
/* allocate new struct */
|
||||||
request = g_malloc0(sizeof(*request));
|
request = g_malloc0(sizeof(*request));
|
||||||
request->dataplane = dataplane;
|
request->dataplane = dataplane;
|
||||||
|
/*
|
||||||
|
* We cannot need more pages per requests than this, and since we
|
||||||
|
* re-use requests, allocate the memory once here. It will be freed
|
||||||
|
* xen_block_dataplane_destroy() when the request list is freed.
|
||||||
|
*/
|
||||||
|
request->buf = qemu_memalign(XC_PAGE_SIZE,
|
||||||
|
BLKIF_MAX_SEGMENTS_PER_REQUEST *
|
||||||
|
XC_PAGE_SIZE);
|
||||||
dataplane->requests_total++;
|
dataplane->requests_total++;
|
||||||
qemu_iovec_init(&request->v, 1);
|
qemu_iovec_init(&request->v, 1);
|
||||||
} else {
|
} else {
|
||||||
|
@ -272,14 +279,12 @@ static void xen_block_complete_aio(void *opaque, int ret)
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
xen_block_copy_request(request);
|
xen_block_copy_request(request);
|
||||||
}
|
}
|
||||||
qemu_vfree(request->buf);
|
|
||||||
break;
|
break;
|
||||||
case BLKIF_OP_WRITE:
|
case BLKIF_OP_WRITE:
|
||||||
case BLKIF_OP_FLUSH_DISKCACHE:
|
case BLKIF_OP_FLUSH_DISKCACHE:
|
||||||
if (!request->req.nr_segments) {
|
if (!request->req.nr_segments) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
qemu_vfree(request->buf);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -360,12 +365,10 @@ static int xen_block_do_aio(XenBlockRequest *request)
|
||||||
{
|
{
|
||||||
XenBlockDataPlane *dataplane = request->dataplane;
|
XenBlockDataPlane *dataplane = request->dataplane;
|
||||||
|
|
||||||
request->buf = qemu_memalign(XC_PAGE_SIZE, request->size);
|
|
||||||
if (request->req.nr_segments &&
|
if (request->req.nr_segments &&
|
||||||
(request->req.operation == BLKIF_OP_WRITE ||
|
(request->req.operation == BLKIF_OP_WRITE ||
|
||||||
request->req.operation == BLKIF_OP_FLUSH_DISKCACHE) &&
|
request->req.operation == BLKIF_OP_FLUSH_DISKCACHE) &&
|
||||||
xen_block_copy_request(request)) {
|
xen_block_copy_request(request)) {
|
||||||
qemu_vfree(request->buf);
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -665,6 +668,7 @@ void xen_block_dataplane_destroy(XenBlockDataPlane *dataplane)
|
||||||
request = QLIST_FIRST(&dataplane->freelist);
|
request = QLIST_FIRST(&dataplane->freelist);
|
||||||
QLIST_REMOVE(request, list);
|
QLIST_REMOVE(request, list);
|
||||||
qemu_iovec_destroy(&request->v);
|
qemu_iovec_destroy(&request->v);
|
||||||
|
qemu_vfree(request->buf);
|
||||||
g_free(request);
|
g_free(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue