Skip to content

Commit

Permalink
proc_fuse: add psi(pressure stall information) procfs
Browse files Browse the repository at this point in the history
Kernel support psi(pressure stall information) since 4.20
with procfs /proc/pressure/{io,cpu,memory} and
cgroupv2 {io.pressure, cpu.pressure, memory.pressure}.

This patch add read-only psi procfs,
and people can get pressure information now.
Full functional feature for monitoring are still under investigation.

Signed-off-by: Feng Sun <[email protected]>
  • Loading branch information
loyou committed Nov 13, 2024
1 parent 0452e12 commit 390f45f
Show file tree
Hide file tree
Showing 8 changed files with 435 additions and 22 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ such as:
/proc/swaps
/proc/uptime
/proc/slabinfo
/proc/pressure/io
/proc/pressure/cpu
/proc/pressure/memory
/sys/devices/system/cpu/online
```

Expand Down Expand Up @@ -109,6 +112,9 @@ docker run -it -m 256m --memory-swap 256m \
-v /var/lib/lxcfs/proc/swaps:/proc/swaps:rw \
-v /var/lib/lxcfs/proc/uptime:/proc/uptime:rw \
-v /var/lib/lxcfs/proc/slabinfo:/proc/slabinfo:rw \
-v /var/lib/lxcfs/proc/pressure/io:/proc/pressure/io:rw \
-v /var/lib/lxcfs/proc/pressure/cpu:/proc/pressure/cpu:rw \
-v /var/lib/lxcfs/proc/pressure/memory:/proc/pressure/memory:rw \
-v /var/lib/lxcfs/sys/devices/system/cpu:/sys/devices/system/cpu:rw \
ubuntu:18.04 /bin/bash
```
Expand Down
3 changes: 3 additions & 0 deletions src/api_extensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ static char *api_extensions[] = {
"proc_swaps",
"proc_uptime",
"proc_slabinfo",
"proc_pressure_io",
"proc_pressure_cpu",
"proc_pressure_memory",
"shared_pidns",
"cpuview_daemon",
"loadavg_daemon",
Expand Down
15 changes: 13 additions & 2 deletions src/bindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ enum lxcfs_virt_t {
LXC_TYPE_CGDIR,
LXC_TYPE_CGFILE,

LXC_TYPE_PROC,
LXC_TYPE_PROC_MEMINFO,
#define LXC_TYPE_PROC_MEMINFO_PATH "/proc/meminfo"

Expand All @@ -57,6 +58,16 @@ enum lxcfs_virt_t {
LXC_TYPE_PROC_SLABINFO,
#define LXC_TYPE_PROC_SLABINFO_PATH "/proc/slabinfo"

LXC_TYPE_PROC_PRESSURE,
LXC_TYPE_PROC_PRESSURE_IO,
#define LXC_TYPE_PROC_PRESSURE_IO_PATH "/proc/pressure/io"

LXC_TYPE_PROC_PRESSURE_CPU,
#define LXC_TYPE_PROC_PRESSURE_CPU_PATH "/proc/pressure/cpu"

LXC_TYPE_PROC_PRESSURE_MEMORY,
#define LXC_TYPE_PROC_PRESSURE_MEMORY_PATH "/proc/pressure/memory"

LXC_TYPE_SYS,
LXC_TYPE_SYS_DEVICES,
LXC_TYPE_SYS_DEVICES_SYSTEM,
Expand All @@ -70,8 +81,8 @@ enum lxcfs_virt_t {
};

/* Macros below used to check the class from the file types above */
#define LXCFS_TYPE_CGROUP(type) (type >= LXC_TYPE_CGDIR && type < LXC_TYPE_PROC_MEMINFO)
#define LXCFS_TYPE_PROC(type) (type >= LXC_TYPE_PROC_MEMINFO && type < LXC_TYPE_SYS)
#define LXCFS_TYPE_CGROUP(type) (type >= LXC_TYPE_CGDIR && type < LXC_TYPE_PROC)
#define LXCFS_TYPE_PROC(type) (type >= LXC_TYPE_PROC && type < LXC_TYPE_SYS)
#define LXCFS_TYPE_SYS(type) (type >= LXC_TYPE_SYS && type < LXC_TYPE_MAX)
#define LXCFS_TYPE_OK(type) (type >= LXC_TYPE_CGDIR && type < LXC_TYPE_MAX)

Expand Down
52 changes: 52 additions & 0 deletions src/cgroups/cgfsng.c
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,54 @@ static bool cgfsng_can_use_cpuview(struct cgroup_ops *ops)
return true;
}

static int cgfsng_get_pressure_io_fd(struct cgroup_ops *ops, const char *cgroup)
{
__do_free char *path = NULL;
struct hierarchy *h;

h = ops->get_hierarchy(ops, "blkio");
if (!h)
return -1;

if (faccessat(h->fd, "io.pressure", F_OK, 0))
return -1;

path = must_make_path_relative(cgroup, "io.pressure", NULL);
return openat(h->fd, path, O_RDWR | O_CLOEXEC | O_NOFOLLOW);
}

static int cgfsng_get_pressure_cpu_fd(struct cgroup_ops *ops, const char *cgroup)
{
__do_free char *path = NULL;
struct hierarchy *h;

h = ops->get_hierarchy(ops, "cpu");
if (!h)
return -1;

if (faccessat(h->fd, "cpu.pressure", F_OK, 0))
return -1;

path = must_make_path_relative(cgroup, "cpu.pressure", NULL);
return openat(h->fd, path, O_RDWR | O_CLOEXEC | O_NOFOLLOW);
}

static int cgfsng_get_pressure_memory_fd(struct cgroup_ops *ops, const char *cgroup)
{
__do_free char *path = NULL;
struct hierarchy *h;

h = ops->get_hierarchy(ops, "memory");
if (!h)
return -1;

if (faccessat(h->fd, "memory.pressure", F_OK, 0))
return -1;

path = must_make_path_relative(cgroup, "memory.pressure", NULL);
return openat(h->fd, path, O_RDWR | O_CLOEXEC | O_NOFOLLOW);
}

/* At startup, parse_hierarchies finds all the info we need about cgroup
* mountpoints and current cgroups, and stores it in @d.
*/
Expand Down Expand Up @@ -1074,6 +1122,10 @@ struct cgroup_ops *cgfsng_ops_init(void)
cgfsng_ops->get_io_merged = cgfsng_get_io_merged;
cgfsng_ops->get_io_wait_time = cgfsng_get_io_wait_time;

/* psi */
cgfsng_ops->get_pressure_io_fd = cgfsng_get_pressure_io_fd;
cgfsng_ops->get_pressure_cpu_fd = cgfsng_get_pressure_cpu_fd;
cgfsng_ops->get_pressure_memory_fd = cgfsng_get_pressure_memory_fd;

return move_ptr(cgfsng_ops);
}
7 changes: 6 additions & 1 deletion src/cgroups/cgroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ struct cgroup_ops {
char **value);
bool (*can_use_cpuview)(struct cgroup_ops *ops);

/* io */
/* blkio */
int (*get_io_service_bytes)(struct cgroup_ops *ops, const char *cgroup,
char **value);
int (*get_io_service_time)(struct cgroup_ops *ops, const char *cgroup,
Expand All @@ -166,6 +166,11 @@ struct cgroup_ops {
char **value);
int (*get_io_wait_time)(struct cgroup_ops *ops, const char *cgroup,
char **value);
/* psi */
int (*get_pressure_io_fd)(struct cgroup_ops *ops, const char *cgroup);
int (*get_pressure_cpu_fd)(struct cgroup_ops *ops, const char *cgroup);
int (*get_pressure_memory_fd)(struct cgroup_ops *ops,
const char *cgroup);
};

extern struct cgroup_ops *cgroup_ops;
Expand Down
50 changes: 42 additions & 8 deletions src/lxcfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,20 @@ static int do_proc_open(const char *path, struct fuse_file_info *fi)
return __proc_open(path, fi);
}

