2005-04-17 06:20:36 +08:00
|
|
|
/*
|
2006-12-13 16:34:23 +08:00
|
|
|
* Written by Mark Hemment, 1996 (markhe@nextd.demon.co.uk).
|
|
|
|
*
|
|
|
|
* (C) SGI 2006, Christoph Lameter <clameter@sgi.com>
|
|
|
|
* Cleaned up and restructured to ease the addition of alternative
|
|
|
|
* implementations of SLAB allocators.
|
2005-04-17 06:20:36 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _LINUX_SLAB_H
|
|
|
|
#define _LINUX_SLAB_H
|
|
|
|
|
2006-12-07 12:33:22 +08:00
|
|
|
#ifdef __KERNEL__
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2006-12-07 12:33:22 +08:00
|
|
|
#include <linux/gfp.h>
|
|
|
|
#include <linux/types.h>
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2006-12-13 16:34:23 +08:00
|
|
|
/*
|
|
|
|
* Flags to pass to kmem_cache_create().
|
|
|
|
* The ones marked DEBUG are only valid if CONFIG_SLAB_DEBUG is set.
|
2005-04-17 06:20:36 +08:00
|
|
|
*/
|
2006-12-13 16:34:24 +08:00
|
|
|
#define SLAB_DEBUG_FREE 0x00000100UL /* DEBUG: Perform (expensive) checks on free */
|
|
|
|
#define SLAB_RED_ZONE 0x00000400UL /* DEBUG: Red zone objs in a cache */
|
|
|
|
#define SLAB_POISON 0x00000800UL /* DEBUG: Poison objects */
|
|
|
|
#define SLAB_HWCACHE_ALIGN 0x00002000UL /* Align objs on cache lines */
|
2006-12-13 16:34:23 +08:00
|
|
|
#define SLAB_CACHE_DMA 0x00004000UL /* Use GFP_DMA memory */
|
|
|
|
#define SLAB_STORE_USER 0x00010000UL /* DEBUG: Store the last owner for bug hunting */
|
|
|
|
#define SLAB_RECLAIM_ACCOUNT 0x00020000UL /* Objects are reclaimable */
|
|
|
|
#define SLAB_PANIC 0x00040000UL /* Panic if kmem_cache_create() fails */
|
|
|
|
#define SLAB_DESTROY_BY_RCU 0x00080000UL /* Defer freeing slabs to RCU */
|
[PATCH] cpuset memory spread slab cache implementation
Provide the slab cache infrastructure to support cpuset memory spreading.
See the previous patches, cpuset_mem_spread, for an explanation of cpuset
memory spreading.
This patch provides a slab cache SLAB_MEM_SPREAD flag. If set in the
kmem_cache_create() call defining a slab cache, then any task marked with the
process state flag PF_MEMSPREAD will spread memory page allocations for that
cache over all the allowed nodes, instead of preferring the local (faulting)
node.
On systems not configured with CONFIG_NUMA, this results in no change to the
page allocation code path for slab caches.
On systems with cpusets configured in the kernel, but the "memory_spread"
cpuset option not enabled for the current tasks cpuset, this adds a call to a
cpuset routine and failed bit test of the processor state flag PF_SPREAD_SLAB.
For tasks so marked, a second inline test is done for the slab cache flag
SLAB_MEM_SPREAD, and if that is set and if the allocation is not
in_interrupt(), this adds a call to to a cpuset routine that computes which of
the tasks mems_allowed nodes should be preferred for this allocation.
==> This patch adds another hook into the performance critical
code path to allocating objects from the slab cache, in the
____cache_alloc() chunk, below. The next patch optimizes this
hook, reducing the impact of the combined mempolicy plus memory
spreading hooks on this critical code path to a single check
against the tasks task_struct flags word.
This patch provides the generic slab flags and logic needed to apply memory
spreading to a particular slab.
A subsequent patch will mark a few specific slab caches for this placement
policy.
Signed-off-by: Paul Jackson <pj@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-03-24 19:16:07 +08:00
|
|
|
#define SLAB_MEM_SPREAD 0x00100000UL /* Spread some memory over cpuset */
|
2007-05-07 05:49:36 +08:00
|
|
|
#define SLAB_TRACE 0x00200000UL /* Trace allocations and frees */
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2007-07-17 19:03:22 +08:00
|
|
|
/*
|
|
|
|
* 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)
|
|
|
|
|
2006-12-13 16:34:23 +08:00
|
|
|
/*
|
|
|
|
* struct kmem_cache related prototypes
|
|
|
|
*/
|
|
|
|
void __init kmem_cache_init(void);
|
2007-05-07 05:49:36 +08:00
|
|
|
int slab_is_available(void);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2006-12-13 16:34:23 +08:00
|
|
|
struct kmem_cache *kmem_cache_create(const char *, size_t, size_t,
|
2006-12-07 12:32:59 +08:00
|
|
|
unsigned long,
|
|
|
|
void (*)(void *, struct kmem_cache *, unsigned long),
|
|
|
|
void (*)(void *, struct kmem_cache *, unsigned long));
|
2006-12-13 16:34:23 +08:00
|
|
|
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 *);
|
2006-12-13 16:34:24 +08:00
|
|
|
int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr);
|
2006-12-13 16:34:23 +08:00
|
|
|
|
2007-05-07 05:49:57 +08:00
|
|
|
/*
|
|
|
|
* Please use this macro to create slab caches. Simply specify the
|
|
|
|
* name of the structure and maybe some flags that are listed above.
|
|
|
|
*
|
|
|
|
* The alignment of the struct determines object alignment. If you
|
|
|
|
* f.e. add ____cacheline_aligned_in_smp to the struct declaration
|
|
|
|
* then the objects will be properly aligned in SMP configurations.
|
|
|
|
*/
|
|
|
|
#define KMEM_CACHE(__struct, __flags) kmem_cache_create(#__struct,\
|
|
|
|
sizeof(struct __struct), __alignof__(struct __struct),\
|
|
|
|
(__flags), NULL, NULL)
|
|
|
|
|
2007-05-17 13:11:01 +08:00
|
|
|
/*
|
|
|
|
* The largest kmalloc size supported by the slab allocators is
|
|
|
|
* 32 megabyte (2^25) or the maximum allocatable page order if that is
|
|
|
|
* less than 32 MB.
|
|
|
|
*
|
|
|
|
* WARNING: Its not easy to increase this value since the allocators have
|
|
|
|
* to do various tricks to work around compiler limitations in order to
|
|
|
|
* ensure proper constant folding.
|
|
|
|
*/
|
2007-06-24 08:16:43 +08:00
|
|
|
#define KMALLOC_SHIFT_HIGH ((MAX_ORDER + PAGE_SHIFT - 1) <= 25 ? \
|
|
|
|
(MAX_ORDER + PAGE_SHIFT - 1) : 25)
|
2007-05-17 13:11:01 +08:00
|
|
|
|
|
|
|
#define KMALLOC_MAX_SIZE (1UL << KMALLOC_SHIFT_HIGH)
|
|
|
|
#define KMALLOC_MAX_ORDER (KMALLOC_SHIFT_HIGH - PAGE_SHIFT)
|
|
|
|
|
2006-12-13 16:34:23 +08:00
|
|
|
/*
|
|
|
|
* Common kmalloc functions provided by all allocators
|
|
|
|
*/
|
|
|
|
void *__kzalloc(size_t, gfp_t);
|
2007-05-07 05:48:40 +08:00
|
|
|
void * __must_check krealloc(const void *, size_t, gfp_t);
|
2006-12-13 16:34:23 +08:00
|
|
|
void kfree(const void *);
|
2007-05-07 05:48:40 +08:00
|
|
|
size_t ksize(const void *);
|
2006-12-13 16:34:23 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* kcalloc - allocate memory for an array. The memory is set to zero.
|
|
|
|
* @n: number of elements.
|
|
|
|
* @size: element size.
|
|
|
|
* @flags: the type of memory to allocate.
|
2006-06-23 17:03:48 +08:00
|
|
|
*
|
|
|
|
* The @flags argument may be one of:
|
|
|
|
*
|
|
|
|
* %GFP_USER - Allocate memory on behalf of user. May sleep.
|
|
|
|
*
|
|
|
|
* %GFP_KERNEL - Allocate normal kernel ram. May sleep.
|
|
|
|
*
|
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 <clameter@sgi.com>
Acked-by: Matt Mackall <mpm@selenic.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Acked-by: Nick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-07-16 14:38:22 +08:00
|
|
|
* %GFP_ATOMIC - Allocation will not sleep. May use emergency pools.
|
2006-06-23 17:03:48 +08:00
|
|
|
* For example, use this inside interrupt handlers.
|
|
|
|
*
|
|
|
|
* %GFP_HIGHUSER - Allocate pages from high memory.
|
|
|
|
*
|
|
|
|
* %GFP_NOIO - Do not do any I/O at all while trying to get memory.
|
|
|
|
*
|
|
|
|
* %GFP_NOFS - Do not make any fs calls while trying to get memory.
|
|
|
|
*
|
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 <clameter@sgi.com>
Acked-by: Matt Mackall <mpm@selenic.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Acked-by: Nick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-07-16 14:38:22 +08:00
|
|
|
* %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.
|
|
|
|
*
|
2006-06-23 17:03:48 +08:00
|
|
|
* 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_HIGH - This allocation has high priority and may use emergency pools.
|
|
|
|
*
|
|
|
|
* %__GFP_NOFAIL - Indicate that this allocation is in no way allowed to fail
|
|
|
|
* (think twice before using).
|
|
|
|
*
|
|
|
|
* %__GFP_NORETRY - If memory is not immediately available,
|
|
|
|
* then give up at once.
|
|
|
|
*
|
|
|
|
* %__GFP_NOWARN - If allocation fails, don't issue any warnings.
|
|
|
|
*
|
|
|
|
* %__GFP_REPEAT - If allocation fails initially, try once more before failing.
|
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 <clameter@sgi.com>
Acked-by: Matt Mackall <mpm@selenic.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Acked-by: Nick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-07-16 14:38:22 +08:00
|
|
|
*
|
|
|
|
* 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.
|
2006-06-23 17:03:48 +08:00
|
|
|
*/
|
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 <clameter@sgi.com>
Acked-by: Matt Mackall <mpm@selenic.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Acked-by: Nick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-07-16 14:38:22 +08:00
|
|
|
static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
|
2005-04-17 06:20:36 +08:00
|
|
|
{
|
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 <clameter@sgi.com>
Acked-by: Matt Mackall <mpm@selenic.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Acked-by: Nick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-07-16 14:38:22 +08:00
|
|
|
if (n != 0 && size > ULONG_MAX / n)
|
|
|
|
return NULL;
|
|
|
|
return __kzalloc(n * size, flags);
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
|
|
|
|
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 <clameter@sgi.com>
Acked-by: Matt Mackall <mpm@selenic.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Acked-by: Nick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-07-16 14:38:22 +08:00
|
|
|
/*
|
|
|
|
* 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.
|
2006-12-13 16:34:23 +08:00
|
|
|
*/
|
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 <clameter@sgi.com>
Acked-by: Matt Mackall <mpm@selenic.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Acked-by: Nick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-07-16 14:38:22 +08:00
|
|
|
#ifdef CONFIG_SLUB
|
|
|
|
#include <linux/slub_def.h>
|
|
|
|
#elif defined(CONFIG_SLOB)
|
|
|
|
#include <linux/slob_def.h>
|
|
|
|
#else
|
|
|
|
#include <linux/slab_def.h>
|
2006-12-13 16:34:23 +08:00
|
|
|
#endif
|
|
|
|
|
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 <clameter@sgi.com>
Acked-by: Matt Mackall <mpm@selenic.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Acked-by: Nick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-07-16 14:38:22 +08:00
|
|
|
#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.
|
|
|
|
*/
|
2006-12-13 16:34:24 +08:00
|
|
|
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);
|
|
|
|
}
|
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 <clameter@sgi.com>
Acked-by: Matt Mackall <mpm@selenic.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Acked-by: Nick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-07-16 14:38:22 +08:00
|
|
|
|
|
|
|
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 */
|
2006-12-13 16:34:24 +08:00
|
|
|
|
2006-10-04 17:15:25 +08:00
|
|
|
/*
|
|
|
|
* kmalloc_track_caller is a special version of kmalloc that records the
|
|
|
|
* calling function of the routine calling it for slab leak tracking instead
|
|
|
|
* of just the calling function (confusing, eh?).
|
|
|
|
* It's useful when the call to kmalloc comes from a widely-used standard
|
|
|
|
* allocator where we care about the real place the memory allocation
|
|
|
|
* request comes from.
|
|
|
|
*/
|
2007-05-07 05:49:36 +08:00
|
|
|
#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_SLUB)
|
2006-10-04 17:15:25 +08:00
|
|
|
extern void *__kmalloc_track_caller(size_t, gfp_t, void*);
|
|
|
|
#define kmalloc_track_caller(size, flags) \
|
|
|
|
__kmalloc_track_caller(size, flags, __builtin_return_address(0))
|
2006-12-13 16:34:23 +08:00
|
|
|
#else
|
|
|
|
#define kmalloc_track_caller(size, flags) \
|
|
|
|
__kmalloc(size, flags)
|
|
|
|
#endif /* DEBUG_SLAB */
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2005-05-01 23:58:38 +08:00
|
|
|
#ifdef CONFIG_NUMA
|
2006-12-07 12:32:30 +08:00
|
|
|
/*
|
|
|
|
* kmalloc_node_track_caller is a special version of kmalloc_node that
|
|
|
|
* records the calling function of the routine calling it for slab leak
|
|
|
|
* tracking instead of just the calling function (confusing, eh?).
|
|
|
|
* It's useful when the call to kmalloc_node comes from a widely-used
|
|
|
|
* standard allocator where we care about the real place the memory
|
|
|
|
* allocation request comes from.
|
|
|
|
*/
|
2007-05-07 05:49:36 +08:00
|
|
|
#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_SLUB)
|
2006-12-07 12:32:30 +08:00
|
|
|
extern void *__kmalloc_node_track_caller(size_t, gfp_t, int, void *);
|
|
|
|
#define kmalloc_node_track_caller(size, flags, node) \
|
|
|
|
__kmalloc_node_track_caller(size, flags, node, \
|
|
|
|
__builtin_return_address(0))
|
2006-12-13 16:34:23 +08:00
|
|
|
#else
|
|
|
|
#define kmalloc_node_track_caller(size, flags, node) \
|
|
|
|
__kmalloc_node(size, flags, node)
|
2006-12-07 12:32:30 +08:00
|
|
|
#endif
|
2006-12-13 16:34:23 +08:00
|
|
|
|
2006-12-07 12:32:30 +08:00
|
|
|
#else /* CONFIG_NUMA */
|
|
|
|
|
|
|
|
#define kmalloc_node_track_caller(size, flags, node) \
|
|
|
|
kmalloc_track_caller(size, flags)
|
2005-05-01 23:58:38 +08:00
|
|
|
|
2006-12-13 16:34:24 +08:00
|
|
|
#endif /* DEBUG_SLAB */
|
2006-01-08 17:01:45 +08:00
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
#endif /* __KERNEL__ */
|
|
|
|
#endif /* _LINUX_SLAB_H */
|