From 698827fa9f45019df1609bb686bc51c94e127fbc Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Sun, 15 Jul 2007 23:38:06 -0700 Subject: Remove the deprecated "kmem_cache_t" typedef from slab.h. Given that there is no remaining usage of the deprecated kmem_cache_t typedef anywhere in the tree, remove that typedef. Signed-off-by: Robert P. J. Day Acked-by: Pekka Enberg Acked-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/slab.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux/slab.h') diff --git a/include/linux/slab.h b/include/linux/slab.h index cebcd3833c76..cd6ab658553f 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -14,8 +14,6 @@ #include #include -typedef struct kmem_cache kmem_cache_t __deprecated; - /* * Flags to pass to kmem_cache_create(). * The ones marked DEBUG are only valid if CONFIG_SLAB_DEBUG is set. -- cgit v1.2.3 From 6193a2ff180920f84ee06977165ebf32431fc2d2 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sun, 15 Jul 2007 23:38:22 -0700 Subject: slob: initial NUMA support This adds preliminary NUMA support to SLOB, primarily aimed at systems with small nodes (tested all the way down to a 128kB SRAM block), whether asymmetric or otherwise. We follow the same conventions as SLAB/SLUB, preferring current node placement for new pages, or with explicit placement, if a node has been specified. Presently on UP NUMA this has the side-effect of preferring node#0 allocations (since numa_node_id() == 0, though this could be reworked if we could hand off a pfn to determine node placement), so single-CPU NUMA systems will want to place smaller nodes further out in terms of node id. Once a page has been bound to a node (via explicit node id typing), we only do block allocations from partial free pages that have a matching node id in the page flags. The current implementation does have some scalability problems, in that all partial free pages are tracked in the global freelist (with contention due to the single spinlock). However, these are things that are being reworked for SMP scalability first, while things like per-node freelists can easily be built on top of this sort of functionality once it's been added. More background can be found in: http://marc.info/?l=linux-mm&m=118117916022379&w=2 http://marc.info/?l=linux-mm&m=118170446306199&w=2 http://marc.info/?l=linux-mm&m=118187859420048&w=2 and subsequent threads. Acked-by: Christoph Lameter Acked-by: Matt Mackall Signed-off-by: Paul Mundt Acked-by: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/slab.h | 126 +++++++++++++++++++++++++-------------------------- 1 file changed, 62 insertions(+), 64 deletions(-) (limited to 'include/linux/slab.h') diff --git a/include/linux/slab.h b/include/linux/slab.h index cd6ab658553f..27402fea9b79 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -42,7 +42,6 @@ struct kmem_cache *kmem_cache_create(const char *, size_t, size_t, void (*)(void *, struct kmem_cache *, unsigned long)); void kmem_cache_destroy(struct kmem_cache *); int kmem_cache_shrink(struct kmem_cache *); -void *kmem_cache_alloc(struct kmem_cache *, gfp_t); void *kmem_cache_zalloc(struct kmem_cache *, gfp_t); void kmem_cache_free(struct kmem_cache *, void *); unsigned int kmem_cache_size(struct kmem_cache *); @@ -61,16 +60,6 @@ int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr); sizeof(struct __struct), __alignof__(struct __struct),\ (__flags), NULL, NULL) -#ifdef CONFIG_NUMA -extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); -#else -static inline void *kmem_cache_alloc_node(struct kmem_cache *cachep, - gfp_t flags, int node) -{ - return kmem_cache_alloc(cachep, flags); -} -#endif - /* * The largest kmalloc size supported by the slab allocators is * 32 megabyte (2^25) or the maximum allocatable page order if that is @@ -89,7 +78,6 @@ static inline void *kmem_cache_alloc_node(struct kmem_cache *cachep, /* * Common kmalloc functions provided by all allocators */ -void *__kmalloc(size_t, gfp_t); void *__kzalloc(size_t, gfp_t); void * __must_check krealloc(const void *, size_t, gfp_t); void kfree(const void *); @@ -100,40 +88,6 @@ size_t ksize(const void *); * @n: number of elements. * @size: element size. * @flags: the type of memory to allocate. - */ -static inline void *kcalloc(size_t n, size_t size, gfp_t flags) -{ - if (n != 0 && size > ULONG_MAX / n) - return NULL; - return __kzalloc(n * size, flags); -} - -/* - * Allocator specific definitions. These are mainly used to establish optimized - * ways to convert kmalloc() calls to kmem_cache_alloc() invocations by selecting - * the appropriate general cache at compile time. - */ - -#if defined(CONFIG_SLAB) || defined(CONFIG_SLUB) -#ifdef CONFIG_SLUB -#include -#else -#include -#endif /* !CONFIG_SLUB */ -#else - -/* - * Fallback definitions for an allocator not wanting to provide - * its own optimized kmalloc definitions (like SLOB). - */ - -/** - * kmalloc - allocate memory - * @size: how many bytes of memory are required. - * @flags: the type of memory to allocate. - * - * kmalloc is the normal method of allocating memory - * in the kernel. * * The @flags argument may be one of: * @@ -141,7 +95,7 @@ static inline void *kcalloc(size_t n, size_t size, gfp_t flags) * * %GFP_KERNEL - Allocate normal kernel ram. May sleep. * - * %GFP_ATOMIC - Allocation will not sleep. + * %GFP_ATOMIC - Allocation will not sleep. May use emergency pools. * For example, use this inside interrupt handlers. * * %GFP_HIGHUSER - Allocate pages from high memory. @@ -150,18 +104,22 @@ static inline void *kcalloc(size_t n, size_t size, gfp_t flags) * * %GFP_NOFS - Do not make any fs calls while trying to get memory. * + * %GFP_NOWAIT - Allocation will not sleep. + * + * %GFP_THISNODE - Allocate node-local memory only. + * + * %GFP_DMA - Allocation suitable for DMA. + * Should only be used for kmalloc() caches. Otherwise, use a + * slab created with SLAB_DMA. + * * Also it is possible to set different flags by OR'ing * in one or more of the following additional @flags: * * %__GFP_COLD - Request cache-cold pages instead of * trying to return cache-warm pages. * - * %__GFP_DMA - Request memory from the DMA-capable zone. - * * %__GFP_HIGH - This allocation has high priority and may use emergency pools. * - * %__GFP_HIGHMEM - Allocated memory may be from highmem. - * * %__GFP_NOFAIL - Indicate that this allocation is in no way allowed to fail * (think twice before using). * @@ -171,24 +129,57 @@ static inline void *kcalloc(size_t n, size_t size, gfp_t flags) * %__GFP_NOWARN - If allocation fails, don't issue any warnings. * * %__GFP_REPEAT - If allocation fails initially, try once more before failing. + * + * There are other flags available as well, but these are not intended + * for general use, and so are not documented here. For a full list of + * potential flags, always refer to linux/gfp.h. */ -static inline void *kmalloc(size_t size, gfp_t flags) +static inline void *kcalloc(size_t n, size_t size, gfp_t flags) { - return __kmalloc(size, flags); + if (n != 0 && size > ULONG_MAX / n) + return NULL; + return __kzalloc(n * size, flags); } -/** - * kzalloc - allocate memory. The memory is set to zero. - * @size: how many bytes of memory are required. - * @flags: the type of memory to allocate (see kmalloc). +/* + * Allocator specific definitions. These are mainly used to establish optimized + * ways to convert kmalloc() calls to kmem_cache_alloc() invocations by + * selecting the appropriate general cache at compile time. + * + * Allocators must define at least: + * + * kmem_cache_alloc() + * __kmalloc() + * kmalloc() + * kzalloc() + * + * Those wishing to support NUMA must also define: + * + * kmem_cache_alloc_node() + * kmalloc_node() + * + * See each allocator definition file for additional comments and + * implementation notes. */ -static inline void *kzalloc(size_t size, gfp_t flags) -{ - return __kzalloc(size, flags); -} +#ifdef CONFIG_SLUB +#include +#elif defined(CONFIG_SLOB) +#include +#else +#include #endif -#ifndef CONFIG_NUMA +#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 kcalloc). + * @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); @@ -198,7 +189,15 @@ static inline void *__kmalloc_node(size_t size, gfp_t flags, int node) { return __kmalloc(size, flags); } -#endif /* !CONFIG_NUMA */ + +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 @@ -245,4 +244,3 @@ extern void *__kmalloc_node_track_caller(size_t, gfp_t, int, void *); #endif /* __KERNEL__ */ #endif /* _LINUX_SLAB_H */ - -- cgit v1.2.3 From 6cb8f91320d3e720351c21741da795fed580b21b Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Tue, 17 Jul 2007 04:03:22 -0700 Subject: Slab allocators: consistent ZERO_SIZE_PTR support and NULL result semantics Define ZERO_OR_NULL_PTR macro to be able to remove the checks from the allocators. Move ZERO_SIZE_PTR related stuff into slab.h. Make ZERO_SIZE_PTR work for all slab allocators and get rid of the WARN_ON_ONCE(size == 0) that is still remaining in SLAB. Make slub return NULL like the other allocators if a too large memory segment is requested via __kmalloc. Signed-off-by: Christoph Lameter Acked-by: Pekka Enberg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/slab.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include/linux/slab.h') diff --git a/include/linux/slab.h b/include/linux/slab.h index 27402fea9b79..0289ec89300a 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -30,6 +30,19 @@ #define SLAB_MEM_SPREAD 0x00100000UL /* Spread some memory over cpuset */ #define SLAB_TRACE 0x00200000UL /* Trace allocations and frees */ +/* + * ZERO_SIZE_PTR will be returned for zero sized kmalloc requests. + * + * Dereferencing ZERO_SIZE_PTR will lead to a distinct access fault. + * + * ZERO_SIZE_PTR can be passed to kfree though in the same way that NULL can. + * Both make kfree a no-op. + */ +#define ZERO_SIZE_PTR ((void *)16) + +#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) < \ + (unsigned long)ZERO_SIZE_PTR) + /* * struct kmem_cache related prototypes */ -- cgit v1.2.3 From 81cda6626178cd55297831296ba8ecedbfd8b52d Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Tue, 17 Jul 2007 04:03:29 -0700 Subject: Slab allocators: Cleanup zeroing allocations It becomes now easy to support the zeroing allocs with generic inline functions in slab.h. Provide inline definitions to allow the continued use of kzalloc, kmem_cache_zalloc etc but remove other definitions of zeroing functions from the slab allocators and util.c. Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/slab.h | 77 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 31 deletions(-) (limited to 'include/linux/slab.h') diff --git a/include/linux/slab.h b/include/linux/slab.h index 0289ec89300a..0e1d0daef6a2 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -55,7 +55,6 @@ struct kmem_cache *kmem_cache_create(const char *, size_t, size_t, void (*)(void *, struct kmem_cache *, unsigned long)); void kmem_cache_destroy(struct kmem_cache *); int kmem_cache_shrink(struct kmem_cache *); -void *kmem_cache_zalloc(struct kmem_cache *, gfp_t); void kmem_cache_free(struct kmem_cache *, void *); unsigned int kmem_cache_size(struct kmem_cache *); const char *kmem_cache_name(struct kmem_cache *); @@ -91,11 +90,37 @@ int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr); /* * Common kmalloc functions provided by all allocators */ -void *__kzalloc(size_t, gfp_t); void * __must_check krealloc(const void *, size_t, gfp_t); void kfree(const void *); size_t ksize(const void *); +/* + * Allocator specific definitions. These are mainly used to establish optimized + * ways to convert kmalloc() calls to kmem_cache_alloc() invocations by + * selecting the appropriate general cache at compile time. + * + * Allocators must define at least: + * + * kmem_cache_alloc() + * __kmalloc() + * kmalloc() + * + * Those wishing to support NUMA must also define: + * + * kmem_cache_alloc_node() + * kmalloc_node() + * + * See each allocator definition file for additional comments and + * implementation notes. + */ +#ifdef CONFIG_SLUB +#include +#elif defined(CONFIG_SLOB) +#include +#else +#include +#endif + /** * kcalloc - allocate memory for an array. The memory is set to zero. * @n: number of elements. @@ -151,37 +176,9 @@ static inline void *kcalloc(size_t n, size_t size, gfp_t flags) { if (n != 0 && size > ULONG_MAX / n) return NULL; - return __kzalloc(n * size, flags); + return __kmalloc(n * size, flags | __GFP_ZERO); } -/* - * Allocator specific definitions. These are mainly used to establish optimized - * ways to convert kmalloc() calls to kmem_cache_alloc() invocations by - * selecting the appropriate general cache at compile time. - * - * Allocators must define at least: - * - * kmem_cache_alloc() - * __kmalloc() - * kmalloc() - * kzalloc() - * - * Those wishing to support NUMA must also define: - * - * kmem_cache_alloc_node() - * kmalloc_node() - * - * See each allocator definition file for additional comments and - * implementation notes. - */ -#ifdef CONFIG_SLUB -#include -#elif defined(CONFIG_SLOB) -#include -#else -#include -#endif - #if !defined(CONFIG_NUMA) && !defined(CONFIG_SLOB) /** * kmalloc_node - allocate memory from a specific node @@ -255,5 +252,23 @@ extern void *__kmalloc_node_track_caller(size_t, gfp_t, int, void *); #endif /* DEBUG_SLAB */ +/* + * Shortcuts + */ +static inline void *kmem_cache_zalloc(struct kmem_cache *k, gfp_t flags) +{ + return kmem_cache_alloc(k, flags | __GFP_ZERO); +} + +/** + * kzalloc - allocate memory. The memory is set to zero. + * @size: how many bytes of memory are required. + * @flags: the type of memory to allocate (see kmalloc). + */ +static inline void *kzalloc(size_t size, gfp_t flags) +{ + return kmalloc(size, flags | __GFP_ZERO); +} + #endif /* __KERNEL__ */ #endif /* _LINUX_SLAB_H */ -- cgit v1.2.3 From 20c2df83d25c6a95affe6157a4c9cac4cf5ffaac Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 20 Jul 2007 10:11:58 +0900 Subject: mm: Remove slab destructors from kmem_cache_create(). Slab destructors were no longer supported after Christoph's c59def9f222d44bb7e2f0a559f2906191a0862d7 change. They've been BUGs for both slab and slub, and slob never supported them either. This rips out support for the dtor pointer from kmem_cache_create() completely and fixes up every single callsite in the kernel (there were about 224, not including the slab allocator definitions themselves, or the documentation references). Signed-off-by: Paul Mundt --- include/linux/slab.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include/linux/slab.h') diff --git a/include/linux/slab.h b/include/linux/slab.h index 0e1d0daef6a2..7d0ecc1659f0 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -51,7 +51,6 @@ int slab_is_available(void); struct kmem_cache *kmem_cache_create(const char *, size_t, size_t, unsigned long, - void (*)(void *, struct kmem_cache *, unsigned long), void (*)(void *, struct kmem_cache *, unsigned long)); void kmem_cache_destroy(struct kmem_cache *); int kmem_cache_shrink(struct kmem_cache *); @@ -70,7 +69,7 @@ int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr); */ #define KMEM_CACHE(__struct, __flags) kmem_cache_create(#__struct,\ sizeof(struct __struct), __alignof__(struct __struct),\ - (__flags), NULL, NULL) + (__flags), NULL) /* * The largest kmalloc size supported by the slab allocators is -- cgit v1.2.3 From 1d4ec7b1d6f130818f9b62dea3411d9ee2ff6ff6 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 20 Jul 2007 12:13:20 -0700 Subject: Fix ZERO_OR_NULL_PTR(ZERO_SIZE_PTR) The comparison with ZERO_SIZE_PTR in ZERO_OR_NULL_PTR() needs to be <= (not just <) so that ZERO_OR_NULL_PTR(ZERO_SIZE_PTR) is 1. Signed-off-by: Roland Dreier [ Duh! - Linus ] Signed-off-by: Linus Torvalds --- include/linux/slab.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux/slab.h') diff --git a/include/linux/slab.h b/include/linux/slab.h index 7d0ecc1659f0..d859354b9e51 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -40,7 +40,7 @@ */ #define ZERO_SIZE_PTR ((void *)16) -#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) < \ +#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= \ (unsigned long)ZERO_SIZE_PTR) /* -- cgit v1.2.3