|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v7 3/6] libs/guest: fill directly iov structure collapsing them
Instead of storing page pointers into an array and lately adding to
iov vector add the pages directly to iov to avoid "guest_data"
array.
Each page was sent using a different iovec item. This potentially exceed
Linux maximum (1024).
Coalesce adjacent IO vector elements to attempt to reduce the number of
overall IO vectors for each operation.
Also some implementation (MiniOS) emulate writev with multiple write calls.
Signed-off-by: Frediano Ziglio <frediano.ziglio@xxxxxxxxxx>
---
Changes since v2:
- change prefix in subject.
Changes since v4:
- added Reviewed-by;
- improved commit message;
- minor style fix.
Changes since v6:
- merged 2 commits;
- reduced diff.
---
tools/libs/guest/xg_sr_save.c | 33 +++++++++++----------------------
1 file changed, 11 insertions(+), 22 deletions(-)
diff --git a/tools/libs/guest/xg_sr_save.c b/tools/libs/guest/xg_sr_save.c
index a6734579aa..84fdbe4140 100644
--- a/tools/libs/guest/xg_sr_save.c
+++ b/tools/libs/guest/xg_sr_save.c
@@ -88,7 +88,6 @@ static int write_batch(struct xc_sr_context *ctx)
xc_interface *xch = ctx->xch;
xen_pfn_t *mfns = NULL, *types = NULL;
void *guest_mapping = NULL;
- void **guest_data = NULL;
void **local_pages = NULL;
int *errors = NULL, rc = -1;
unsigned int i, p, nr_pages = 0, nr_pages_mapped = 0;
@@ -118,8 +117,6 @@ static int write_batch(struct xc_sr_context *ctx)
types = malloc(nr_pfns * sizeof(*types));
/* Errors from attempting to map the gfns. */
errors = malloc(nr_pfns * sizeof(*errors));
- /* Pointers to page data to send. Mapped gfns or local allocations. */
- guest_data = calloc(nr_pfns, sizeof(*guest_data));
/* Pointers to locally allocated pages. Need freeing. */
local_pages = calloc(nr_pfns, sizeof(*local_pages));
/* iovec[] for writev(). */
@@ -127,7 +124,7 @@ static int write_batch(struct xc_sr_context *ctx)
/* page_data record PFNs list */
rec_pfns = malloc(nr_pfns * sizeof(*rec_pfns));
- if ( !mfns || !types || !errors || !guest_data || !local_pages || !iov ||
!rec_pfns )
+ if ( !mfns || !types || !errors || !local_pages || !iov || !rec_pfns )
{
ERROR("Unable to allocate arrays for a batch of %u pages",
nr_pfns);
@@ -218,8 +215,17 @@ static int write_batch(struct xc_sr_context *ctx)
else
goto err;
}
+ else if ( iov[iovcnt - 1].iov_base + iov[iovcnt - 1].iov_len !=
+ page )
+ {
+ iov[iovcnt].iov_base = page;
+ iov[iovcnt].iov_len = PAGE_SIZE;
+ iovcnt++;
+ }
else
- guest_data[i] = page;
+ {
+ iov[iovcnt - 1].iov_len += PAGE_SIZE;
+ }
rc = -1;
++p;
@@ -231,28 +237,12 @@ static int write_batch(struct xc_sr_context *ctx)
for ( i = 0; i < nr_pfns; ++i )
rec_pfns[i] = ((uint64_t)(types[i]) << 32) | ctx->save.batch_pfns[i];
- if ( nr_pages )
- {
- for ( i = 0; i < nr_pfns; ++i )
- {
- if ( guest_data[i] )
- {
- iov[iovcnt].iov_base = guest_data[i];
- iov[iovcnt].iov_len = PAGE_SIZE;
- iovcnt++;
- --nr_pages;
- }
- }
- }
-
if ( writev_exact(ctx->fd, iov, iovcnt) )
{
PERROR("Failed to write page data to stream");
goto err;
}
- /* Sanity check we have sent all the pages we expected to. */
- assert(nr_pages == 0);
rc = ctx->save.nr_batch_pfns = 0;
err:
@@ -263,7 +253,6 @@ static int write_batch(struct xc_sr_context *ctx)
free(rec_pfns);
free(iov);
free(local_pages);
- free(guest_data);
free(errors);
free(types);
free(mfns);
--
2.43.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |