Commit abeae267 authored by Pavel Emelyanov's avatar Pavel Emelyanov

proc: Keep /proc/self cached separately from /proc/pid

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: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 829d4332
...@@ -159,20 +159,48 @@ int move_img_fd(int *img_fd, int want_fd) ...@@ -159,20 +159,48 @@ int move_img_fd(int *img_fd, int want_fd)
return 0; 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 pid_t open_proc_pid = PROC_NONE;
static int open_proc_fd = -1; 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) if (open_proc_fd >= 0)
ret = close(open_proc_fd); close(open_proc_fd);
open_proc_fd = -1; open_proc_pid = pid;
open_proc_pid = PROC_NONE; 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() void close_proc()
...@@ -213,10 +241,9 @@ inline int open_pid_proc(pid_t pid) ...@@ -213,10 +241,9 @@ inline int open_pid_proc(pid_t pid)
int fd; int fd;
int dfd; int dfd;
if (pid == open_proc_pid) fd = get_proc_fd(pid);
return open_proc_fd; if (fd >= 0)
return fd;
close_pid_proc();
dfd = get_service_fd(PROC_FD_OFF); dfd = get_service_fd(PROC_FD_OFF);
if (dfd < 0) { if (dfd < 0) {
...@@ -239,13 +266,16 @@ inline int open_pid_proc(pid_t pid) ...@@ -239,13 +266,16 @@ inline int open_pid_proc(pid_t pid)
snprintf(path, sizeof(path), "%d", pid); snprintf(path, sizeof(path), "%d", pid);
fd = openat(dfd, path, O_RDONLY); fd = openat(dfd, path, O_RDONLY);
if (fd < 0) if (fd < 0) {
pr_perror("Can't open %s", path); pr_perror("Can't open %s", path);
else { return -1;
open_proc_fd = fd;
open_proc_pid = pid;
} }
if (pid == PROC_SELF)
set_proc_self_fd(fd);
else
set_proc_pid_fd(pid, fd);
return fd; return fd;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment