1
2
3
4
5
6
7
|
#define SLAB_DEBUG_FREE 0x00000100UL /* DEBUG: Perform (expensive) checks on free */
#define SLAB_RED_ZONE 0x00000400UL /* DEBUG: Red zone objs in a cache */
#define SLAB_POISON 0x00000800UL /* DEBUG: Poison objects */
#define SLAB_STORE_USER 0x00010000UL /* DEBUG: Store the last owner for bug hunting */
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
static
__always_inline
void
*slab_alloc_node(
struct
kmem_cache *s,
size_t
size
/* 添加size参数 */
, gfp_t gfpflags,
int
node, unsigned
long
addr)
{
......
if
(unlikely(gfpflags & __GFP_ZERO) && object)
memset
(object, 0, s->object_size);
/* 添加这段代码 */
if
(object && (s->flags&SLAB_RED_ZONE)) {
size = s->object_size - size;
set_freepointer(s, object, (
void
*)(
uintptr_t
)size);
if
(size)
memset
((
void
*)object + s->object_size - size, SLUB_RED_ACTIVE, size);
/* 初始化red zone */
}
/* 添加结束 */
slab_post_alloc_hook(s, gfpflags, object);
return
object;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
static
__always_inline
void
*slab_alloc(
struct
kmem_cache *s,
size_t
size
/* 添加size参数 */
, gfp_t gfpflags, unsigned
long
addr)
{
return
slab_alloc_node(s, size
/* 添加size参数 */
, gfpflags, NUMA_NO_NODE, addr);
}
void
*kmem_cache_alloc(
struct
kmem_cache *s, gfp_t gfpflags)
{
void
*ret = slab_alloc(s, s->object_size
/* 添加object_size参数 */
, gfpflags, _RET_IP_);
......
}
void
*kmem_cache_alloc_trace(
struct
kmem_cache *s, gfp_t gfpflags,
size_t
size)
{
void
*ret = slab_alloc(s, size
/* 添加size参数 */
, gfpflags, _RET_IP_);
......
}
void
*kmem_cache_alloc_node(
struct
kmem_cache *s, gfp_t gfpflags,
int
node)
{
void
*ret = slab_alloc_node(s, s->object_size
/* 添加object_size参数 */
, gfpflags, node, _RET_IP_);
......
}
void
*kmem_cache_alloc_node_trace(
struct
kmem_cache *s, gfp_t gfpflags,
int
node,
size_t
size)
{
void
*ret = slab_alloc_node(s, size
/* 添加size参数 */
, gfpflags, node, _RET_IP_);
......
}
void
*__kmalloc(
size_t
size, gfp_t flags)
{
......
ret = slab_alloc(s, size
/* 添加size参数 */
, flags, _RET_IP_);
......
}
void
*__kmalloc_node(
size_t
size, gfp_t flags,
int
node)
{
......
ret = slab_alloc_node(s, size
/* 添加size参数 */
, flags, node, _RET_IP_);
......
}
void
*__kmalloc_track_caller(
size_t
size, gfp_t gfpflags, unsigned
long
caller)
{
......
ret = slab_alloc(s, size
/* 添加size参数 */
, gfpflags, caller);
......
}
void
*__kmalloc_node_track_caller(
size_t
size, gfp_t gfpflags,
int
node, unsigned
long
caller)
{
......
ret = slab_alloc_node(s, size
/* 添加size参数 */
, gfpflags, node, caller);
......
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
static
int
check_object(
struct
kmem_cache *s,
struct
page *page,
void
*object, u8 val)
{
......
/* Check free pointer validity */
/* 添加这段代码 */
if
(val == SLUB_RED_ACTIVE) {
if
(s->flags&SLAB_RED_ZONE) {
size_t
remain = (
size_t
)get_freepointer(s, p);
BUG_ON(remain >= s->object_size);
if
(remain && !check_bytes_and_report(s, page, object,
"Redzone"
, object + s->object_size - remain, val, remain))
return
0;
}
}
else
/* 添加结束 */
if
(!check_valid_pointer(s, page, get_freepointer(s, p))) {
object_err(s, page, p,
"Freepointer corrupt"
);
set_freepointer(s, p, NULL);
return
0;
}
return
1;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
static
inline
size_t
slab_ksize(
const
struct
kmem_cache *s,
const
void
*object
/* 添加object参数 */
)
{
#ifdef CONFIG_SLUB_DEBUG
/* 添加这段代码 */
if
((s->flags&SLAB_RED_ZONE) && object) {
size_t
remain = (
size_t
)get_freepointer((
void
*)s, (
void
*)object);
BUG_ON(remain >= s->object_size);
return
s->object_size - remain;
}
/* 添加结束 */
if
(s->flags&(SLAB_RED_ZONE|SLAB_POISON))
return
s->object_size;
#endif
......
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
static
inline
void
slab_post_alloc_hook(
struct
kmem_cache *s, gfp_t flags,
void
*object)
{
......
kmemcheck_slab_alloc(s, flags, object, slab_ksize(s, object
/* 添加这个参数 */
));
......
}
size_t
ksize(
const
void
*object)
{
......
return
slab_ksize(page->slab_cache, object
/* 添加object参数 */
);
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
static
void
early_kmem_cache_node_alloc(
int
node)
{
......
#ifdef CONFIG_SLUB_DEBUG
set_freepointer(kmem_cache_node, n, NULL);
/* 添加这行代码 */
init_object(kmem_cache_node, n, SLUB_RED_ACTIVE);
init_tracking(kmem_cache_node, n);
#endif
......
}
|