[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