[CRIU] [PATCH 4/6] criu: page-xfer: add ability to write pagemap flags

Mike Rapoport rppt at linux.vnet.ibm.com
Thu Sep 8 00:39:10 PDT 2016


Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
---
 criu/include/page-xfer.h |  2 +-
 criu/page-xfer.c         | 40 ++++++++++++++++++++++++++++++++--------
 2 files changed, 33 insertions(+), 9 deletions(-)

diff --git a/criu/include/page-xfer.h b/criu/include/page-xfer.h
index 007733e..bf4900f 100644
--- a/criu/include/page-xfer.h
+++ b/criu/include/page-xfer.h
@@ -12,7 +12,7 @@ extern int cr_page_server(bool daemon_mode, int cfd);
 
 struct page_xfer {
 	/* transfers one vaddr:len entry */
-	int (*write_pagemap)(struct page_xfer *self, struct iovec *iov);
+	int (*write_pagemap)(struct page_xfer *self, struct iovec *iov, u32 flags);
 	/* transfers pages related to previous pagemap */
 	int (*write_pages)(struct page_xfer *self, int pipe, unsigned long len);
 	/* transfers one hole -- vaddr:len entry w/o pages */
diff --git a/criu/page-xfer.c b/criu/page-xfer.c
index a02ca3b..68dba86 100644
--- a/criu/page-xfer.c
+++ b/criu/page-xfer.c
@@ -46,6 +46,9 @@ static void psi2iovec(struct page_server_iov *ps, struct iovec *iov)
 #define PS_IOV_FLUSH		0x1023
 #define PS_IOV_FLUSH_N_CLOSE	0x1024
 
+#define PS_CMD_BITS	16
+#define PS_CMD_MASK	((1 << PS_CMD_BITS) - 1)
+
 #define PS_TYPE_BITS	8
 #define PS_TYPE_MASK	((1 << PS_TYPE_BITS) - 1)
 
@@ -64,6 +67,21 @@ static long decode_pm_id(u64 dst_id)
 	return (long)(dst_id >> PS_TYPE_BITS);
 }
 
+static inline u32 encode_ps_cmd(u32 cmd, u32 flags)
+{
+	return flags << PS_CMD_BITS | cmd;
+}
+
+static inline u32 decode_ps_cmd(u32 cmd)
+{
+	return cmd & PS_CMD_MASK;
+}
+
+static inline u32 decode_ps_flags(u32 cmd)
+{
+	return cmd >> PS_CMD_BITS;
+}
+
 static inline int send_psi(int sk, u32 cmd, u32 nr_pages, u64 vaddr, u64 dst_id)
 {
 	struct page_server_iov pi = {
@@ -90,10 +108,11 @@ static inline int send_iov(int sk, u32 cmd, u64 dst_id, struct iovec *iov)
 }
 
 /* page-server xfer */
-static int write_pagemap_to_server(struct page_xfer *xfer,
-		struct iovec *iov)
+static int write_pagemap_to_server(struct page_xfer *xfer, struct iovec *iov,
+				   u32 flags)
 {
-	return send_iov(xfer->sk, PS_IOV_ADD, xfer->dst_id, iov);
+	return send_iov(xfer->sk, encode_ps_cmd(PS_IOV_ADD, flags),
+			xfer->dst_id, iov);
 }
 
 static int write_pages_to_server(struct page_xfer *xfer,
@@ -152,14 +171,15 @@ static int open_page_server_xfer(struct page_xfer *xfer, int fd_type, long id)
 }
 
 /* local xfer */
-static int write_pagemap_loc(struct page_xfer *xfer,
-		struct iovec *iov)
+static int write_pagemap_loc(struct page_xfer *xfer, struct iovec *iov,
+			     u32 flags)
 {
 	int ret;
 	PagemapEntry pe = PAGEMAP_ENTRY__INIT;
 
 	iovec2pagemap(iov, &pe);
 	pe.has_flags = true;
+	pe.flags = flags;
 	if (opts.auto_dedup && xfer->parent != NULL) {
 		ret = dedup_one_iovec(xfer->parent, iov);
 		if (ret == -1) {
@@ -436,7 +456,7 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
 				continue;
 			}
 
-			if (xfer->write_pagemap(xfer, &iov))
+			if (xfer->write_pagemap(xfer, &iov, 0))
 				return -1;
 			if (xfer->write_pages(xfer, ppb->p[0], iov.iov_len))
 				return -1;
@@ -586,6 +606,7 @@ static int page_server_add(int sk, struct page_server_iov *pi)
 	size_t len;
 	struct page_xfer *lxfer = &cxfer.loc_xfer;
 	struct iovec iov;
+	u32 flags;
 
 	pr_debug("Adding %"PRIx64"/%u\n", pi->vaddr, pi->nr_pages);
 
@@ -593,7 +614,8 @@ static int page_server_add(int sk, struct page_server_iov *pi)
 		return -1;
 
 	psi2iovec(pi, &iov);
-	if (lxfer->write_pagemap(lxfer, &iov))
+	flags = decode_ps_flags(pi->cmd);
+	if (lxfer->write_pagemap(lxfer, &iov, flags))
 		return -1;
 
 	len = iov.iov_len;
@@ -705,6 +727,7 @@ static int page_server_serve(int sk)
 
 	while (1) {
 		struct page_server_iov pi;
+		u32 cmd;
 
 		ret = recv(sk, &pi, sizeof(pi), MSG_WAITALL);
 		if (!ret)
@@ -717,8 +740,9 @@ static int page_server_serve(int sk)
 		}
 
 		flushed = false;
+		cmd = decode_ps_cmd(pi.cmd);
 
-		switch (pi.cmd) {
+		switch (cmd) {
 		case PS_IOV_OPEN:
 			ret = page_server_open(-1, &pi);
 			break;
-- 
1.9.1



More information about the CRIU mailing list