static int do_proc_opendir(const char *path, struct fuse_file_info *fi)
{
char *error;
int (*__proc_opendir)(const char *path, struct fuse_file_info *fi);

dlerror();
__proc_opendir = (int (*)(const char *path, struct fuse_file_info *fi))dlsym(dlopen_handle, "proc_opendir");
error = dlerror();
if (error)
return log_error(-1, "%s - Failed to find proc_opendir()", error);

return __proc_opendir(path, fi);
}

static int do_proc_access(const char *path, int mode)
{
char *error;
Expand Down Expand Up @@ -608,6 +622,20 @@ static int do_proc_release(const char *path, struct fuse_file_info *fi)
return __proc_release(path, fi);
}

static int do_proc_releasedir(const char *path, struct fuse_file_info *fi)
{
char *error;
int (*__proc_releasedir)(const char *path, struct fuse_file_info *fi);

dlerror();
__proc_releasedir = (int (*)(const char *path, struct fuse_file_info *)) dlsym(dlopen_handle, "proc_releasedir");
error = dlerror();
if (error)
return log_error(-1, "%s - Failed to find proc_releasedir()", error);

return __proc_releasedir(path, fi);
}

static int do_sys_release(const char *path, struct fuse_file_info *fi)
{
char *error;
Expand Down Expand Up @@ -724,8 +752,12 @@ static int lxcfs_opendir(const char *path, struct fuse_file_info *fi)
return ret;
}

if (strcmp(path, "/proc") == 0)
return 0;
if (strncmp(path, "/proc", 5) == 0) {
up_users();
ret = do_proc_opendir(path, fi);
down_users();
return ret;
}

if (strncmp(path, "/sys", 4) == 0) {
up_users();
Expand Down Expand Up @@ -768,7 +800,7 @@ static int lxcfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
return ret;
}

if (strcmp(path, "/proc") == 0) {
if (LXCFS_TYPE_PROC(type)) {
up_users();
ret = do_proc_readdir(path, buf, filler, offset, fi);
down_users();
Expand Down Expand Up @@ -837,12 +869,14 @@ static int lxcfs_releasedir(const char *path, struct fuse_file_info *fi)
return ret;
}

if (path) {
if (strcmp(path, "/") == 0)
return 0;
if (strcmp(path, "/proc") == 0)
return 0;
if (LXCFS_TYPE_PROC(type)) {
up_users();
ret = do_proc_releasedir(path, fi);
down_users();
return ret;
}
if (path && strcmp(path, "/") == 0)
return 0;

lxcfs_error("unknown file type: path=%s, type=%d, fi->fh=%" PRIu64,
path, type, fi->fh);
Expand Down
Loading

0 comments on commit 390f45f

Please sign in to comment.