summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Morton <akpm@digeo.com>2003-04-12 12:59:04 -0700
committerJames Bottomley <jejb@raven.il.steeleye.com>2003-04-12 12:59:04 -0700
commitffa5b8ebe5ebc9f23f8d81bd3fb2bbdcfddbe822 (patch)
tree5ced482392a68048d0a5cbcd462c27a141416461
parent873015a8c8de62f3c7ef5b3861d15b10ef7d438b (diff)
[PATCH] vmalloc stats in /proc/meminfo
From: Matt Porter <porter@cox.net> There was a thread a while back on lkml where Dave Hansen proposed this simple vmalloc usage reporting patch. The thread pretty much died out as most people seemed focused on what VM loading type bugs it could solve. I had posted that this type of information was really valuable in debugging embedded Linux board ports. A common example is where people do arch specific setup that limits there vmalloc space and then they find modules won't load. ;) Having the Vmalloc* info readily available is real useful in helping folks to fix their kernel ports.
-rw-r--r--fs/proc/proc_misc.c53
1 files changed, 51 insertions, 2 deletions
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 2d2f791eb598..60dd7b44e838 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -43,6 +43,7 @@
#include <linux/hugetlb.h>
#include <linux/jiffies.h>
#include <linux/sysrq.h>
+#include <linux/vmalloc.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/io.h>
@@ -98,6 +99,41 @@ static int loadavg_read_proc(char *page, char **start, off_t off,
return proc_calc_metrics(page, start, off, count, eof, len);
}
+struct vmalloc_info {
+ unsigned long used;
+ unsigned long largest_chunk;
+};
+
+static struct vmalloc_info get_vmalloc_info(void)
+{
+ unsigned long prev_end = VMALLOC_START;
+ struct vm_struct* vma;
+ struct vmalloc_info vmi;
+ vmi.used = 0;
+
+ read_lock(&vmlist_lock);
+
+ if(!vmlist)
+ vmi.largest_chunk = (VMALLOC_END-VMALLOC_START);
+ else
+ vmi.largest_chunk = 0;
+
+ for (vma = vmlist; vma; vma = vma->next) {
+ unsigned long free_area_size =
+ (unsigned long)vma->addr - prev_end;
+ vmi.used += vma->size;
+ if (vmi.largest_chunk < free_area_size )
+
+ vmi.largest_chunk = free_area_size;
+ prev_end = vma->size + (unsigned long)vma->addr;
+ }
+ if(VMALLOC_END-prev_end > vmi.largest_chunk)
+ vmi.largest_chunk = VMALLOC_END-prev_end;
+
+ read_unlock(&vmlist_lock);
+ return vmi;
+}
+
static int uptime_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
@@ -143,6 +179,8 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
unsigned long inactive;
unsigned long active;
unsigned long free;
+ unsigned long vmtot;
+ struct vmalloc_info vmi;
get_page_state(&ps);
get_zone_counts(&active, &inactive, &free);
@@ -155,6 +193,11 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
si_swapinfo(&i);
committed = atomic_read(&vm_committed_space);
+ vmtot = (VMALLOC_END-VMALLOC_START)>>10;
+ vmi = get_vmalloc_info();
+ vmi.used >>= 10;
+ vmi.largest_chunk >>= 10;
+
/*
* Tagged format, for easy grepping and expansion.
*/
@@ -177,7 +220,10 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
"Mapped: %8lu kB\n"
"Slab: %8lu kB\n"
"Committed_AS: %8u kB\n"
- "PageTables: %8lu kB\n",
+ "PageTables: %8lu kB\n"
+ "VmallocTotal: %8lu kB\n"
+ "VmallocUsed: %8lu kB\n"
+ "VmallocChunk: %8lu kB\n",
K(i.totalram),
K(i.freeram),
K(i.bufferram),
@@ -196,7 +242,10 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
K(ps.nr_mapped),
K(ps.nr_slab),
K(committed),
- K(ps.nr_page_table_pages)
+ K(ps.nr_page_table_pages),
+ vmtot,
+ vmi.used,
+ vmi.largest_chunk
);
len += hugetlb_report_meminfo(page + len);