The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxcfs/pull/437
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com>
From 77b37202eb163069ee202c73ad32f4f2d4a340af Mon Sep 17 00:00:00 2001 From: Christian Brauner <christian.brau...@ubuntu.com> Date: Thu, 5 Nov 2020 19:19:41 +0100 Subject: [PATCH 1/2] cgfsng: align method implementations Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com> --- src/cgroups/cgfsng.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/cgroups/cgfsng.c b/src/cgroups/cgfsng.c index 824b0e7..2d09f88 100644 --- a/src/cgroups/cgfsng.c +++ b/src/cgroups/cgfsng.c @@ -992,33 +992,33 @@ struct cgroup_ops *cgfsng_ops_init(void) if (!cgfsng_ops) return ret_set_errno(NULL, ENOMEM); - cgfsng_ops->cgroup_layout = CGROUP_LAYOUT_UNKNOWN; - cgfsng_ops->mntns_fd = -EBADF; - cgfsng_ops->cgroup2_root_fd = -EBADF; + cgfsng_ops->cgroup_layout = CGROUP_LAYOUT_UNKNOWN; + cgfsng_ops->mntns_fd = -EBADF; + cgfsng_ops->cgroup2_root_fd = -EBADF; if (cg_init(cgfsng_ops)) return NULL; - cgfsng_ops->num_hierarchies = cgfsng_num_hierarchies; - cgfsng_ops->get = cgfsng_get; - cgfsng_ops->get_hierarchies = cgfsng_get_hierarchies; - cgfsng_ops->get_hierarchy = cgfsng_get_hierarchy; - cgfsng_ops->driver = "cgfsng"; - cgfsng_ops->version = "1.0.0"; - cgfsng_ops->mount = cgfsng_mount; + cgfsng_ops->num_hierarchies = cgfsng_num_hierarchies; + cgfsng_ops->get = cgfsng_get; + cgfsng_ops->get_hierarchies = cgfsng_get_hierarchies; + cgfsng_ops->get_hierarchy = cgfsng_get_hierarchy; + cgfsng_ops->driver = "cgfsng"; + cgfsng_ops->version = "1.0.0"; + cgfsng_ops->mount = cgfsng_mount; /* memory */ - cgfsng_ops->get_memory_stats_fd = cgfsng_get_memory_stats_fd; - cgfsng_ops->get_memory_stats = cgfsng_get_memory_stats; - cgfsng_ops->get_memory_max = cgfsng_get_memory_max; - cgfsng_ops->get_memory_swap_max = cgfsng_get_memory_swap_max; - cgfsng_ops->get_memory_current = cgfsng_get_memory_current; - cgfsng_ops->get_memory_swap_current = cgfsng_get_memory_swap_current; - cgfsng_ops->can_use_swap = cgfsng_can_use_swap; + cgfsng_ops->get_memory_stats_fd = cgfsng_get_memory_stats_fd; + cgfsng_ops->get_memory_stats = cgfsng_get_memory_stats; + cgfsng_ops->get_memory_max = cgfsng_get_memory_max; + cgfsng_ops->get_memory_swap_max = cgfsng_get_memory_swap_max; + cgfsng_ops->get_memory_current = cgfsng_get_memory_current; + cgfsng_ops->get_memory_swap_current = cgfsng_get_memory_swap_current; + cgfsng_ops->can_use_swap = cgfsng_can_use_swap; /* cpuset */ - cgfsng_ops->get_cpuset_cpus = cgfsng_get_cpuset_cpus; - cgfsng_ops->can_use_cpuview = cgfsng_can_use_cpuview; + cgfsng_ops->get_cpuset_cpus = cgfsng_get_cpuset_cpus; + cgfsng_ops->can_use_cpuview = cgfsng_can_use_cpuview; /* blkio */ cgfsng_ops->get_io_service_bytes = cgfsng_get_io_service_bytes; From 3b9c3c53ee34b908636b534f3eb2807d817f4765 Mon Sep 17 00:00:00 2001 From: Christian Brauner <christian.brau...@ubuntu.com> Date: Thu, 5 Nov 2020 20:21:00 +0100 Subject: [PATCH 2/2] meminfo: align swap implementation with docs Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com> --- src/cgroups/cgfsng.c | 7 +++++++ src/cgroups/cgroup.h | 2 ++ src/proc_fuse.c | 45 ++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/cgroups/cgfsng.c b/src/cgroups/cgfsng.c index 2d09f88..b369ed2 100644 --- a/src/cgroups/cgfsng.c +++ b/src/cgroups/cgfsng.c @@ -602,6 +602,12 @@ static int cgfsng_get_memory_stats_fd(struct cgroup_ops *ops, const char *cgroup return openat(h->fd, path, O_RDONLY | O_CLOEXEC | O_NOFOLLOW); } +static int cgfsng_get_memory_swappiness(struct cgroup_ops *ops, + const char *cgroup, char **value) +{ + return cgfsng_get_memory(ops, cgroup, "memory.swappiness", value); +} + static int cgfsng_get_memory_current(struct cgroup_ops *ops, const char *cgroup, char **value) { @@ -1014,6 +1020,7 @@ struct cgroup_ops *cgfsng_ops_init(void) cgfsng_ops->get_memory_swap_max = cgfsng_get_memory_swap_max; cgfsng_ops->get_memory_current = cgfsng_get_memory_current; cgfsng_ops->get_memory_swap_current = cgfsng_get_memory_swap_current; + cgfsng_ops->get_memory_swappiness = cgfsng_get_memory_swappiness; cgfsng_ops->can_use_swap = cgfsng_can_use_swap; /* cpuset */ diff --git a/src/cgroups/cgroup.h b/src/cgroups/cgroup.h index ad4a3ae..ba29b97 100644 --- a/src/cgroups/cgroup.h +++ b/src/cgroups/cgroup.h @@ -153,6 +153,8 @@ struct cgroup_ops { char **value); int (*get_memory_swap_max)(struct cgroup_ops *ops, const char *cgroup, char **value); + int (*get_memory_swappiness)(struct cgroup_ops *ops, const char *cgroup, + char **value); bool (*can_use_swap)(struct cgroup_ops *ops); /* cpuset */ diff --git a/src/proc_fuse.c b/src/proc_fuse.c index 7bc1eb0..0d24b9e 100644 --- a/src/proc_fuse.c +++ b/src/proc_fuse.c @@ -310,6 +310,15 @@ static uint64_t get_min_memlimit(const char *cgroup, bool swap) return retlimit; } +static bool swappiness_is_off(const char *cgroup) +{ + __do_free char *swappiness_str = NULL; + int ret; + + ret = cgroup_ops->get_memory_swappiness(cgroup_ops, cgroup, &swappiness_str); + return (ret > 0) && swappiness_str && (*swappiness_str == '0'); +} + static inline bool startswith(const char *line, const char *pref) { return strncmp(line, pref, strlen(pref)) == 0; @@ -1141,7 +1150,8 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset, __do_fclose FILE *f = NULL; struct fuse_context *fc = fuse_get_context(); struct lxcfs_opts *opts = (struct lxcfs_opts *)fuse_get_context()->private_data; - bool wants_swap = opts && !opts->swap_off && liblxcfs_can_use_swap(), host_swap = false; + bool wants_swap = opts && !opts->swap_off && liblxcfs_can_use_swap(), host_swap = false, + swappiness_off = false; struct file_info *d = INTTYPE_TO_PTR(fi->fh); uint64_t memlimit = 0, memusage = 0, memswlimit = 0, memswusage = 0, hosttotal = 0, swfree = 0, swusage = 0, swtotal = 0; @@ -1195,6 +1205,7 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset, * turned off for current kernel. */ if (wants_swap) { + swappiness_off = swappiness_is_off(cgroup); memswlimit = get_min_memlimit(cgroup, true); if (memswlimit > 0) { ret = cgroup_ops->get_memory_swap_current(cgroup_ops, cgroup, &memswusage_str); @@ -1209,6 +1220,36 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset, swusage = (memswusage - memusage) / 1024; } } + + /* + * If the swappiness is set to 0 and there is no SWAP usage, no + * SWAP is reported. However if there is SWAP usage, then a + * SWAP device of the size of the usage (100% full) is + * reported. This provides adequate reporting of the memory + * consumption while preventing applications from assuming more + * SWAP is available. + */ + if (swappiness_off) { + if (swusage == 0) { + wants_swap = false; + } else { + swtotal = swusage; + swfree = 0; + } + } + + /* + * Because SWAP usage for a given container can exceed the + * delta between RAM and RAM+SWAP, the SWAP size is always + * reported to be the smaller of the RAM+SWAP limit or the host + * SWAP device itself. This ensures that at no point SWAP usage + * will be allowed to exceed the SWAP size. + */ + if (wants_swap && (swtotal > memlimit)) { + swtotal = memlimit; + swusage = memlimit; + swfree = 0; + } } f = fopen_cached("/proc/meminfo", "re", &fopen_cache); @@ -1253,7 +1294,7 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset, * anyway.) so fallback to the host's values in * that case too. */ - if ((hostswtotal < swtotal) || swtotal == 0) { + if ((hostswtotal < swtotal)) { swtotal = hostswtotal; host_swap = true; }
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel