diff options
author | Christoph Lameter <cl@linux.com> | 2012-11-28 11:23:16 -0500 |
---|---|---|
committer | Pekka Enberg <penberg@kernel.org> | 2012-12-11 05:14:28 -0500 |
commit | 4590685546a374fb0f60682ce0e3a6fd48911d46 (patch) | |
tree | 1287ce1e1633067f8bf2cf9f93f1d6fe8a1f8908 /mm/slab_common.c | |
parent | 2f9baa9fcf8d0a204ca129a671d6086cc100faab (diff) |
mm/sl[aou]b: Common alignment code
Extract the code to do object alignment from the allocators.
Do the alignment calculations in slab_common so that the
__kmem_cache_create functions of the allocators do not have
to deal with alignment.
Signed-off-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
Diffstat (limited to 'mm/slab_common.c')
-rw-r--r-- | mm/slab_common.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/mm/slab_common.c b/mm/slab_common.c index 497b45c25bae..a8e76d79ee65 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c | |||
@@ -73,6 +73,34 @@ static inline int kmem_cache_sanity_check(const char *name, size_t size) | |||
73 | #endif | 73 | #endif |
74 | 74 | ||
75 | /* | 75 | /* |
76 | * Figure out what the alignment of the objects will be given a set of | ||
77 | * flags, a user specified alignment and the size of the objects. | ||
78 | */ | ||
79 | unsigned long calculate_alignment(unsigned long flags, | ||
80 | unsigned long align, unsigned long size) | ||
81 | { | ||
82 | /* | ||
83 | * If the user wants hardware cache aligned objects then follow that | ||
84 | * suggestion if the object is sufficiently large. | ||
85 | * | ||
86 | * The hardware cache alignment cannot override the specified | ||
87 | * alignment though. If that is greater then use it. | ||
88 | */ | ||
89 | if (flags & SLAB_HWCACHE_ALIGN) { | ||
90 | unsigned long ralign = cache_line_size(); | ||
91 | while (size <= ralign / 2) | ||
92 | ralign /= 2; | ||
93 | align = max(align, ralign); | ||
94 | } | ||
95 | |||
96 | if (align < ARCH_SLAB_MINALIGN) | ||
97 | align = ARCH_SLAB_MINALIGN; | ||
98 | |||
99 | return ALIGN(align, sizeof(void *)); | ||
100 | } | ||
101 | |||
102 | |||
103 | /* | ||
76 | * kmem_cache_create - Create a cache. | 104 | * kmem_cache_create - Create a cache. |
77 | * @name: A string which is used in /proc/slabinfo to identify this cache. | 105 | * @name: A string which is used in /proc/slabinfo to identify this cache. |
78 | * @size: The size of objects to be created in this cache. | 106 | * @size: The size of objects to be created in this cache. |
@@ -124,7 +152,7 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size, size_t align | |||
124 | s = kmem_cache_zalloc(kmem_cache, GFP_KERNEL); | 152 | s = kmem_cache_zalloc(kmem_cache, GFP_KERNEL); |
125 | if (s) { | 153 | if (s) { |
126 | s->object_size = s->size = size; | 154 | s->object_size = s->size = size; |
127 | s->align = align; | 155 | s->align = calculate_alignment(flags, align, size); |
128 | s->ctor = ctor; | 156 | s->ctor = ctor; |
129 | s->name = kstrdup(name, GFP_KERNEL); | 157 | s->name = kstrdup(name, GFP_KERNEL); |
130 | if (!s->name) { | 158 | if (!s->name) { |
@@ -211,7 +239,7 @@ void __init create_boot_cache(struct kmem_cache *s, const char *name, size_t siz | |||
211 | 239 | ||
212 | s->name = name; | 240 | s->name = name; |
213 | s->size = s->object_size = size; | 241 | s->size = s->object_size = size; |
214 | s->align = ARCH_KMALLOC_MINALIGN; | 242 | s->align = calculate_alignment(flags, ARCH_KMALLOC_MINALIGN, size); |
215 | err = __kmem_cache_create(s, flags); | 243 | err = __kmem_cache_create(s, flags); |
216 | 244 | ||
217 | if (err) | 245 | if (err) |