Skip to content

Commit 0eac776

Browse files
tsautereau-anssianthraxx
authored andcommitted
slub: Extend init_on_alloc to slab caches with constructors
Signed-off-by: Thibaut Sautereau <[email protected]> Signed-off-by: Levente Polyak <[email protected]>
1 parent fdbc1df commit 0eac776

File tree

2 files changed

+20
-5
lines changed

2 files changed

+20
-5
lines changed

mm/slab.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,8 +614,10 @@ static inline void cache_random_seq_destroy(struct kmem_cache *cachep) { }
614614
static inline bool slab_want_init_on_alloc(gfp_t flags, struct kmem_cache *c)
615615
{
616616
if (static_branch_unlikely(&init_on_alloc)) {
617+
#ifndef CONFIG_SLUB
617618
if (c->ctor)
618619
return false;
620+
#endif
619621
if (c->flags & (SLAB_TYPESAFE_BY_RCU | SLAB_POISON))
620622
return flags & __GFP_ZERO;
621623
return true;

mm/slub.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1635,9 +1635,10 @@ static inline bool slab_free_freelist_hook(struct kmem_cache *s,
16351635
* need to show a valid freepointer to check_object().
16361636
*
16371637
* Note that doing this for all caches (not just ctor
1638-
* ones, which have s->offset != NULL)) causes a GPF,
1639-
* due to KASAN poisoning and the way set_freepointer()
1640-
* eventually dereferences the freepointer.
1638+
* ones, which have s->offset >= object_size)) causes a
1639+
* GPF, due to KASAN poisoning and the way
1640+
* set_freepointer() eventually dereferences the
1641+
* freepointer.
16411642
*/
16421643
set_freepointer(s, object, NULL);
16431644
}
@@ -2952,8 +2953,14 @@ static __always_inline void *slab_alloc_node(struct kmem_cache *s,
29522953
if (s->ctor)
29532954
s->ctor(object);
29542955
kasan_poison_object_data(s, object);
2955-
} else if (unlikely(slab_want_init_on_alloc(gfpflags, s)) && object)
2956+
} else if (unlikely(slab_want_init_on_alloc(gfpflags, s)) && object) {
29562957
memset(object, 0, s->object_size);
2958+
if (s->ctor) {
2959+
kasan_unpoison_object_data(s, object);
2960+
s->ctor(object);
2961+
kasan_poison_object_data(s, object);
2962+
}
2963+
}
29572964

29582965
if (object) {
29592966
check_canary(s, object, s->random_inactive);
@@ -3411,8 +3418,14 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size,
34113418
} else if (unlikely(slab_want_init_on_alloc(flags, s))) {
34123419
int j;
34133420

3414-
for (j = 0; j < i; j++)
3421+
for (j = 0; j < i; j++) {
34153422
memset(p[j], 0, s->object_size);
3423+
if (s->ctor) {
3424+
kasan_unpoison_object_data(s, p[j]);
3425+
s->ctor(p[j]);
3426+
kasan_poison_object_data(s, p[j]);
3427+
}
3428+
}
34163429
}
34173430

34183431
for (k = 0; k < i; k++) {

0 commit comments

Comments
 (0)