[CRIU] [PATCH 05/11] lazy-pages: use poll instead of select

Mike Rapoport rppt at linux.vnet.ibm.com
Sun Apr 10 23:19:48 PDT 2016


Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
---
 criu/uffd.c | 47 ++++++++++++++++++++++++++++++++---------------
 1 file changed, 32 insertions(+), 15 deletions(-)

diff --git a/criu/uffd.c b/criu/uffd.c
index 254a5b3..14de015 100644
--- a/criu/uffd.c
+++ b/criu/uffd.c
@@ -500,15 +500,17 @@ out:
 	return ret;
 }
 
+#define POLL_TIMEOUT 5000
+
 static int handle_requests(int fd)
 {
-	fd_set set;
+	struct pollfd *pollfd;
+	int nr_pollfd;
 	int ret = -1;
 	struct uffd_msg msg;
 	__u64 flags;
 	__u64 address;
 	unsigned long ps;
-	struct timeval timeout;
 	struct uffd_pages_struct *uffd_pages;
 	void *dest;
 
@@ -521,34 +523,46 @@ static int handle_requests(int fd)
 	if ((total_pages = find_vmas(&uffd_list)) == -1)
 		return -1;
 
-	/* Initialize FD sets for read() with timeouts (using select()) */
-	FD_ZERO(&set);
-	FD_SET(fd, &set);
-
 	/* All operations will be done on page size */
 	ps = page_size();
 	dest = malloc(ps);
 
+	/* allocate pollfd per task + pollfd for listen */
+	nr_pollfd = task_entries->nr_tasks + 1;
+	pollfd = malloc(sizeof(*pollfd) * nr_pollfd);
+	if (!pollfd || !dest) {
+		pr_err("memory allocation failed\n");
+		ret = -1;
+		goto out;
+	}
+
+	/*
+	 * use nr_pollfd to set number of pollfd's being polled
+	 * FIXME: eventually nr_pollfd should be nr_tasks + 1, and the
+	 * first fd to poll on should that of listen
+	 */
+	nr_pollfd = 1;
+	pollfd[0].fd = fd;
+	pollfd[0].events = POLLIN;
+
 	while (1) {
 		bool page_sent = false;
 		/*
 		 * Setting the timeout to 5 seconds. If after this time
 		 * no uffd pages are requested the code switches to
 		 * copying the remaining pages.
-		 *
-		 * Timeout is re-defined every time select() is run as
-		 * select(2) says:
-		 *  Consider timeout to be undefined after select() returns.
 		 */
-		timeout.tv_sec = 5;
-		timeout.tv_usec = 0;
-		ret = select(fd + 1, &set, NULL, NULL, &timeout);
-		pr_debug("select() rc: 0x%x\n", ret);
-		if (ret == 0) {
+		ret = poll(pollfd, nr_pollfd, POLL_TIMEOUT);
+		pr_debug("poll() rc: 0x%x\n", ret);
+		if (ret < 0) {
+			pr_perror("polling failed");
+			goto out;
+		} else if (ret == 0) {
 			pr_debug("read timeout\n");
 			pr_debug("switching from request to copy mode\n");
 			break;
 		}
+
 		ret = read(fd, &msg, sizeof(msg));
 		pr_debug("read() ret: 0x%x\n", ret);
 		if (!ret)
@@ -613,6 +627,7 @@ static int handle_requests(int fd)
 	ret = 0;
 
 out:
+	free(pollfd);
 	free(dest);
 	close(fd);
 	return ret;
@@ -674,6 +689,8 @@ int cr_lazy_pages()
 	pr_debug("uffd is 0x%d\n", uffd);
 	uffd_flags = fcntl(uffd, F_GETFD, NULL);
 	pr_debug("uffd_flags are 0x%x\n", uffd_flags);
+	if (fcntl(uffd, F_SETFD, uffd_flags | O_NONBLOCK))
+		return -1;
 
 	ret = handle_requests(uffd);
 	close(listen);
-- 
1.9.1



More information about the CRIU mailing list