diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/slab.c | 8 | ||||
-rw-r--r-- | mm/slob.c | 2 | ||||
-rw-r--r-- | mm/slub.c | 24 |
3 files changed, 24 insertions, 10 deletions
@@ -2746,7 +2746,7 @@ static int cache_grow(struct kmem_cache *cachep, | |||
2746 | * Be lazy and only check for valid flags here, keeping it out of the | 2746 | * Be lazy and only check for valid flags here, keeping it out of the |
2747 | * critical path in kmem_cache_alloc(). | 2747 | * critical path in kmem_cache_alloc(). |
2748 | */ | 2748 | */ |
2749 | BUG_ON(flags & ~(GFP_DMA | GFP_LEVEL_MASK)); | 2749 | BUG_ON(flags & ~(GFP_DMA | __GFP_ZERO | GFP_LEVEL_MASK)); |
2750 | 2750 | ||
2751 | local_flags = (flags & GFP_LEVEL_MASK); | 2751 | local_flags = (flags & GFP_LEVEL_MASK); |
2752 | /* Take the l3 list lock to change the colour_next on this node */ | 2752 | /* Take the l3 list lock to change the colour_next on this node */ |
@@ -3392,6 +3392,9 @@ __cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid, | |||
3392 | local_irq_restore(save_flags); | 3392 | local_irq_restore(save_flags); |
3393 | ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, caller); | 3393 | ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, caller); |
3394 | 3394 | ||
3395 | if (unlikely((flags & __GFP_ZERO) && ptr)) | ||
3396 | memset(ptr, 0, obj_size(cachep)); | ||
3397 | |||
3395 | return ptr; | 3398 | return ptr; |
3396 | } | 3399 | } |
3397 | 3400 | ||
@@ -3443,6 +3446,9 @@ __cache_alloc(struct kmem_cache *cachep, gfp_t flags, void *caller) | |||
3443 | objp = cache_alloc_debugcheck_after(cachep, flags, objp, caller); | 3446 | objp = cache_alloc_debugcheck_after(cachep, flags, objp, caller); |
3444 | prefetchw(objp); | 3447 | prefetchw(objp); |
3445 | 3448 | ||
3449 | if (unlikely((flags & __GFP_ZERO) && objp)) | ||
3450 | memset(objp, 0, obj_size(cachep)); | ||
3451 | |||
3446 | return objp; | 3452 | return objp; |
3447 | } | 3453 | } |
3448 | 3454 | ||
@@ -334,6 +334,8 @@ static void *slob_alloc(size_t size, gfp_t gfp, int align, int node) | |||
334 | BUG_ON(!b); | 334 | BUG_ON(!b); |
335 | spin_unlock_irqrestore(&slob_lock, flags); | 335 | spin_unlock_irqrestore(&slob_lock, flags); |
336 | } | 336 | } |
337 | if (unlikely((gfp & __GFP_ZERO) && b)) | ||
338 | memset(b, 0, size); | ||
337 | return b; | 339 | return b; |
338 | } | 340 | } |
339 | 341 | ||
@@ -1077,7 +1077,7 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node) | |||
1077 | void *last; | 1077 | void *last; |
1078 | void *p; | 1078 | void *p; |
1079 | 1079 | ||
1080 | BUG_ON(flags & ~(GFP_DMA | GFP_LEVEL_MASK)); | 1080 | BUG_ON(flags & ~(GFP_DMA | __GFP_ZERO | GFP_LEVEL_MASK)); |
1081 | 1081 | ||
1082 | if (flags & __GFP_WAIT) | 1082 | if (flags & __GFP_WAIT) |
1083 | local_irq_enable(); | 1083 | local_irq_enable(); |
@@ -1540,7 +1540,7 @@ debug: | |||
1540 | * Otherwise we can simply pick the next object from the lockless free list. | 1540 | * Otherwise we can simply pick the next object from the lockless free list. |
1541 | */ | 1541 | */ |
1542 | static void __always_inline *slab_alloc(struct kmem_cache *s, | 1542 | static void __always_inline *slab_alloc(struct kmem_cache *s, |
1543 | gfp_t gfpflags, int node, void *addr) | 1543 | gfp_t gfpflags, int node, void *addr, int length) |
1544 | { | 1544 | { |
1545 | struct page *page; | 1545 | struct page *page; |
1546 | void **object; | 1546 | void **object; |
@@ -1558,19 +1558,25 @@ static void __always_inline *slab_alloc(struct kmem_cache *s, | |||
1558 | page->lockless_freelist = object[page->offset]; | 1558 | page->lockless_freelist = object[page->offset]; |
1559 | } | 1559 | } |
1560 | local_irq_restore(flags); | 1560 | local_irq_restore(flags); |
1561 | |||
1562 | if (unlikely((gfpflags & __GFP_ZERO) && object)) | ||
1563 | memset(object, 0, length); | ||
1564 | |||
1561 | return object; | 1565 | return object; |
1562 | } | 1566 | } |
1563 | 1567 | ||
1564 | void *kmem_cache_alloc(struct kmem_cache *s, gfp_t gfpflags) | 1568 | void *kmem_cache_alloc(struct kmem_cache *s, gfp_t gfpflags) |
1565 | { | 1569 | { |
1566 | return slab_alloc(s, gfpflags, -1, __builtin_return_address(0)); | 1570 | return slab_alloc(s, gfpflags, -1, |
1571 | __builtin_return_address(0), s->objsize); | ||
1567 | } | 1572 | } |
1568 | EXPORT_SYMBOL(kmem_cache_alloc); | 1573 | EXPORT_SYMBOL(kmem_cache_alloc); |
1569 | 1574 | ||
1570 | #ifdef CONFIG_NUMA | 1575 | #ifdef CONFIG_NUMA |
1571 | void *kmem_cache_alloc_node(struct kmem_cache *s, gfp_t gfpflags, int node) | 1576 | void *kmem_cache_alloc_node(struct kmem_cache *s, gfp_t gfpflags, int node) |
1572 | { | 1577 | { |
1573 | return slab_alloc(s, gfpflags, node, __builtin_return_address(0)); | 1578 | return slab_alloc(s, gfpflags, node, |
1579 | __builtin_return_address(0), s->objsize); | ||
1574 | } | 1580 | } |
1575 | EXPORT_SYMBOL(kmem_cache_alloc_node); | 1581 | EXPORT_SYMBOL(kmem_cache_alloc_node); |
1576 | #endif | 1582 | #endif |
@@ -2318,7 +2324,7 @@ void *__kmalloc(size_t size, gfp_t flags) | |||
2318 | if (ZERO_OR_NULL_PTR(s)) | 2324 | if (ZERO_OR_NULL_PTR(s)) |
2319 | return s; | 2325 | return s; |
2320 | 2326 | ||
2321 | return slab_alloc(s, flags, -1, __builtin_return_address(0)); | 2327 | return slab_alloc(s, flags, -1, __builtin_return_address(0), size); |
2322 | } | 2328 | } |
2323 | EXPORT_SYMBOL(__kmalloc); | 2329 | EXPORT_SYMBOL(__kmalloc); |
2324 | 2330 | ||
@@ -2330,7 +2336,7 @@ void *__kmalloc_node(size_t size, gfp_t flags, int node) | |||
2330 | if (ZERO_OR_NULL_PTR(s)) | 2336 | if (ZERO_OR_NULL_PTR(s)) |
2331 | return s; | 2337 | return s; |
2332 | 2338 | ||
2333 | return slab_alloc(s, flags, node, __builtin_return_address(0)); | 2339 | return slab_alloc(s, flags, node, __builtin_return_address(0), size); |
2334 | } | 2340 | } |
2335 | EXPORT_SYMBOL(__kmalloc_node); | 2341 | EXPORT_SYMBOL(__kmalloc_node); |
2336 | #endif | 2342 | #endif |
@@ -2643,7 +2649,7 @@ void *kmem_cache_zalloc(struct kmem_cache *s, gfp_t flags) | |||
2643 | { | 2649 | { |
2644 | void *x; | 2650 | void *x; |
2645 | 2651 | ||
2646 | x = slab_alloc(s, flags, -1, __builtin_return_address(0)); | 2652 | x = slab_alloc(s, flags, -1, __builtin_return_address(0), 0); |
2647 | if (x) | 2653 | if (x) |
2648 | memset(x, 0, s->objsize); | 2654 | memset(x, 0, s->objsize); |
2649 | return x; | 2655 | return x; |
@@ -2693,7 +2699,7 @@ void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, void *caller) | |||
2693 | if (ZERO_OR_NULL_PTR(s)) | 2699 | if (ZERO_OR_NULL_PTR(s)) |
2694 | return s; | 2700 | return s; |
2695 | 2701 | ||
2696 | return slab_alloc(s, gfpflags, -1, caller); | 2702 | return slab_alloc(s, gfpflags, -1, caller, size); |
2697 | } | 2703 | } |
2698 | 2704 | ||
2699 | void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags, | 2705 | void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags, |
@@ -2704,7 +2710,7 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags, | |||
2704 | if (ZERO_OR_NULL_PTR(s)) | 2710 | if (ZERO_OR_NULL_PTR(s)) |
2705 | return s; | 2711 | return s; |
2706 | 2712 | ||
2707 | return slab_alloc(s, gfpflags, node, caller); | 2713 | return slab_alloc(s, gfpflags, node, caller, size); |
2708 | } | 2714 | } |
2709 | 2715 | ||
2710 | #if defined(CONFIG_SYSFS) && defined(CONFIG_SLUB_DEBUG) | 2716 | #if defined(CONFIG_SYSFS) && defined(CONFIG_SLUB_DEBUG) |