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)
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;
}
......
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