Merge branch 'slab/procfs' into slab/for-linus
This commit is contained in:
Коммит
a304f836a2
118
mm/slab.c
118
mm/slab.c
|
@ -4276,54 +4276,8 @@ out:
|
|||
}
|
||||
|
||||
#ifdef CONFIG_SLABINFO
|
||||
|
||||
static void print_slabinfo_header(struct seq_file *m)
|
||||
void get_slabinfo(struct kmem_cache *cachep, struct slabinfo *sinfo)
|
||||
{
|
||||
/*
|
||||
* Output format version, so at least we can change it
|
||||
* without _too_ many complaints.
|
||||
*/
|
||||
#if STATS
|
||||
seq_puts(m, "slabinfo - version: 2.1 (statistics)\n");
|
||||
#else
|
||||
seq_puts(m, "slabinfo - version: 2.1\n");
|
||||
#endif
|
||||
seq_puts(m, "# name <active_objs> <num_objs> <objsize> "
|
||||
"<objperslab> <pagesperslab>");
|
||||
seq_puts(m, " : tunables <limit> <batchcount> <sharedfactor>");
|
||||
seq_puts(m, " : slabdata <active_slabs> <num_slabs> <sharedavail>");
|
||||
#if STATS
|
||||
seq_puts(m, " : globalstat <listallocs> <maxobjs> <grown> <reaped> "
|
||||
"<error> <maxfreeable> <nodeallocs> <remotefrees> <alienoverflow>");
|
||||
seq_puts(m, " : cpustat <allochit> <allocmiss> <freehit> <freemiss>");
|
||||
#endif
|
||||
seq_putc(m, '\n');
|
||||
}
|
||||
|
||||
static void *s_start(struct seq_file *m, loff_t *pos)
|
||||
{
|
||||
loff_t n = *pos;
|
||||
|
||||
mutex_lock(&slab_mutex);
|
||||
if (!n)
|
||||
print_slabinfo_header(m);
|
||||
|
||||
return seq_list_start(&slab_caches, *pos);
|
||||
}
|
||||
|
||||
static void *s_next(struct seq_file *m, void *p, loff_t *pos)
|
||||
{
|
||||
return seq_list_next(p, &slab_caches, pos);
|
||||
}
|
||||
|
||||
static void s_stop(struct seq_file *m, void *p)
|
||||
{
|
||||
mutex_unlock(&slab_mutex);
|
||||
}
|
||||
|
||||
static int s_show(struct seq_file *m, void *p)
|
||||
{
|
||||
struct kmem_cache *cachep = list_entry(p, struct kmem_cache, list);
|
||||
struct slab *slabp;
|
||||
unsigned long active_objs;
|
||||
unsigned long num_objs;
|
||||
|
@ -4378,13 +4332,20 @@ static int s_show(struct seq_file *m, void *p)
|
|||
if (error)
|
||||
printk(KERN_ERR "slab: cache %s error: %s\n", name, error);
|
||||
|
||||
seq_printf(m, "%-17s %6lu %6lu %6u %4u %4d",
|
||||
name, active_objs, num_objs, cachep->size,
|
||||
cachep->num, (1 << cachep->gfporder));
|
||||
seq_printf(m, " : tunables %4u %4u %4u",
|
||||
cachep->limit, cachep->batchcount, cachep->shared);
|
||||
seq_printf(m, " : slabdata %6lu %6lu %6lu",
|
||||
active_slabs, num_slabs, shared_avail);
|
||||
sinfo->active_objs = active_objs;
|
||||
sinfo->num_objs = num_objs;
|
||||
sinfo->active_slabs = active_slabs;
|
||||
sinfo->num_slabs = num_slabs;
|
||||
sinfo->shared_avail = shared_avail;
|
||||
sinfo->limit = cachep->limit;
|
||||
sinfo->batchcount = cachep->batchcount;
|
||||
sinfo->shared = cachep->shared;
|
||||
sinfo->objects_per_slab = cachep->num;
|
||||
sinfo->cache_order = cachep->gfporder;
|
||||
}
|
||||
|
||||
void slabinfo_show_stats(struct seq_file *m, struct kmem_cache *cachep)
|
||||
{
|
||||
#if STATS
|
||||
{ /* list3 stats */
|
||||
unsigned long high = cachep->high_mark;
|
||||
|
@ -4414,31 +4375,8 @@ static int s_show(struct seq_file *m, void *p)
|
|||
allochit, allocmiss, freehit, freemiss);
|
||||
}
|
||||
#endif
|
||||
seq_putc(m, '\n');
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* slabinfo_op - iterator that generates /proc/slabinfo
|
||||
*
|
||||
* Output layout:
|
||||
* cache-name
|
||||
* num-active-objs
|
||||
* total-objs
|
||||
* object size
|
||||
* num-active-slabs
|
||||
* total-slabs
|
||||
* num-pages-per-slab
|
||||
* + further values on SMP and with statistics enabled
|
||||
*/
|
||||
|
||||
static const struct seq_operations slabinfo_op = {
|
||||
.start = s_start,
|
||||
.next = s_next,
|
||||
.stop = s_stop,
|
||||
.show = s_show,
|
||||
};
|
||||
|
||||
#define MAX_SLABINFO_WRITE 128
|
||||
/**
|
||||
* slabinfo_write - Tuning for the slab allocator
|
||||
|
@ -4447,7 +4385,7 @@ static const struct seq_operations slabinfo_op = {
|
|||
* @count: data length
|
||||
* @ppos: unused
|
||||
*/
|
||||
static ssize_t slabinfo_write(struct file *file, const char __user *buffer,
|
||||
ssize_t slabinfo_write(struct file *file, const char __user *buffer,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
char kbuf[MAX_SLABINFO_WRITE + 1], *tmp;
|
||||
|
@ -4490,19 +4428,6 @@ static ssize_t slabinfo_write(struct file *file, const char __user *buffer,
|
|||
return res;
|
||||
}
|
||||
|
||||
static int slabinfo_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return seq_open(file, &slabinfo_op);
|
||||
}
|
||||
|
||||
static const struct file_operations proc_slabinfo_operations = {
|
||||
.open = slabinfo_open,
|
||||
.read = seq_read,
|
||||
.write = slabinfo_write,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DEBUG_SLAB_LEAK
|
||||
|
||||
static void *leaks_start(struct seq_file *m, loff_t *pos)
|
||||
|
@ -4631,6 +4556,16 @@ static int leaks_show(struct seq_file *m, void *p)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void *s_next(struct seq_file *m, void *p, loff_t *pos)
|
||||
{
|
||||
return seq_list_next(p, &slab_caches, pos);
|
||||
}
|
||||
|
||||
static void s_stop(struct seq_file *m, void *p)
|
||||
{
|
||||
mutex_unlock(&slab_mutex);
|
||||
}
|
||||
|
||||
static const struct seq_operations slabstats_op = {
|
||||
.start = leaks_start,
|
||||
.next = s_next,
|
||||
|
@ -4665,7 +4600,6 @@ static const struct file_operations proc_slabstats_operations = {
|
|||
|
||||
static int __init slab_proc_init(void)
|
||||
{
|
||||
proc_create("slabinfo",S_IWUSR|S_IRUSR,NULL,&proc_slabinfo_operations);
|
||||
#ifdef CONFIG_DEBUG_SLAB_LEAK
|
||||
proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations);
|
||||
#endif
|
||||
|
|
20
mm/slab.h
20
mm/slab.h
|
@ -47,4 +47,24 @@ static inline struct kmem_cache *__kmem_cache_alias(const char *name, size_t siz
|
|||
|
||||
int __kmem_cache_shutdown(struct kmem_cache *);
|
||||
|
||||
struct seq_file;
|
||||
struct file;
|
||||
|
||||
struct slabinfo {
|
||||
unsigned long active_objs;
|
||||
unsigned long num_objs;
|
||||
unsigned long active_slabs;
|
||||
unsigned long num_slabs;
|
||||
unsigned long shared_avail;
|
||||
unsigned int limit;
|
||||
unsigned int batchcount;
|
||||
unsigned int shared;
|
||||
unsigned int objects_per_slab;
|
||||
unsigned int cache_order;
|
||||
};
|
||||
|
||||
void get_slabinfo(struct kmem_cache *s, struct slabinfo *sinfo);
|
||||
void slabinfo_show_stats(struct seq_file *m, struct kmem_cache *s);
|
||||
ssize_t slabinfo_write(struct file *file, const char __user *buffer,
|
||||
size_t count, loff_t *ppos);
|
||||
#endif
|
||||
|
|
109
mm/slab_common.c
109
mm/slab_common.c
|
@ -13,6 +13,8 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/page.h>
|
||||
|
@ -192,3 +194,110 @@ int slab_is_available(void)
|
|||
{
|
||||
return slab_state >= UP;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SLABINFO
|
||||
static void print_slabinfo_header(struct seq_file *m)
|
||||
{
|
||||
/*
|
||||
* Output format version, so at least we can change it
|
||||
* without _too_ many complaints.
|
||||
*/
|
||||
#ifdef CONFIG_DEBUG_SLAB
|
||||
seq_puts(m, "slabinfo - version: 2.1 (statistics)\n");
|
||||
#else
|
||||
seq_puts(m, "slabinfo - version: 2.1\n");
|
||||
#endif
|
||||
seq_puts(m, "# name <active_objs> <num_objs> <objsize> "
|
||||
"<objperslab> <pagesperslab>");
|
||||
seq_puts(m, " : tunables <limit> <batchcount> <sharedfactor>");
|
||||
seq_puts(m, " : slabdata <active_slabs> <num_slabs> <sharedavail>");
|
||||
#ifdef CONFIG_DEBUG_SLAB
|
||||
seq_puts(m, " : globalstat <listallocs> <maxobjs> <grown> <reaped> "
|
||||
"<error> <maxfreeable> <nodeallocs> <remotefrees> <alienoverflow>");
|
||||
seq_puts(m, " : cpustat <allochit> <allocmiss> <freehit> <freemiss>");
|
||||
#endif
|
||||
seq_putc(m, '\n');
|
||||
}
|
||||
|
||||
static void *s_start(struct seq_file *m, loff_t *pos)
|
||||
{
|
||||
loff_t n = *pos;
|
||||
|
||||
mutex_lock(&slab_mutex);
|
||||
if (!n)
|
||||
print_slabinfo_header(m);
|
||||
|
||||
return seq_list_start(&slab_caches, *pos);
|
||||
}
|
||||
|
||||
static void *s_next(struct seq_file *m, void *p, loff_t *pos)
|
||||
{
|
||||
return seq_list_next(p, &slab_caches, pos);
|
||||
}
|
||||
|
||||
static void s_stop(struct seq_file *m, void *p)
|
||||
{
|
||||
mutex_unlock(&slab_mutex);
|
||||
}
|
||||
|
||||
static int s_show(struct seq_file *m, void *p)
|
||||
{
|
||||
struct kmem_cache *s = list_entry(p, struct kmem_cache, list);
|
||||
struct slabinfo sinfo;
|
||||
|
||||
memset(&sinfo, 0, sizeof(sinfo));
|
||||
get_slabinfo(s, &sinfo);
|
||||
|
||||
seq_printf(m, "%-17s %6lu %6lu %6u %4u %4d",
|
||||
s->name, sinfo.active_objs, sinfo.num_objs, s->size,
|
||||
sinfo.objects_per_slab, (1 << sinfo.cache_order));
|
||||
|
||||
seq_printf(m, " : tunables %4u %4u %4u",
|
||||
sinfo.limit, sinfo.batchcount, sinfo.shared);
|
||||
seq_printf(m, " : slabdata %6lu %6lu %6lu",
|
||||
sinfo.active_slabs, sinfo.num_slabs, sinfo.shared_avail);
|
||||
slabinfo_show_stats(m, s);
|
||||
seq_putc(m, '\n');
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* slabinfo_op - iterator that generates /proc/slabinfo
|
||||
*
|
||||
* Output layout:
|
||||
* cache-name
|
||||
* num-active-objs
|
||||
* total-objs
|
||||
* object size
|
||||
* num-active-slabs
|
||||
* total-slabs
|
||||
* num-pages-per-slab
|
||||
* + further values on SMP and with statistics enabled
|
||||
*/
|
||||
static const struct seq_operations slabinfo_op = {
|
||||
.start = s_start,
|
||||
.next = s_next,
|
||||
.stop = s_stop,
|
||||
.show = s_show,
|
||||
};
|
||||
|
||||
static int slabinfo_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return seq_open(file, &slabinfo_op);
|
||||
}
|
||||
|
||||
static const struct file_operations proc_slabinfo_operations = {
|
||||
.open = slabinfo_open,
|
||||
.read = seq_read,
|
||||
.write = slabinfo_write,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
static int __init slab_proc_init(void)
|
||||
{
|
||||
proc_create("slabinfo", S_IRUSR, NULL, &proc_slabinfo_operations);
|
||||
return 0;
|
||||
}
|
||||
module_init(slab_proc_init);
|
||||
#endif /* CONFIG_SLABINFO */
|
||||
|
|
77
mm/slub.c
77
mm/slub.c
|
@ -5405,49 +5405,14 @@ __initcall(slab_sysfs_init);
|
|||
* The /proc/slabinfo ABI
|
||||
*/
|
||||
#ifdef CONFIG_SLABINFO
|
||||
static void print_slabinfo_header(struct seq_file *m)
|
||||
{
|
||||
seq_puts(m, "slabinfo - version: 2.1\n");
|
||||
seq_puts(m, "# name <active_objs> <num_objs> <object_size> "
|
||||
"<objperslab> <pagesperslab>");
|
||||
seq_puts(m, " : tunables <limit> <batchcount> <sharedfactor>");
|
||||
seq_puts(m, " : slabdata <active_slabs> <num_slabs> <sharedavail>");
|
||||
seq_putc(m, '\n');
|
||||
}
|
||||
|
||||
static void *s_start(struct seq_file *m, loff_t *pos)
|
||||
{
|
||||
loff_t n = *pos;
|
||||
|
||||
mutex_lock(&slab_mutex);
|
||||
if (!n)
|
||||
print_slabinfo_header(m);
|
||||
|
||||
return seq_list_start(&slab_caches, *pos);
|
||||
}
|
||||
|
||||
static void *s_next(struct seq_file *m, void *p, loff_t *pos)
|
||||
{
|
||||
return seq_list_next(p, &slab_caches, pos);
|
||||
}
|
||||
|
||||
static void s_stop(struct seq_file *m, void *p)
|
||||
{
|
||||
mutex_unlock(&slab_mutex);
|
||||
}
|
||||
|
||||
static int s_show(struct seq_file *m, void *p)
|
||||
void get_slabinfo(struct kmem_cache *s, struct slabinfo *sinfo)
|
||||
{
|
||||
unsigned long nr_partials = 0;
|
||||
unsigned long nr_slabs = 0;
|
||||
unsigned long nr_inuse = 0;
|
||||
unsigned long nr_objs = 0;
|
||||
unsigned long nr_free = 0;
|
||||
struct kmem_cache *s;
|
||||
int node;
|
||||
|
||||
s = list_entry(p, struct kmem_cache, list);
|
||||
|
||||
for_each_online_node(node) {
|
||||
struct kmem_cache_node *n = get_node(s, node);
|
||||
|
||||
|
@ -5460,41 +5425,21 @@ static int s_show(struct seq_file *m, void *p)
|
|||
nr_free += count_partial(n, count_free);
|
||||
}
|
||||
|
||||
nr_inuse = nr_objs - nr_free;
|
||||
|
||||
seq_printf(m, "%-17s %6lu %6lu %6u %4u %4d", s->name, nr_inuse,
|
||||
nr_objs, s->size, oo_objects(s->oo),
|
||||
(1 << oo_order(s->oo)));
|
||||
seq_printf(m, " : tunables %4u %4u %4u", 0, 0, 0);
|
||||
seq_printf(m, " : slabdata %6lu %6lu %6lu", nr_slabs, nr_slabs,
|
||||
0UL);
|
||||
seq_putc(m, '\n');
|
||||
return 0;
|
||||
sinfo->active_objs = nr_objs - nr_free;
|
||||
sinfo->num_objs = nr_objs;
|
||||
sinfo->active_slabs = nr_slabs;
|
||||
sinfo->num_slabs = nr_slabs;
|
||||
sinfo->objects_per_slab = oo_objects(s->oo);
|
||||
sinfo->cache_order = oo_order(s->oo);
|
||||
}
|
||||
|
||||
static const struct seq_operations slabinfo_op = {
|
||||
.start = s_start,
|
||||
.next = s_next,
|
||||
.stop = s_stop,
|
||||
.show = s_show,
|
||||
};
|
||||
|
||||
static int slabinfo_open(struct inode *inode, struct file *file)
|
||||
void slabinfo_show_stats(struct seq_file *m, struct kmem_cache *s)
|
||||
{
|
||||
return seq_open(file, &slabinfo_op);
|
||||
}
|
||||
|
||||
static const struct file_operations proc_slabinfo_operations = {
|
||||
.open = slabinfo_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
static int __init slab_proc_init(void)
|
||||
ssize_t slabinfo_write(struct file *file, const char __user *buffer,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
proc_create("slabinfo", S_IRUSR, NULL, &proc_slabinfo_operations);
|
||||
return 0;
|
||||
return -EIO;
|
||||
}
|
||||
module_init(slab_proc_init);
|
||||
#endif /* CONFIG_SLABINFO */
|
||||
|
|
Загрузка…
Ссылка в новой задаче