Skip to content

Commit 6144847

Browse files
dvyukovtorvalds
authored andcommitted
mm: don't warn about large allocations for slab
Slub does not call kmalloc_slab() for sizes > KMALLOC_MAX_CACHE_SIZE, instead it falls back to kmalloc_large(). For slab KMALLOC_MAX_CACHE_SIZE == KMALLOC_MAX_SIZE and it calls kmalloc_slab() for all allocations relying on NULL return value for over-sized allocations. This inconsistency leads to unwanted warnings from kmalloc_slab() for over-sized allocations for slab. Returning NULL for failed allocations is the expected behavior. Make slub and slab code consistent by checking size > KMALLOC_MAX_CACHE_SIZE in slab before calling kmalloc_slab(). While we are here also fix the check in kmalloc_slab(). We should check against KMALLOC_MAX_CACHE_SIZE rather than KMALLOC_MAX_SIZE. It all kinda worked because for slab the constants are the same, and slub always checks the size against KMALLOC_MAX_CACHE_SIZE before kmalloc_slab(). But if we get there with size > KMALLOC_MAX_CACHE_SIZE anyhow bad things will happen. For example, in case of a newly introduced bug in slub code. Also move the check in kmalloc_slab() from function entry to the size > 192 case. This partially compensates for the additional check in slab code and makes slub code a bit faster (at least theoretically). Also drop __GFP_NOWARN in the warning check. This warning means a bug in slab code itself, user-passed flags have nothing to do with it. Nothing of this affects slob. Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Dmitry Vyukov <[email protected]> Reported-by: [email protected] Reported-by: [email protected] Reported-by: [email protected] Reported-by: [email protected] Reported-by: [email protected] Acked-by: Christoph Lameter <[email protected]> Acked-by: Vlastimil Babka <[email protected]> Cc: Pekka Enberg <[email protected]> Cc: David Rientjes <[email protected]> Cc: Joonsoo Kim <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 0684e65 commit 6144847

File tree

2 files changed

+10
-6
lines changed

2 files changed

+10
-6
lines changed

mm/slab.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3675,6 +3675,8 @@ __do_kmalloc_node(size_t size, gfp_t flags, int node, unsigned long caller)
36753675
struct kmem_cache *cachep;
36763676
void *ret;
36773677

3678+
if (unlikely(size > KMALLOC_MAX_CACHE_SIZE))
3679+
return NULL;
36783680
cachep = kmalloc_slab(size, flags);
36793681
if (unlikely(ZERO_OR_NULL_PTR(cachep)))
36803682
return cachep;
@@ -3710,6 +3712,8 @@ static __always_inline void *__do_kmalloc(size_t size, gfp_t flags,
37103712
struct kmem_cache *cachep;
37113713
void *ret;
37123714

3715+
if (unlikely(size > KMALLOC_MAX_CACHE_SIZE))
3716+
return NULL;
37133717
cachep = kmalloc_slab(size, flags);
37143718
if (unlikely(ZERO_OR_NULL_PTR(cachep)))
37153719
return cachep;

mm/slab_common.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,18 +1027,18 @@ struct kmem_cache *kmalloc_slab(size_t size, gfp_t flags)
10271027
{
10281028
unsigned int index;
10291029

1030-
if (unlikely(size > KMALLOC_MAX_SIZE)) {
1031-
WARN_ON_ONCE(!(flags & __GFP_NOWARN));
1032-
return NULL;
1033-
}
1034-
10351030
if (size <= 192) {
10361031
if (!size)
10371032
return ZERO_SIZE_PTR;
10381033

10391034
index = size_index[size_index_elem(size)];
1040-
} else
1035+
} else {
1036+
if (unlikely(size > KMALLOC_MAX_CACHE_SIZE)) {
1037+
WARN_ON(1);
1038+
return NULL;
1039+
}
10411040
index = fls(size - 1);
1041+
}
10421042

10431043
#ifdef CONFIG_ZONE_DMA
10441044
if (unlikely((flags & GFP_DMA)))

0 commit comments

Comments
 (0)