[3.12 1/3] Move kmallocXXX functions to common code
Subsystems (3)
A message that is not in the archive (sent off-list or not yet received): [email protected]
The kmalloc* functions of all slab allcoators are similar now so lets move them into slab.h. This requires some function naming changes in slob.
As a results of this patch there is a common set of functions for all allocators. Also means that kmalloc_large() is now available in general to perform large order allocations that go directly via the page allocator. kmalloc_large() can be substituted if kmalloc() throws warnings because of too large allocations.
kmalloc_large() has exactly the same semantics as kmalloc but can only used for allocations > PAGE_SIZE.
include/linux/slab.h +124 -32
@@ -4,6 +4,8 @@* (C) SGI 2006, Christoph Lameter * Cleaned up and restructured to ease the addition of alternative * implementations of SLAB allocators. +* (C) Linux Foundation 2008-2013 +* Unified interface for all slab allocators */ #ifndef _LINUX_SLAB_H
@@ -94,6 +96,7 @@#define ZERO_OR_NULL_PTR (x) ((unsigned long)(x) <= \ (unsigned long)ZERO_SIZE_PTR) +#include <linux/kmemleak.h> struct mem_cgroup ;/*
@@ -289,6 +292,57 @@ static __always_inline int kmalloc_index }#endif /* !CONFIG_SLOB */ +void *__kmalloc (size_t size,gfp_t flags); +void *kmem_cache_alloc (struct kmem_cache *,gfp_t flags); + +#ifdef CONFIG_NUMA +void *__kmalloc_node (size_t size,gfp_t flags,int node); +void *kmem_cache_alloc_node (struct kmem_cache *,gfp_t flags,int node); +#else +static __always_inline void *__kmalloc_node(size_t size, gfp_t flags, int node) +{ +return __kmalloc (size, flags); +} + +static __always_inline void *kmem_cache_alloc_node(struct kmem_cache *s, gfp_t flags, int node) +{ +return kmem_cache_alloc (s, flags); +} +#endif + +#ifdef CONFIG_TRACING +extern void *kmem_cache_alloc_trace (struct kmem_cache *,gfp_t ,size_t ); + +#ifdef CONFIG_NUMA +extern void *kmem_cache_alloc_node_trace (struct kmem_cache *s, +gfp_t gfpflags, +int node,size_t size); +#else +static __always_inline void * +kmem_cache_alloc_node_trace (struct kmem_cache *s, +gfp_t gfpflags, +int node,size_t size) +{ +return kmem_cache_alloc_trace (s, gfpflags, size); +} +#endif /* CONFIG_NUMA */ + +#else /* CONFIG_TRACING */ +static __always_inline void *kmem_cache_alloc_trace(struct kmem_cache *s, +gfp_t flags,size_t size) +{ +return kmem_cache_alloc (s, flags); +} + +static __always_inline void * +kmem_cache_alloc_node_trace (struct kmem_cache *s, +gfp_t gfpflags, +int node,size_t size) +{ +return kmem_cache_alloc_node (s, gfpflags, node); +} +#endif /* CONFIG_TRACING */ +#ifdef CONFIG_SLAB #include <linux/slab_def.h> #endif
@@ -297,10 +351,61 @@ static __always_inline int kmalloc_index#include <linux/slub_def.h> #endif -#ifdef CONFIG_SLOB -#include <linux/slob_def.h> +static __always_inline void * +kmalloc_order (size_t size,gfp_t flags,unsigned int order) +{ +void *ret; + + flags |= (__GFP_COMP | __GFP_KMEMCG); + ret = (void *)__get_free_pages (flags, order); +kmemleak_alloc (ret, size,1 , flags); +return ret; +} + +#ifdef CONFIG_TRACING +extern void *kmalloc_order_trace (size_t size,gfp_t flags,unsigned int order); +#else +static __always_inline void * +kmalloc_order_trace (size_t size,gfp_t flags,unsigned int order) +{ +return kmalloc_order (size, flags, order); +}#endif +static __always_inline void *kmalloc_large(size_t size, gfp_t flags) +{ +unsigned int order =get_order (size); +return kmalloc_order_trace (size, flags, order); +} + +/** +* kmalloc - allocate memory +* @size: how many bytes of memory are required. +* @flags: the type of memory to allocate (see kcalloc). +* +* kmalloc is the normal method of allocating memory +* for objects smaller than page size in the kernel. +*/ +static __always_inline void *kmalloc(size_t size, gfp_t flags) +{ +if (__builtin_constant_p (size)) { +if (size >KMALLOC_MAX_CACHE_SIZE ) +return kmalloc_large (size, flags); +#ifndef CONFIG_SLOB +if (!(flags &GFP_DMA )) { +int index =kmalloc_index (size); + +if (!index) +return ZERO_SIZE_PTR ; + +return kmem_cache_alloc_trace (kmalloc_caches[index], + flags, size); + } +#endif + } +return __kmalloc (size, flags); +} +/* * Determine size used for the nth kmalloc cache. * return size or 0 if a kmalloc cache for that
@@ -321,6 +426,23 @@ static __always_inline int kmalloc_size(return 0 ; } +static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) +{ +#ifndef CONFIG_SLOB +if (__builtin_constant_p (size) && + size <=KMALLOC_MAX_CACHE_SIZE && !(flags &SLAB_CACHE_DMA )) { +int i =kmalloc_index (size); + +if (!i) +return ZERO_SIZE_PTR ; + +return kmem_cache_alloc_node_trace (kmalloc_caches[i], + flags, node, size); + } +#endif +return __kmalloc_node (size, flags, node); +} +/* * Setting ARCH_SLAB_MINALIGN in arch headers allows a different alignment. * Intended for arches that get misalignment faults even for 64 bit integer
@@ -451,36 +573,6 @@ static inline void *kcalloc(size_t n, sireturn kmalloc_array (n, size, flags | __GFP_ZERO); } -#if !defined(CONFIG_NUMA ) && !defined(CONFIG_SLOB ) -/** -* kmalloc_node - allocate memory from a specific node -* @size: how many bytes of memory are required. -* @flags: the type of memory to allocate (see kmalloc). -* @node: node to allocate from. -* -* kmalloc() for non-local nodes, used to allocate from a specific node -* if available. Equivalent to kmalloc() in the non-NUMA single-node -* case. -*/ -static inline void *kmalloc_node (size_t size,gfp_t flags,int node) -{ -return kmalloc (size, flags); -} - -static inline void *__kmalloc_node (size_t size,gfp_t flags,int node) -{ -return __kmalloc (size, flags); -} - -void *kmem_cache_alloc (struct kmem_cache *,gfp_t ); - -static inline void *kmem_cache_alloc_node (struct kmem_cache *cachep, -gfp_t flags,int node) -{ -return kmem_cache_alloc (cachep, flags); -} -#endif /* !CONFIG_NUMA && !CONFIG_SLOB */ -/* * kmalloc_track_caller is a special version of kmalloc that records the * calling function of the routine calling it for slab leak tracking instead
include/linux/slub_def.h +0 -97
115 lines not on this page · raw message
include/linux/slab_def.h +0 -106
116 lines not on this page · raw message
include/linux/slob_def.h deleted +0 -31
@@ -1,31 +0,0 @@ -#ifndef __LINUX_SLOB_DEF_H -#define __LINUX_SLOB_DEF_H - -#include <linux/numa.h> - -void *kmem_cache_alloc_node (struct kmem_cache *,gfp_t flags,int node); - -static __always_inline void *kmem_cache_alloc(struct kmem_cache *cachep, -gfp_t flags) -{ -return kmem_cache_alloc_node (cachep, flags,NUMA_NO_NODE ); -} - -void *__kmalloc_node (size_t size,gfp_t flags,int node); - -static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) -{ -return __kmalloc_node (size, flags, node); -} - -static __always_inline void *kmalloc(size_t size, gfp_t flags) -{ -return __kmalloc_node (size, flags,NUMA_NO_NODE ); -} - -static __always_inline void *__kmalloc(size_t size, gfp_t flags) -{ -return kmalloc (size, flags); -} - -#endif /* __LINUX_SLOB_DEF_H */
mm/slob.c +24 -4
@@ -462,11 +462,11 @@ __do_kmalloc_node(size_t size, gfp_t gfpreturn ret; } -void *__kmalloc_node (size_t size,gfp_t gfp,int node) +void *__kmalloc (size_t size,gfp_t gfp) { -return __do_kmalloc_node (size, gfp, node, _RET_IP_); +return __do_kmalloc_node (size, gfp,NUMA_NO_NODE , _RET_IP_); } -EXPORT_SYMBOL (__kmalloc_node); +EXPORT_SYMBOL (__kmalloc);#ifdef CONFIG_TRACING void *__kmalloc_track_caller (size_t size,gfp_t gfp,unsigned long caller)
@@ -534,7 +534,7 @@ int __kmem_cache_create(struct kmem_cachreturn 0 ; } -void *kmem_cache_alloc_node (struct kmem_cache *c,gfp_t flags,int node) +void *slob_alloc_node (struct kmem_cache *c,gfp_t flags,int node) {void *b;
@@ -560,7 +560,27 @@ void *kmem_cache_alloc_node(struct kmem_kmemleak_alloc_recursive (b, c->size,1 , c->flags, flags);return b; } +EXPORT_SYMBOL (slob_alloc_node); + +void *kmem_cache_alloc (struct kmem_cache *cachep,gfp_t flags) +{ +return slob_alloc_node (cachep, flags,NUMA_NO_NODE ); +} +EXPORT_SYMBOL (kmem_cache_alloc); + +#ifdef CONFIG_NUMA +void *__kmalloc_node (size_t size,gfp_t gfp,int node) +{ +return __do_kmalloc_node (size, gfp, node, _RET_IP_); +} +EXPORT_SYMBOL (__kmalloc_node); + +void *kmem_cache_alloc_node (struct kmem_cache *cachep,gfp_t gfp,int node) +{ +return slob_alloc_node (cachep, gfp, node); +}EXPORT_SYMBOL (kmem_cache_alloc_node); +#endif static void __kmem_cache_free (void *b,int size) {
mm/slab_common.c +10 -0
@@ -19,6 +19,7 @@#include <asm/tlbflush.h> #include <asm/page.h> #include <linux/memcontrol.h> +#include <trace/events/kmem.h> #include "slab.h"
@@ -495,6 +496,15 @@ void __init create_kmalloc_caches(unsign }#endif /* !CONFIG_SLOB */ +#ifdef CONFIG_TRACING +void *kmalloc_order_trace (size_t size,gfp_t flags,unsigned int order) +{ +void *ret =kmalloc_order (size, flags, order); +trace_kmalloc (_RET_IP_, ret, size,PAGE_SIZE << order, flags); +return ret; +} +EXPORT_SYMBOL (kmalloc_order_trace); +#endif #ifdef CONFIG_SLABINFO
mm/slub.c +0 -8
@@ -2434,14 +2434,6 @@ void *kmem_cache_alloc_trace(struct kmem return ret; }EXPORT_SYMBOL (kmem_cache_alloc_trace); - -void *kmalloc_order_trace (size_t size,gfp_t flags,unsigned int order) -{ -void *ret =kmalloc_order (size, flags, order); -trace_kmalloc (_RET_IP_, ret, size,PAGE_SIZE << order, flags); -return ret; -} -EXPORT_SYMBOL (kmalloc_order_trace);#endif #ifdef CONFIG_NUMA
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 10 lines · Christoph Lameter
The kmalloc* functions of all slab allcoators are similar now so lets move them into
slab.h. This requires some function naming changes in slob.As a results of this patch there is a common set of functions for all allocators. Also means that
kmalloc_large()is now available in general to perform large order allocations that go directly via the page allocator.kmalloc_large()can be substituted ifkmalloc()throws warnings because of too large allocations.
Quoted 4 lines
kmalloc_large()has exactly the same semantics as kmalloc but can only used for allocations >PAGE_SIZE.Signed-off-by Christoph Lameter <[email protected]>
I already applied an earlier version that's now breaking linux-next. Can you please send incremental fixes on top of slab/next? I'd prefer not to rebase...
Pekka
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 3 lines · Pekka Enberg
I already applied an earlier version that's now breaking linux-next. Can you please send incremental fixes on top of slab/next? I'd prefer not to rebase...
Ok, I rebased anyway and dropped the broken commits. I'm not happy that this bundles kmalloc_large(), though, so it needs to be taken out for me to merge this.
Pekka
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Christoph Lameter
reviewerQuoted 8 lines · Pekka Enberg
Quoted 3 lines · Pekka Enberg
I already applied an earlier version that's now breaking linux-next. Can you please send incremental fixes on top of slab/next? I'd prefer not to rebase...
Ok, I rebased anyway and dropped the broken commits. I'm not happy that this bundles
kmalloc_large(), though, so it needs to be taken out for me to merge this.
kmalloc_large is already available for slub. I just made it generally available. slob large allocations now also fallback to kmalloc_large. We could just disable it for SLAB?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Christoph Lameter
reviewerQuoted 3 lines · Pekka Enberg
I already applied an earlier version that's now breaking linux-next. Can you please send incremental fixes on top of slab/next? I'd prefer not to rebase...
There is breakage because the first two patches have cross dependencies. That is the main reason for the new patchset.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 8 lines · Christoph Lameter
As a results of this patch there is a common set of functions for all allocators. Also means that
kmalloc_large()is now available in general to perform large order allocations that go directly via the page allocator.kmalloc_large()can be substituted ifkmalloc()throws warnings because of too large allocations.
kmalloc_large()has exactly the same semantics as kmalloc but can only used for allocations >PAGE_SIZE.
The introduction kmalloc_large() needs to happen in a separate patch. What exactly is the benefit of adding the new API, btw? Why don't people just use the page allocator directly?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Christoph Lameter
reviewerQuoted 4 lines · Pekka Enberg
The introduction
kmalloc_large()needs to happen in a separate patch. What exactly is the benefit of adding the new API, btw? Why don't people just use the page allocator directly?
The advantage of kmalloc_large is that is has the same calling convention as kmalloc. get_free_pages() etc require page addresses and return unsigned longs meaning that conversions are required.
kmalloc_large functionality is already in use by slob and slub and therefore is easy to make commonly available.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
[3.12 2/3] slub: remove verify_mem_not_deleted()
In reply to a message not in the archiveI do not see any user for this code in the tree.
include/linux/slub_def.h +0 -13
@@ -98,17 +98,4 @@ struct kmem_cache { struct kmem_cache_node *node[MAX_NUMNODES]; }; -/** -* Calling this on allocated memory will check that the memory -* is expected to be in use, and print warnings if not. -*/ -#ifdef CONFIG_SLUB_DEBUG -extern bool verify_mem_not_deleted (const void *x); -#else -static inline bool verify_mem_not_deleted (const void *x) -{ -return true; -} -#endif -#endif /* _LINUX_SLUB_DEF_H */
mm/slub.c +0 -36
@@ -3308,42 +3308,6 @@ size_t ksize(const void *object) }EXPORT_SYMBOL (ksize); -#ifdef CONFIG_SLUB_DEBUG -bool verify_mem_not_deleted (const void *x) -{ -struct page *page; -void *object = (void *)x; -unsigned long flags; -bool rv; - -if (unlikely (ZERO_OR_NULL_PTR (x))) -return false; - -local_irq_save (flags); - - page =virt_to_head_page (x); -if (unlikely (!PageSlab (page))) { -/* maybe it was from stack? */ - rv = true; - goto out_unlock; - } - -slab_lock (page); -if (on_freelist (page->slab_cache, page, object)) { -object_err (page->slab_cache, page, object,"Object is on free-list" ); - rv = false; - }else { - rv = true; - } -slab_unlock (page); - -out_unlock: -local_irq_restore (flags); -return rv; -} -EXPORT_SYMBOL (verify_mem_not_deleted); -#endif -void kfree (const void *x) {struct page *page;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
[3.12 3/3] seq_file: Use kmalloc_large for page sized allocation
In reply to a message not in the archiveThere is no point in using the slab allocation functions for large page order allocation. Use kmalloc_large().
This fixes the warning about large allocs but it will still cause large contiguous allocs that could fail because of memory fragmentation.
fs/seq_file.c +2 -2
@@ -136,7 +136,7 @@ static int traverse(struct seq_file *m, Eoverflow: m->op->stop (m, p);kfree (m->buf); - m->buf =kmalloc (m->size <<=1 ,GFP_KERNEL ); + m->buf =kmalloc_large (m->size <<=1 ,GFP_KERNEL );return !m->buf ? -ENOMEM : -EAGAIN ; }
@@ -232,7 +232,7 @@ ssize_t seq_read(struct file *file, char goto Fill; m->op->stop (m, p);kfree (m->buf); - m->buf =kmalloc (m->size <<=1 ,GFP_KERNEL ); + m->buf =kmalloc_large (m->size <<=1 ,GFP_KERNEL );if (!m->buf) goto Enomem; m->count =0 ;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>