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
Kirill Smelkov
linux
Commits
62dfe539
Commit
62dfe539
authored
Feb 09, 2002
by
Alexander Viro
Committed by
David S. Miller
Feb 09, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] /proc/slabinfo cleanup (seq_...)
Straightforward rewrite to seq_file.
parent
aa45600e
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
141 additions
and
140 deletions
+141
-140
fs/proc/proc_misc.c
fs/proc/proc_misc.c
+15
-4
include/linux/slab.h
include/linux/slab.h
+0
-5
mm/slab.c
mm/slab.c
+126
-131
No files found.
fs/proc/proc_misc.c
View file @
62dfe539
...
...
@@ -223,6 +223,20 @@ static struct file_operations proc_ksyms_operations = {
};
#endif
extern
struct
seq_operations
slabinfo_op
;
extern
ssize_t
slabinfo_write
(
struct
file
*
,
const
char
*
,
size_t
,
loff_t
*
);
static
int
slabinfo_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
seq_open
(
file
,
&
slabinfo_op
);
}
static
struct
file_operations
proc_slabinfo_operations
=
{
open:
slabinfo_open
,
read:
seq_read
,
write:
slabinfo_write
,
llseek:
seq_lseek
,
release:
seq_release
,
};
static
int
kstat_read_proc
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
{
...
...
@@ -551,6 +565,7 @@ void __init proc_misc_init(void)
entry
->
proc_fops
=
&
proc_kmsg_operations
;
create_seq_entry
(
"cpuinfo"
,
0
,
&
proc_cpuinfo_operations
);
create_seq_entry
(
"interrupts"
,
0
,
&
proc_interrupts_operations
);
create_seq_entry
(
"slabinfo"
,
S_IWUSR
|
S_IRUGO
,
&
proc_slabinfo_operations
);
#ifdef CONFIG_MODULES
create_seq_entry
(
"ksyms"
,
0
,
&
proc_ksyms_operations
);
#endif
...
...
@@ -575,8 +590,4 @@ void __init proc_misc_init(void)
entry
->
proc_fops
=
&
ppc_htab_operations
;
}
#endif
entry
=
create_proc_read_entry
(
"slabinfo"
,
S_IWUSR
|
S_IRUGO
,
NULL
,
slabinfo_read_proc
,
NULL
);
if
(
entry
)
entry
->
write_proc
=
slabinfo_write_proc
;
}
include/linux/slab.h
View file @
62dfe539
...
...
@@ -62,11 +62,6 @@ extern void *kmalloc(size_t, int);
extern
void
kfree
(
const
void
*
);
extern
int
FASTCALL
(
kmem_cache_reap
(
int
));
extern
int
slabinfo_read_proc
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
);
struct
file
;
extern
int
slabinfo_write_proc
(
struct
file
*
file
,
const
char
*
buffer
,
unsigned
long
count
,
void
*
data
);
/* System wide caches */
extern
kmem_cache_t
*
vm_area_cachep
;
...
...
mm/slab.c
View file @
62dfe539
...
...
@@ -75,6 +75,7 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/compiler.h>
#include <linux/seq_file.h>
#include <asm/uaccess.h>
/*
...
...
@@ -1869,31 +1870,56 @@ int kmem_cache_reap (int gfp_mask)
}
#ifdef CONFIG_PROC_FS
/* /proc/slabinfo
* cache-name num-active-objs total-objs
* obj-size num-active-slabs total-slabs
* num-pages-per-slab
*/
#define FIXUP(t) \
do { \
if (len <= off) { \
off -= len; \
len = 0; \
} else { \
if (len-off > count) \
goto t; \
} \
} while (0)
static
int
proc_getdata
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
)
static
void
*
s_start
(
struct
seq_file
*
m
,
loff_t
*
pos
)
{
loff_t
n
=
*
pos
;
struct
list_head
*
p
;
int
len
=
0
;
/* Output format version, so at least we can change it without _too_
* many complaints.
*/
len
+=
sprintf
(
page
+
len
,
"slabinfo - version: 1.1"
down
(
&
cache_chain_sem
);
if
(
!
n
)
return
(
void
*
)
1
;
p
=
&
cache_cache
.
next
;
while
(
--
n
)
{
p
=
p
->
next
;
if
(
p
==
&
cache_cache
.
next
)
return
NULL
;
}
return
list_entry
(
p
,
kmem_cache_t
,
next
);
}
static
void
*
s_next
(
struct
seq_file
*
m
,
void
*
p
,
loff_t
*
pos
)
{
kmem_cache_t
*
cachep
=
p
;
++*
pos
;
if
(
p
==
(
void
*
)
1
)
return
&
cache_cache
;
cachep
=
list_entry
(
cachep
->
next
.
next
,
kmem_cache_t
,
next
);
return
cachep
==
&
cache_cache
?
NULL
:
cachep
;
}
static
void
s_stop
(
struct
seq_file
*
m
,
void
*
p
)
{
up
(
&
cache_chain_sem
);
}
static
int
s_show
(
struct
seq_file
*
m
,
void
*
p
)
{
kmem_cache_t
*
cachep
=
p
;
struct
list_head
*
q
;
slab_t
*
slabp
;
unsigned
long
active_objs
;
unsigned
long
num_objs
;
unsigned
long
active_slabs
=
0
;
unsigned
long
num_slabs
;
const
char
*
name
;
if
(
p
==
(
void
*
)
1
)
{
/*
* Output format version, so at least we can change it
* without _too_ many complaints.
*/
seq_puts
(
m
,
"slabinfo - version: 1.1"
#if STATS
" (statistics)"
#endif
...
...
@@ -1901,116 +1927,89 @@ static int proc_getdata (char*page, char**start, off_t off, int count)
" (SMP)"
#endif
"
\n
"
);
FIXUP
(
got_data
);
down
(
&
cache_chain_sem
);
p
=
&
cache_cache
.
next
;
do
{
kmem_cache_t
*
cachep
;
struct
list_head
*
q
;
slab_t
*
slabp
;
unsigned
long
active_objs
;
unsigned
long
num_objs
;
unsigned
long
active_slabs
=
0
;
unsigned
long
num_slabs
;
const
char
*
name
;
cachep
=
list_entry
(
p
,
kmem_cache_t
,
next
);
return
0
;
}
spin_lock_irq
(
&
cachep
->
spinlock
);
active_objs
=
0
;
num_slabs
=
0
;
list_for_each
(
q
,
&
cachep
->
slabs_full
)
{
slabp
=
list_entry
(
q
,
slab_t
,
list
);
if
(
slabp
->
inuse
!=
cachep
->
num
)
BUG
();
active_objs
+=
cachep
->
num
;
active_slabs
++
;
}
list_for_each
(
q
,
&
cachep
->
slabs_partial
)
{
slabp
=
list_entry
(
q
,
slab_t
,
list
);
if
(
slabp
->
inuse
==
cachep
->
num
||
!
slabp
->
inuse
)
BUG
();
active_objs
+=
slabp
->
inuse
;
active_slabs
++
;
}
list_for_each
(
q
,
&
cachep
->
slabs_free
)
{
slabp
=
list_entry
(
q
,
slab_t
,
list
);
if
(
slabp
->
inuse
)
BUG
();
num_slabs
++
;
}
num_slabs
+=
active_slabs
;
num_objs
=
num_slabs
*
cachep
->
num
;
spin_lock_irq
(
&
cachep
->
spinlock
);
active_objs
=
0
;
num_slabs
=
0
;
list_for_each
(
q
,
&
cachep
->
slabs_full
)
{
slabp
=
list_entry
(
q
,
slab_t
,
list
);
if
(
slabp
->
inuse
!=
cachep
->
num
)
BUG
();
active_objs
+=
cachep
->
num
;
active_slabs
++
;
}
list_for_each
(
q
,
&
cachep
->
slabs_partial
)
{
slabp
=
list_entry
(
q
,
slab_t
,
list
);
if
(
slabp
->
inuse
==
cachep
->
num
||
!
slabp
->
inuse
)
BUG
();
active_objs
+=
slabp
->
inuse
;
active_slabs
++
;
}
list_for_each
(
q
,
&
cachep
->
slabs_free
)
{
slabp
=
list_entry
(
q
,
slab_t
,
list
);
if
(
slabp
->
inuse
)
BUG
();
num_slabs
++
;
}
num_slabs
+=
active_slabs
;
num_objs
=
num_slabs
*
cachep
->
num
;
name
=
cachep
->
name
;
{
char
tmp
;
if
(
__get_user
(
tmp
,
name
))
name
=
"broken"
;
}
name
=
cachep
->
name
;
{
char
tmp
;
if
(
__get_user
(
tmp
,
name
))
name
=
"broken"
;
}
len
+=
sprintf
(
page
+
len
,
"%-17s %6lu %6lu %6u %4lu %4lu %4u"
,
name
,
active_objs
,
num_objs
,
cachep
->
objsize
,
active_slabs
,
num_slabs
,
(
1
<<
cachep
->
gfporder
));
seq_printf
(
m
,
"%-17s %6lu %6lu %6u %4lu %4lu %4u"
,
name
,
active_objs
,
num_objs
,
cachep
->
objsize
,
active_slabs
,
num_slabs
,
(
1
<<
cachep
->
gfporder
));
#if STATS
{
unsigned
long
errors
=
cachep
->
errors
;
unsigned
long
high
=
cachep
->
high_mark
;
unsigned
long
grown
=
cachep
->
grown
;
unsigned
long
reaped
=
cachep
->
reaped
;
unsigned
long
allocs
=
cachep
->
num_allocations
;
len
+=
sprintf
(
page
+
len
,
" : %6lu %7lu %5lu %4lu %4lu"
,
high
,
allocs
,
grown
,
reaped
,
errors
);
}
{
unsigned
long
errors
=
cachep
->
errors
;
unsigned
long
high
=
cachep
->
high_mark
;
unsigned
long
grown
=
cachep
->
grown
;
unsigned
long
reaped
=
cachep
->
reaped
;
unsigned
long
allocs
=
cachep
->
num_allocations
;
seq_printf
(
m
,
" : %6lu %7lu %5lu %4lu %4lu"
,
high
,
allocs
,
grown
,
reaped
,
errors
);
}
#endif
#ifdef CONFIG_SMP
{
unsigned
int
batchcount
=
cachep
->
batchcount
;
unsigned
int
limit
;
if
(
cc_data
(
cachep
))
limit
=
cc_data
(
cachep
)
->
limit
;
else
limit
=
0
;
len
+=
sprintf
(
page
+
len
,
" : %4u %4u"
,
limit
,
batchcount
);
}
{
unsigned
int
batchcount
=
cachep
->
batchcount
;
unsigned
int
limit
;
if
(
cc_data
(
cachep
))
limit
=
cc_data
(
cachep
)
->
limit
;
else
limit
=
0
;
seq_printf
(
m
,
" : %4u %4u"
,
limit
,
batchcount
);
}
#endif
#if STATS && defined(CONFIG_SMP)
{
unsigned
long
allochit
=
atomic_read
(
&
cachep
->
allochit
);
unsigned
long
allocmiss
=
atomic_read
(
&
cachep
->
allocmiss
);
unsigned
long
freehit
=
atomic_read
(
&
cachep
->
freehit
);
unsigned
long
freemiss
=
atomic_read
(
&
cachep
->
freemiss
);
len
+=
sprintf
(
page
+
len
,
" : %6lu %6lu %6lu %6lu"
,
allochit
,
allocmiss
,
freehit
,
freemiss
);
}
{
unsigned
long
allochit
=
atomic_read
(
&
cachep
->
allochit
);
unsigned
long
allocmiss
=
atomic_read
(
&
cachep
->
allocmiss
);
unsigned
long
freehit
=
atomic_read
(
&
cachep
->
freehit
);
unsigned
long
freemiss
=
atomic_read
(
&
cachep
->
freemiss
);
seq_printf
(
m
,
" : %6lu %6lu %6lu %6lu"
,
allochit
,
allocmiss
,
freehit
,
freemiss
);
}
#endif
len
+=
sprintf
(
page
+
len
,
"
\n
"
);
spin_unlock_irq
(
&
cachep
->
spinlock
);
FIXUP
(
got_data_up
);
p
=
cachep
->
next
.
next
;
}
while
(
p
!=
&
cache_cache
.
next
);
got_data_up:
up
(
&
cache_chain_sem
);
got_data:
*
start
=
page
+
off
;
return
len
;
spin_unlock_irq
(
&
cachep
->
spinlock
);
seq_putc
(
m
,
'\n'
);
return
0
;
}
/**
* slabinfo_read_proc - generates /proc/slabinfo
* @page: scratch area, one page long
* @start: pointer to the pointer to the output buffer
* @off: offset within /proc/slabinfo the caller is interested in
* @count: requested len in bytes
* @eof: eof marker
* @data: unused
* slabinfo_op - iterator that generates /proc/slabinfo
*
*
The contents of the buffer are
*
Output layout:
* cache-name
* num-active-objs
* total-objs
...
...
@@ -2020,28 +2019,24 @@ static int proc_getdata (char*page, char**start, off_t off, int count)
* num-pages-per-slab
* + further values on SMP and with statistics enabled
*/
int
slabinfo_read_proc
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
{
int
len
=
proc_getdata
(
page
,
start
,
off
,
count
);
len
-=
(
*
start
-
page
);
if
(
len
<=
count
)
*
eof
=
1
;
if
(
len
>
count
)
len
=
count
;
if
(
len
<
0
)
len
=
0
;
return
len
;
}
struct
seq_operations
slabinfo_op
=
{
start:
s_start
,
next:
s_next
,
stop:
s_stop
,
show:
s_show
};
#define MAX_SLABINFO_WRITE 128
/**
* slabinfo_write
_proc
- SMP tuning for the slab allocator
* slabinfo_write - SMP tuning for the slab allocator
* @file: unused
* @buffer: user buffer
* @count: data len
* @data: unused
*/
int
slabinfo_write_proc
(
struct
file
*
file
,
const
char
*
buffer
,
unsigned
long
count
,
void
*
data
)
ssize_t
slabinfo_write
(
struct
file
*
file
,
const
char
*
buffer
,
size_t
count
,
loff_t
*
ppos
)
{
#ifdef CONFIG_SMP
char
kbuf
[
MAX_SLABINFO_WRITE
+
1
],
*
tmp
;
...
...
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