mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-26 13:44:15 +08:00
Merge branch 'slab/procfs' into slab/next
This commit is contained in:
commit
b4f591c45f
118
mm/slab.c
118
mm/slab.c
@ -4276,54 +4276,8 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SLABINFO
|
#ifdef CONFIG_SLABINFO
|
||||||
|
void get_slabinfo(struct kmem_cache *cachep, struct slabinfo *sinfo)
|
||||||
static void print_slabinfo_header(struct seq_file *m)
|
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* 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;
|
struct slab *slabp;
|
||||||
unsigned long active_objs;
|
unsigned long active_objs;
|
||||||
unsigned long num_objs;
|
unsigned long num_objs;
|
||||||
@ -4378,13 +4332,20 @@ static int s_show(struct seq_file *m, void *p)
|
|||||||
if (error)
|
if (error)
|
||||||
printk(KERN_ERR "slab: cache %s error: %s\n", name, error);
|
printk(KERN_ERR "slab: cache %s error: %s\n", name, error);
|
||||||
|
|
||||||
seq_printf(m, "%-17s %6lu %6lu %6u %4u %4d",
|
sinfo->active_objs = active_objs;
|
||||||
name, active_objs, num_objs, cachep->size,
|
sinfo->num_objs = num_objs;
|
||||||
cachep->num, (1 << cachep->gfporder));
|
sinfo->active_slabs = active_slabs;
|
||||||
seq_printf(m, " : tunables %4u %4u %4u",
|
sinfo->num_slabs = num_slabs;
|
||||||
cachep->limit, cachep->batchcount, cachep->shared);
|
sinfo->shared_avail = shared_avail;
|
||||||
seq_printf(m, " : slabdata %6lu %6lu %6lu",
|
sinfo->limit = cachep->limit;
|
||||||
active_slabs, num_slabs, shared_avail);
|
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
|
#if STATS
|
||||||
{ /* list3 stats */
|
{ /* list3 stats */
|
||||||
unsigned long high = cachep->high_mark;
|
unsigned long high = cachep->high_mark;
|
||||||
@ -4414,31 +4375,8 @@ static int s_show(struct seq_file *m, void *p)
|
|||||||
allochit, allocmiss, freehit, freemiss);
|
allochit, allocmiss, freehit, freemiss);
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
#define MAX_SLABINFO_WRITE 128
|
||||||
/**
|
/**
|
||||||
* slabinfo_write - Tuning for the slab allocator
|
* slabinfo_write - Tuning for the slab allocator
|
||||||
@ -4447,7 +4385,7 @@ static const struct seq_operations slabinfo_op = {
|
|||||||
* @count: data length
|
* @count: data length
|
||||||
* @ppos: unused
|
* @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)
|
size_t count, loff_t *ppos)
|
||||||
{
|
{
|
||||||
char kbuf[MAX_SLABINFO_WRITE + 1], *tmp;
|
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;
|
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
|
#ifdef CONFIG_DEBUG_SLAB_LEAK
|
||||||
|
|
||||||
static void *leaks_start(struct seq_file *m, loff_t *pos)
|
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;
|
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 = {
|
static const struct seq_operations slabstats_op = {
|
||||||
.start = leaks_start,
|
.start = leaks_start,
|
||||||
.next = s_next,
|
.next = s_next,
|
||||||
@ -4665,7 +4600,6 @@ static const struct file_operations proc_slabstats_operations = {
|
|||||||
|
|
||||||
static int __init slab_proc_init(void)
|
static int __init slab_proc_init(void)
|
||||||
{
|
{
|
||||||
proc_create("slabinfo",S_IWUSR|S_IRUSR,NULL,&proc_slabinfo_operations);
|
|
||||||
#ifdef CONFIG_DEBUG_SLAB_LEAK
|
#ifdef CONFIG_DEBUG_SLAB_LEAK
|
||||||
proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations);
|
proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations);
|
||||||
#endif
|
#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 *);
|
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
|
#endif
|
||||||
|
109
mm/slab_common.c
109
mm/slab_common.c
@ -13,6 +13,8 @@
|
|||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/cpu.h>
|
#include <linux/cpu.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
#include <linux/seq_file.h>
|
||||||
|
#include <linux/proc_fs.h>
|
||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
#include <asm/tlbflush.h>
|
#include <asm/tlbflush.h>
|
||||||
#include <asm/page.h>
|
#include <asm/page.h>
|
||||||
@ -192,3 +194,110 @@ int slab_is_available(void)
|
|||||||
{
|
{
|
||||||
return slab_state >= UP;
|
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
@ -5399,49 +5399,14 @@ __initcall(slab_sysfs_init);
|
|||||||
* The /proc/slabinfo ABI
|
* The /proc/slabinfo ABI
|
||||||
*/
|
*/
|
||||||
#ifdef CONFIG_SLABINFO
|
#ifdef CONFIG_SLABINFO
|
||||||
static void print_slabinfo_header(struct seq_file *m)
|
void get_slabinfo(struct kmem_cache *s, struct slabinfo *sinfo)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
unsigned long nr_partials = 0;
|
unsigned long nr_partials = 0;
|
||||||
unsigned long nr_slabs = 0;
|
unsigned long nr_slabs = 0;
|
||||||
unsigned long nr_inuse = 0;
|
|
||||||
unsigned long nr_objs = 0;
|
unsigned long nr_objs = 0;
|
||||||
unsigned long nr_free = 0;
|
unsigned long nr_free = 0;
|
||||||
struct kmem_cache *s;
|
|
||||||
int node;
|
int node;
|
||||||
|
|
||||||
s = list_entry(p, struct kmem_cache, list);
|
|
||||||
|
|
||||||
for_each_online_node(node) {
|
for_each_online_node(node) {
|
||||||
struct kmem_cache_node *n = get_node(s, node);
|
struct kmem_cache_node *n = get_node(s, node);
|
||||||
|
|
||||||
@ -5454,41 +5419,21 @@ static int s_show(struct seq_file *m, void *p)
|
|||||||
nr_free += count_partial(n, count_free);
|
nr_free += count_partial(n, count_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
nr_inuse = nr_objs - nr_free;
|
sinfo->active_objs = nr_objs - nr_free;
|
||||||
|
sinfo->num_objs = nr_objs;
|
||||||
seq_printf(m, "%-17s %6lu %6lu %6u %4u %4d", s->name, nr_inuse,
|
sinfo->active_slabs = nr_slabs;
|
||||||
nr_objs, s->size, oo_objects(s->oo),
|
sinfo->num_slabs = nr_slabs;
|
||||||
(1 << oo_order(s->oo)));
|
sinfo->objects_per_slab = oo_objects(s->oo);
|
||||||
seq_printf(m, " : tunables %4u %4u %4u", 0, 0, 0);
|
sinfo->cache_order = oo_order(s->oo);
|
||||||
seq_printf(m, " : slabdata %6lu %6lu %6lu", nr_slabs, nr_slabs,
|
|
||||||
0UL);
|
|
||||||
seq_putc(m, '\n');
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct seq_operations slabinfo_op = {
|
void slabinfo_show_stats(struct seq_file *m, struct kmem_cache *s)
|
||||||
.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 = {
|
ssize_t slabinfo_write(struct file *file, const char __user *buffer,
|
||||||
.open = slabinfo_open,
|
size_t count, loff_t *ppos)
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = seq_release,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int __init slab_proc_init(void)
|
|
||||||
{
|
{
|
||||||
proc_create("slabinfo", S_IRUSR, NULL, &proc_slabinfo_operations);
|
return -EIO;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
module_init(slab_proc_init);
|
|
||||||
#endif /* CONFIG_SLABINFO */
|
#endif /* CONFIG_SLABINFO */
|
||||||
|
Loading…
Reference in New Issue
Block a user