]> git.proxmox.com Git - lxcfs.git/commitdiff
fix #1655: merge stable upstream patches for /proc/meminfo
authorWolfgang Bumiller <w.bumiller@proxmox.com>
Wed, 7 Feb 2018 12:00:54 +0000 (13:00 +0100)
committerWolfgang Bumiller <w.bumiller@proxmox.com>
Wed, 7 Feb 2018 12:11:17 +0000 (13:11 +0100)
* Fix inaccurate values in /proc/meminfo for containers with child cgroups
* Change MemAvailable figure in /proc/meminfo to include cache memory

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
debian/patches/0001-Fix-inaccurate-values-in-proc-meminfo-for-containers.patch [new file with mode: 0644]
debian/patches/0002-Change-MemAvailable-figure-in-proc-meminfo-to-includ.patch [new file with mode: 0644]
debian/patches/0003-bindings-remove-unused-function.patch [new file with mode: 0644]
debian/patches/series

diff --git a/debian/patches/0001-Fix-inaccurate-values-in-proc-meminfo-for-containers.patch b/debian/patches/0001-Fix-inaccurate-values-in-proc-meminfo-for-containers.patch
new file mode 100644 (file)
index 0000000..c79f2e0
--- /dev/null
@@ -0,0 +1,72 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Aaron Sokoloski <asokoloski@gmail.com>
+Date: Sat, 2 Dec 2017 12:43:06 -0600
+Subject: [PATCH lxcfs] Fix inaccurate values in /proc/meminfo for containers
+ with child cgroups
+
+The values for Cached, Active, Inactive, Active(anon), Inactive(anon),
+Active(file), Inactive(file), and Unevictable are derived/computed
+from these values in the relevant meminfo.stat:
+
+cache
+active_anon
+inactive_anon
+active_file
+inactive_file
+unevictable
+
+However, these value apply only to the cgroup of the lxc container
+itself.  If your container uses memory cgroups internally, and thus
+the container cgroup has children, their memory is not counted.
+
+In order to take the memory usage of child cgroups into account, we
+need to look at the "total_" prefixed versions of these values.
+
+Signed-off-by: Aaron Sokoloski <asokoloski@gmail.com>
+---
+ bindings.c | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/bindings.c b/bindings.c
+index d7c2d1d..fc62089 100644
+--- a/bindings.c
++++ b/bindings.c
+@@ -2959,23 +2959,23 @@ static void parse_memstat(char *memstat, unsigned long *cached,
+       char *eol;
+       while (*memstat) {
+-              if (startswith(memstat, "cache")) {
+-                      sscanf(memstat + 5, "%lu", cached);
++              if (startswith(memstat, "total_cache")) {
++                      sscanf(memstat + 11, "%lu", cached);
+                       *cached /= 1024;
+-              } else if (startswith(memstat, "active_anon")) {
+-                      sscanf(memstat + 11, "%lu", active_anon);
++              } else if (startswith(memstat, "total_active_anon")) {
++                      sscanf(memstat + 17, "%lu", active_anon);
+                       *active_anon /= 1024;
+-              } else if (startswith(memstat, "inactive_anon")) {
+-                      sscanf(memstat + 13, "%lu", inactive_anon);
++              } else if (startswith(memstat, "total_inactive_anon")) {
++                      sscanf(memstat + 19, "%lu", inactive_anon);
+                       *inactive_anon /= 1024;
+-              } else if (startswith(memstat, "active_file")) {
+-                      sscanf(memstat + 11, "%lu", active_file);
++              } else if (startswith(memstat, "total_active_file")) {
++                      sscanf(memstat + 17, "%lu", active_file);
+                       *active_file /= 1024;
+-              } else if (startswith(memstat, "inactive_file")) {
+-                      sscanf(memstat + 13, "%lu", inactive_file);
++              } else if (startswith(memstat, "total_inactive_file")) {
++                      sscanf(memstat + 19, "%lu", inactive_file);
+                       *inactive_file /= 1024;
+-              } else if (startswith(memstat, "unevictable")) {
+-                      sscanf(memstat + 11, "%lu", unevictable);
++              } else if (startswith(memstat, "total_unevictable")) {
++                      sscanf(memstat + 17, "%lu", unevictable);
+                       *unevictable /= 1024;
+               }
+               eol = strchr(memstat, '\n');
+-- 
+2.11.0
+
diff --git a/debian/patches/0002-Change-MemAvailable-figure-in-proc-meminfo-to-includ.patch b/debian/patches/0002-Change-MemAvailable-figure-in-proc-meminfo-to-includ.patch
new file mode 100644 (file)
index 0000000..c3a6911
--- /dev/null
@@ -0,0 +1,57 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Aaron Sokoloski <asokoloski@gmail.com>
+Date: Mon, 4 Dec 2017 12:30:37 -0600
+Subject: [PATCH lxcfs] Change MemAvailable figure in /proc/meminfo to include
+ cache memory -- Fixes #175 I think.
+
+MemAvailable represents roughly how much more memory we can use before
+we start swapping.  Page cache memory can be reclaimed if it's needed
+for something else, so it should count as available memory.  This
+change should also fix the "available" column of the "free" command,
+as well as the "avail Mem" value in "top", both of which come from
+MemAvailable.
+
+Note that this isn't perfectly accurate.  On a physical machine, the
+value for MemAvailable is the result of a calculation that takes into
+account that when memory gets low (but before it's completely
+exhausted), kswapd wakes up and starts paging things out.  See:
+
+https://github.com/torvalds/linux/blob/a0908a1b7d68706ee52ed4a039756e70c8e956e9/mm/page_alloc.c#L4553
+(si_mem_available function)
+
+I tried to think of a way to be more exact, but this calculation
+includes figures that we don't have available for a given cgroup
+hierarchy, such as reclaimable slab memory and the low watermark for
+zones.  So it's not really feasible to reproduce it exactly.
+
+Anyway, since the kernel calculation itself is just an estimation, it
+doesn't seem too bad that we're a little bit off.  Adding in the
+amount of memory used for page cache seems much better than what we
+were doing before (just copying the free memory figure), because that
+can be wrong by gigabytes.
+
+For a more detailed understanding of how MemAvailable comes about one
+should look at 34e431b0ae398fc54ea69ff85ec700722c9da773 in the Linux
+kernel tree.
+
+Signed-off-by: Aaron Sokoloski <asokoloski@gmail.com>
+---
+ bindings.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/bindings.c b/bindings.c
+index fc62089..cfd386e 100644
+--- a/bindings.c
++++ b/bindings.c
+@@ -3165,7 +3165,7 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
+                       snprintf(lbuf, 100, "MemFree:        %8lu kB\n", memlimit - memusage);
+                       printme = lbuf;
+               } else if (startswith(line, "MemAvailable:")) {
+-                      snprintf(lbuf, 100, "MemAvailable:   %8lu kB\n", memlimit - memusage);
++                      snprintf(lbuf, 100, "MemAvailable:   %8lu kB\n", memlimit - memusage + cached);
+                       printme = lbuf;
+               } else if (startswith(line, "SwapTotal:") && memswlimit > 0) {
+                       sscanf(line+sizeof("SwapTotal:")-1, "%lu", &hostswtotal);
+-- 
+2.11.0
+
diff --git a/debian/patches/0003-bindings-remove-unused-function.patch b/debian/patches/0003-bindings-remove-unused-function.patch
new file mode 100644 (file)
index 0000000..4144af9
--- /dev/null
@@ -0,0 +1,42 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Christian Brauner <christian.brauner@ubuntu.com>
+Date: Thu, 2 Nov 2017 13:30:03 +0100
+Subject: [PATCH lxcfs] bindings: remove unused function
+
+Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
+---
+ bindings.c | 18 ------------------
+ 1 file changed, 18 deletions(-)
+
+diff --git a/bindings.c b/bindings.c
+index cfd386e..cbf05fe 100644
+--- a/bindings.c
++++ b/bindings.c
+@@ -3591,24 +3591,6 @@ static uint64_t get_reaper_age(pid_t pid)
+       return procage;
+ }
+-static uint64_t get_reaper_btime(pid)
+-{
+-      int ret;
+-      struct sysinfo sys;
+-      uint64_t procstart;
+-      uint64_t uptime;
+-
+-      ret = sysinfo(&sys);
+-      if (ret < 0) {
+-              lxcfs_debug("%s\n", "failed to retrieve system information");
+-              return 0;
+-      }
+-
+-      uptime = (uint64_t)time(NULL) - (uint64_t)sys.uptime;
+-      procstart = get_reaper_start_time_in_sec(pid);
+-      return uptime + procstart;
+-}
+-
+ #define CPUALL_MAX_SIZE (BUF_RESERVE_SIZE / 2)
+ static int proc_stat_read(char *buf, size_t size, off_t offset,
+               struct fuse_file_info *fi)
+-- 
+2.11.0
+
index bf650b42b1037ca3c7f99c19421c9e1728402554..78bd877936732290746fc14fa77b63b1415a1c19 100644 (file)
@@ -1 +1,4 @@
 do-not-start-without-lxcfs.patch
+0001-Fix-inaccurate-values-in-proc-meminfo-for-containers.patch
+0002-Change-MemAvailable-figure-in-proc-meminfo-to-includ.patch
+0003-bindings-remove-unused-function.patch