[CRIU] [PATCH 3/3] proc: Keep /proc/self cached separately from /proc/pid

Pavel Emelyanov xemul at parallels.com
Tue Sep 23 09:33:32 PDT 2014


When dumping tasks we do a lot of open_proc()-s and to
speed this up the /proc/pid directory is opened first
and the fd is kept cached. So next open_proc()-s do just
openat(cached_fd, name).

The thing is that we sometimes call open_proc(PROC_SELF)
in between and proc helpers cache the /proc/self too. As
the result we have a bunch of 

  open(/proc/pid) 
  close()
  open(/proc/self)
  close()

see-saw-s in the middle of dumping tasks.

To fix this we may cache the /proc/self separately from
the /proc/pid descriptor. This eliminates quite a lot
of pointless open-s and close-s.

Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
---
 util.c | 60 +++++++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 45 insertions(+), 15 deletions(-)

diff --git a/util.c b/util.c
index 0fffb46..8283730 100644
--- a/util.c
+++ b/util.c
@@ -159,20 +159,48 @@ int move_img_fd(int *img_fd, int want_fd)
 	return 0;
 }
 
+/*
+ * Cached opened /proc/$pid and /proc/self files.
+ * Used for faster access to /proc/.../foo files
+ * by using openat()-s
+ */
+
 static pid_t open_proc_pid = PROC_NONE;
 static int open_proc_fd = -1;
+static int open_proc_self_fd = -1;
 
-int close_pid_proc(void)
+static inline void set_proc_self_fd(int fd)
 {
-	int ret = 0;
+	if (open_proc_self_fd >= 0)
+		close(open_proc_self_fd);
+
+	open_proc_self_fd = fd;
+}
 
+static inline void set_proc_pid_fd(int pid, int fd)
+{
 	if (open_proc_fd >= 0)
-		ret = close(open_proc_fd);
+		close(open_proc_fd);
 
-	open_proc_fd = -1;
-	open_proc_pid = PROC_NONE;
+	open_proc_pid = pid;
+	open_proc_fd = fd;
+}
 
-	return ret;
+static inline int get_proc_fd(int pid)
+{
+	if (pid == PROC_SELF)
+		return open_proc_self_fd;
+	else if (pid == open_proc_pid)
+		return open_proc_fd;
+	else
+		return -1;
+}
+
+int close_pid_proc(void)
+{
+	set_proc_self_fd(-1);
+	set_proc_pid_fd(PROC_NONE, -1);
+	return 0;
 }
 
 void close_proc()
@@ -213,10 +241,9 @@ inline int open_pid_proc(pid_t pid)
 	int fd;
 	int dfd;
 
-	if (pid == open_proc_pid)
-		return open_proc_fd;
-
-	close_pid_proc();
+	fd = get_proc_fd(pid);
+	if (fd >= 0)
+		return fd;
 
 	dfd = get_service_fd(PROC_FD_OFF);
 	if (dfd < 0) {
@@ -239,13 +266,16 @@ inline int open_pid_proc(pid_t pid)
 		snprintf(path, sizeof(path), "%d", pid);
 
 	fd = openat(dfd, path, O_RDONLY);
-	if (fd < 0)
+	if (fd < 0) {
 		pr_perror("Can't open %s", path);
-	else {
-		open_proc_fd = fd;
-		open_proc_pid = pid;
+		return -1;
 	}
 
+	if (pid == PROC_SELF)
+		set_proc_self_fd(fd);
+	else
+		set_proc_pid_fd(pid, fd);
+
 	return fd;
 }
 
-- 
1.8.4.2




More information about the CRIU mailing list