Skip to content

Commit

Permalink
vmalloc: show vmalloced areas via /proc/vmallocinfo
Browse files Browse the repository at this point in the history
Implement a new proc file that allows the display of the currently allocated
vmalloc memory.

It allows to see the users of vmalloc.  That is important if vmalloc space is
scarce (i386 for example).

And it's going to be important for the compound page fallback to vmalloc.
Many of the current users can be switched to use compound pages with fallback.
 This means that the number of users of vmalloc is reduced and page tables no
longer necessary to access the memory.  /proc/vmallocinfo allows to review how
that reduction occurs.

If memory becomes fragmented and larger order allocations are no longer
possible then /proc/vmallocinfo allows to see which compound page allocations
fell back to virtual compound pages.  That is important for new users of
virtual compound pages.  Such as order 1 stack allocation etc that may
fallback to virtual compound pages in the future.

/proc/vmallocinfo permissions are made readable-only-by-root to avoid possible
information leakage.

[[email protected]: coding-style fixes]
[[email protected]: CONFIG_MMU=n build fix]
Signed-off-by: Christoph Lameter <[email protected]>
Reviewed-by: KOSAKI Motohiro <[email protected]>
Cc: Hugh Dickins <[email protected]>
Cc: Nick Piggin <[email protected]>
Cc: Arjan van de Ven <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Christoph Lameter authored and torvalds committed Apr 28, 2008
1 parent b454456 commit a10aa57
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 1 deletion.
17 changes: 17 additions & 0 deletions fs/proc/proc_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,20 @@ static const struct file_operations proc_slabstats_operations = {
#endif
#endif

#ifdef CONFIG_MMU
static int vmalloc_open(struct inode *inode, struct file *file)
{
return seq_open(file, &vmalloc_op);
}

static const struct file_operations proc_vmalloc_operations = {
.open = vmalloc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
#endif

static int show_stat(struct seq_file *p, void *v)
{
int i;
Expand Down Expand Up @@ -868,6 +882,9 @@ void __init proc_misc_init(void)
#ifdef CONFIG_DEBUG_SLAB_LEAK
create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations);
#endif
#endif
#ifdef CONFIG_MMU
proc_create("vmallocinfo", S_IRUSR, NULL, &proc_vmalloc_operations);
#endif
create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations);
create_seq_entry("pagetypeinfo", S_IRUGO, &pagetypeinfo_file_ops);
Expand Down
2 changes: 2 additions & 0 deletions include/linux/vmalloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,6 @@ extern void free_vm_area(struct vm_struct *area);
extern rwlock_t vmlist_lock;
extern struct vm_struct *vmlist;

extern const struct seq_operations vmalloc_op;

#endif /* _LINUX_VMALLOC_H */
76 changes: 75 additions & 1 deletion mm/vmalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>

#include <linux/seq_file.h>
#include <linux/vmalloc.h>

#include <asm/uaccess.h>
Expand Down Expand Up @@ -873,3 +873,77 @@ void free_vm_area(struct vm_struct *area)
kfree(area);
}
EXPORT_SYMBOL_GPL(free_vm_area);


#ifdef CONFIG_PROC_FS
static void *s_start(struct seq_file *m, loff_t *pos)
{
loff_t n = *pos;
struct vm_struct *v;

read_lock(&vmlist_lock);
v = vmlist;
while (n > 0 && v) {
n--;
v = v->next;
}
if (!n)
return v;

return NULL;

}

static void *s_next(struct seq_file *m, void *p, loff_t *pos)
{
struct vm_struct *v = p;

++*pos;
return v->next;
}

static void s_stop(struct seq_file *m, void *p)
{
read_unlock(&vmlist_lock);
}

static int s_show(struct seq_file *m, void *p)
{
struct vm_struct *v = p;

seq_printf(m, "0x%p-0x%p %7ld",
v->addr, v->addr + v->size, v->size);

if (v->nr_pages)
seq_printf(m, " pages=%d", v->nr_pages);

if (v->phys_addr)
seq_printf(m, " phys=%lx", v->phys_addr);

if (v->flags & VM_IOREMAP)
seq_printf(m, " ioremap");

if (v->flags & VM_ALLOC)
seq_printf(m, " vmalloc");

if (v->flags & VM_MAP)
seq_printf(m, " vmap");

if (v->flags & VM_USERMAP)
seq_printf(m, " user");

if (v->flags & VM_VPAGES)
seq_printf(m, " vpages");

seq_putc(m, '\n');
return 0;
}

const struct seq_operations vmalloc_op = {
.start = s_start,
.next = s_next,
.stop = s_stop,
.show = s_show,
};
#endif

0 comments on commit a10aa57

Please sign in to comment.