library: properly handle memory used by tmpfs

tmpfs has become much more widely used since distributions use it for
/tmp (Fedora 18+). In /proc/meminfo, memory used by tmpfs is accounted
into "Cached" (aka "NR_FILE_PAGES",
 http://lxr.free-electrons.com/source/mm/shmem.c#L301 ).

The tools just pass it on, so what top, free and vmstat report as
"cached" is the sum of page cache and tmpfs.

free has the extremely useful "-/+ buffers/cache" output. However, now
that tmpfs is accounted into "cached", those numbers are way off once
you have big files in /tmp.

Fortunately, kernel 2.6.32 introduces "Shmem", which makes tmpfs memory
usage accessible from userspace (
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=4b02108ac1b3354a22b0d83c684797692efdc395 ).

This patch substracts Shmem from Cached to get the actual page cache
memory. This makes both issues mentioned above disappear. For older
kernels, Shmem is not available (hence zero) and this patch is no-op.

Additionally:
* Update the man pages of free and vmstat to explain what is happening
* Finally drop "MemShared" from the /proc/meminfo parser, it has been
  dead for 10+ years and is only causing confusion ( removed in kernel
  2.5.54, see
  https://git.kernel.org/cgit/linux/kernel/git/tglx/history.git/commit/?id=fe04e9451e5a159247cf9f03c615a4273ac0c571 )
This commit is contained in:
Jakob Unterwurzacher
2014-02-18 22:12:21 +01:00
committed by Jaromir Capik
parent 24f1fbd9d0
commit 3569c0351f
4 changed files with 31 additions and 12 deletions

View File

@ -531,7 +531,6 @@ static int compare_mem_table_structs(const void *a, const void *b){
*
* MemTotal: 61768 kB old
* MemFree: 1436 kB old
* MemShared: 0 kB old (now always zero; not calculated)
* Buffers: 1312 kB old
* Cached: 20932 kB old
* Active: 12464 kB new
@ -560,7 +559,7 @@ static int compare_mem_table_structs(const void *a, const void *b){
* Hugepagesize: 4096 kB 2.5.??+
*/
/* obsolete since 2.6.x, but reused for shmem in 2.6.32+ */
/* Shmem in 2.6.32+ */
unsigned long kb_main_shared;
/* old but still kicking -- the important stuff */
unsigned long kb_main_buffers;
@ -631,14 +630,13 @@ void meminfo(void){
{"LowTotal", &kb_low_total},
{"Mapped", &kb_mapped}, // kB version of vmstat nr_mapped
{"MemFree", &kb_main_free}, // important
{"MemShared", &kb_main_shared}, // obsolete since kernel 2.6! (sharing the variable with Shmem replacement)
{"MemTotal", &kb_main_total}, // important
{"NFS_Unstable", &kb_nfs_unstable},
{"PageTables", &kb_pagetables}, // kB version of vmstat nr_page_table_pages
{"ReverseMaps", &nr_reversemaps}, // same as vmstat nr_page_table_pages
{"SReclaimable", &kb_swap_reclaimable}, // "swap reclaimable" (dentry and inode structures)
{"SUnreclaim", &kb_swap_unreclaimable},
{"Shmem", &kb_main_shared}, // kernel 2.6 and later (sharing the output variable with obsolete MemShared)
{"Shmem", &kb_main_shared}, // kernel 2.6.32 and later
{"Slab", &kb_slab}, // kB version of vmstat nr_slab
{"SwapCached", &kb_swap_cached},
{"SwapFree", &kb_swap_free}, // important
@ -684,6 +682,8 @@ nextline:
}
kb_swap_used = kb_swap_total - kb_swap_free;
kb_main_used = kb_main_total - kb_main_free;
/* "Cached" includes "Shmem" - we want only the page cache here */
kb_main_cached -= kb_main_shared;
}
/*****************************************************************/

View File

@ -20,8 +20,7 @@ extern int uptime (double *uptime_secs, double *idle_secs);
extern unsigned long getbtime(void);
extern void loadavg(double *av1, double *av5, double *av15);
/* obsolete */
/* Shmem in 2.6.32+ */
extern unsigned long kb_main_shared;
/* old but still kicking -- the important stuff */
extern unsigned long kb_main_buffers;