[CRIU] [PATCH 02/11] lazy-pages: split_iov: always create the new iov above the one being split
Mike Rapoport
rppt at linux.vnet.ibm.com
Sun Mar 25 16:27:22 MSK 2018
Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
---
criu/uffd.c | 40 +++++++++++++++++-----------------------
1 file changed, 17 insertions(+), 23 deletions(-)
diff --git a/criu/uffd.c b/criu/uffd.c
index 62faa2f..16637d3 100644
--- a/criu/uffd.c
+++ b/criu/uffd.c
@@ -390,7 +390,7 @@ static struct lazy_iov *find_iov(struct lazy_pages_info *lpi,
return NULL;
}
-static int split_iov(struct lazy_iov *iov, unsigned long addr, bool new_below)
+static int split_iov(struct lazy_iov *iov, unsigned long addr)
{
struct lazy_iov *new;
@@ -398,21 +398,11 @@ static int split_iov(struct lazy_iov *iov, unsigned long addr, bool new_below)
if (!new)
return -1;
- if (new_below) {
- new->base = iov->base;
- new->img_base = iov->img_base;
- new->len = addr - iov->base;
- iov->base = addr;
- iov->img_base += new->len;
- iov->len -= new->len;
- list_add_tail(&new->l, &iov->l);
- } else {
- new->base = addr;
- new->img_base = iov->img_base + addr - iov->base;
- new->len = iov->len - (addr - iov->base);
- iov->len -= new->len;
- list_add(&new->l, &iov->l);
- }
+ new->base = addr;
+ new->img_base = iov->img_base + addr - iov->base;
+ new->len = iov->len - (addr - iov->base);
+ iov->len -= new->len;
+ list_add(&new->l, &iov->l);
return 0;
}
@@ -485,7 +475,7 @@ static int drop_iovs(struct lazy_pages_info *lpi, unsigned long addr, int len)
iov->img_base += len;
iov->len -= len;
} else {
- if (split_iov(iov, addr + len, false))
+ if (split_iov(iov, addr + len))
return -1;
iov->len -= len;
}
@@ -533,14 +523,18 @@ static int remap_iovs(struct lazy_pages_info *lpi, unsigned long from,
from = iov->base;
}
- if (from > iov->base)
- if (split_iov(iov, from, true))
- return -1;
- if (from + len < iov_end)
- if (split_iov(iov, from + len, false))
+ if (from > iov->base) {
+ if (split_iov(iov, from))
return -1;
+ list_safe_reset_next(iov, n, l);
+ continue;
+ }
- list_safe_reset_next(iov, n, l);
+ if (from + len < iov_end) {
+ if (split_iov(iov, from + len))
+ return -1;
+ list_safe_reset_next(iov, n, l);
+ }
/* here we have iov->base = from, iov_end <= from + len */
from = iov_end;
--
2.7.4
More information about the CRIU
mailing list