|
@@ -26,7 +26,11 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
|
|
|
unsigned long committed;
|
|
|
struct vmalloc_info vmi;
|
|
|
long cached;
|
|
|
+ long available;
|
|
|
+ unsigned long pagecache;
|
|
|
+ unsigned long wmark_low = 0;
|
|
|
unsigned long pages[NR_LRU_LISTS];
|
|
|
+ struct zone *zone;
|
|
|
int lru;
|
|
|
|
|
|
/*
|
|
@@ -47,12 +51,44 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
|
|
|
for (lru = LRU_BASE; lru < NR_LRU_LISTS; lru++)
|
|
|
pages[lru] = global_page_state(NR_LRU_BASE + lru);
|
|
|
|
|
|
+ for_each_zone(zone)
|
|
|
+ wmark_low += zone->watermark[WMARK_LOW];
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Estimate the amount of memory available for userspace allocations,
|
|
|
+ * without causing swapping.
|
|
|
+ *
|
|
|
+ * Free memory cannot be taken below the low watermark, before the
|
|
|
+ * system starts swapping.
|
|
|
+ */
|
|
|
+ available = i.freeram - wmark_low;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Not all the page cache can be freed, otherwise the system will
|
|
|
+ * start swapping. Assume at least half of the page cache, or the
|
|
|
+ * low watermark worth of cache, needs to stay.
|
|
|
+ */
|
|
|
+ pagecache = pages[LRU_ACTIVE_FILE] + pages[LRU_INACTIVE_FILE];
|
|
|
+ pagecache -= min(pagecache / 2, wmark_low);
|
|
|
+ available += pagecache;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Part of the reclaimable swap consists of items that are in use,
|
|
|
+ * and cannot be freed. Cap this estimate at the low watermark.
|
|
|
+ */
|
|
|
+ available += global_page_state(NR_SLAB_RECLAIMABLE) -
|
|
|
+ min(global_page_state(NR_SLAB_RECLAIMABLE) / 2, wmark_low);
|
|
|
+
|
|
|
+ if (available < 0)
|
|
|
+ available = 0;
|
|
|
+
|
|
|
/*
|
|
|
* Tagged format, for easy grepping and expansion.
|
|
|
*/
|
|
|
seq_printf(m,
|
|
|
"MemTotal: %8lu kB\n"
|
|
|
"MemFree: %8lu kB\n"
|
|
|
+ "MemAvailable: %8lu kB\n"
|
|
|
"Buffers: %8lu kB\n"
|
|
|
"Cached: %8lu kB\n"
|
|
|
"SwapCached: %8lu kB\n"
|
|
@@ -105,6 +141,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
|
|
|
,
|
|
|
K(i.totalram),
|
|
|
K(i.freeram),
|
|
|
+ K(available),
|
|
|
K(i.bufferram),
|
|
|
K(cached),
|
|
|
K(total_swapcache_pages()),
|