diff options
author | Pekka Enberg <penberg@cs.helsinki.fi> | 2006-09-26 02:31:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-26 11:48:48 -0400 |
commit | ca5f9703dffa012cc46166e6206c5a992910e041 (patch) | |
tree | d1fb19019db14465eb8674aa1b13c6506a569705 | |
parent | db37648cd6ce9b828abd6d49aa3d269926ee7b7d (diff) |
[PATCH] slab: respect architecture and caller mandated alignment
As explained by Heiko, on s390 (32-bit) ARCH_KMALLOC_MINALIGN is set to
eight because their common I/O layer allocates data structures that need to
have an eight byte alignment. This does not work when CONFIG_SLAB_DEBUG is
enabled because kmem_cache_create will override alignment to BYTES_PER_WORD
which is four.
So change kmem_cache_create to ensure cache alignment is always at minimum
what the architecture or caller mandates even if slab debugging is enabled.
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Christoph Lameter <clameter@sgi.com>
Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | mm/slab.c | 25 |
1 files changed, 16 insertions, 9 deletions
@@ -2096,6 +2096,15 @@ kmem_cache_create (const char *name, size_t size, size_t align, | |||
2096 | } else { | 2096 | } else { |
2097 | ralign = BYTES_PER_WORD; | 2097 | ralign = BYTES_PER_WORD; |
2098 | } | 2098 | } |
2099 | |||
2100 | /* | ||
2101 | * Redzoning and user store require word alignment. Note this will be | ||
2102 | * overridden by architecture or caller mandated alignment if either | ||
2103 | * is greater than BYTES_PER_WORD. | ||
2104 | */ | ||
2105 | if (flags & SLAB_RED_ZONE || flags & SLAB_STORE_USER) | ||
2106 | ralign = BYTES_PER_WORD; | ||
2107 | |||
2099 | /* 2) arch mandated alignment: disables debug if necessary */ | 2108 | /* 2) arch mandated alignment: disables debug if necessary */ |
2100 | if (ralign < ARCH_SLAB_MINALIGN) { | 2109 | if (ralign < ARCH_SLAB_MINALIGN) { |
2101 | ralign = ARCH_SLAB_MINALIGN; | 2110 | ralign = ARCH_SLAB_MINALIGN; |
@@ -2109,8 +2118,7 @@ kmem_cache_create (const char *name, size_t size, size_t align, | |||
2109 | flags &= ~(SLAB_RED_ZONE | SLAB_STORE_USER); | 2118 | flags &= ~(SLAB_RED_ZONE | SLAB_STORE_USER); |
2110 | } | 2119 | } |
2111 | /* | 2120 | /* |
2112 | * 4) Store it. Note that the debug code below can reduce | 2121 | * 4) Store it. |
2113 | * the alignment to BYTES_PER_WORD. | ||
2114 | */ | 2122 | */ |
2115 | align = ralign; | 2123 | align = ralign; |
2116 | 2124 | ||
@@ -2122,20 +2130,19 @@ kmem_cache_create (const char *name, size_t size, size_t align, | |||
2122 | #if DEBUG | 2130 | #if DEBUG |
2123 | cachep->obj_size = size; | 2131 | cachep->obj_size = size; |
2124 | 2132 | ||
2133 | /* | ||
2134 | * Both debugging options require word-alignment which is calculated | ||
2135 | * into align above. | ||
2136 | */ | ||
2125 | if (flags & SLAB_RED_ZONE) { | 2137 | if (flags & SLAB_RED_ZONE) { |
2126 | /* redzoning only works with word aligned caches */ | ||
2127 | align = BYTES_PER_WORD; | ||
2128 | |||
2129 | /* add space for red zone words */ | 2138 | /* add space for red zone words */ |
2130 | cachep->obj_offset += BYTES_PER_WORD; | 2139 | cachep->obj_offset += BYTES_PER_WORD; |
2131 | size += 2 * BYTES_PER_WORD; | 2140 | size += 2 * BYTES_PER_WORD; |
2132 | } | 2141 | } |
2133 | if (flags & SLAB_STORE_USER) { | 2142 | if (flags & SLAB_STORE_USER) { |
2134 | /* user store requires word alignment and | 2143 | /* user store requires one word storage behind the end of |
2135 | * one word storage behind the end of the real | 2144 | * the real object. |
2136 | * object. | ||
2137 | */ | 2145 | */ |
2138 | align = BYTES_PER_WORD; | ||
2139 | size += BYTES_PER_WORD; | 2146 | size += BYTES_PER_WORD; |
2140 | } | 2147 | } |
2141 | #if FORCED_DEBUG && defined(CONFIG_DEBUG_PAGEALLOC) | 2148 | #if FORCED_DEBUG && defined(CONFIG_DEBUG_PAGEALLOC) |