Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
a304f836
Commit
a304f836
authored
Dec 18, 2012
by
Pekka Enberg
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'slab/procfs' into slab/for-linus
parents
29594404
0d7561c6
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
166 additions
and
158 deletions
+166
-158
mm/slab.c
mm/slab.c
+26
-92
mm/slab.h
mm/slab.h
+20
-0
mm/slab_common.c
mm/slab_common.c
+109
-0
mm/slub.c
mm/slub.c
+11
-66
No files found.
mm/slab.c
View file @
a304f836
...
...
@@ -4276,54 +4276,8 @@ static void cache_reap(struct work_struct *w)
}
#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.
*/
#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
)
void
get_slabinfo
(
struct
kmem_cache
*
cachep
,
struct
slabinfo
*
sinfo
)
{
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
*/
s
tatic
s
size_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
...
...
mm/slab.h
View file @
a304f836
...
...
@@ -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
mm/slab_common.c
View file @
a304f836
...
...
@@ -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 */
mm/slub.c
View file @
a304f836
...
...
@@ -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 */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment