| From 1ab335d8f85792e3b107ff8237d53cf64db714df Mon Sep 17 00:00:00 2001 |
| From: Carsten Otte <cotte@de.ibm.com> |
| Date: Fri, 6 Aug 2010 18:19:22 +0200 |
| Subject: slab: fix object alignment |
| |
| From: Carsten Otte <cotte@de.ibm.com> |
| |
| commit 1ab335d8f85792e3b107ff8237d53cf64db714df upstream. |
| |
| This patch fixes alignment of slab objects in case CONFIG_DEBUG_PAGEALLOC is |
| active. |
| Before this spot in kmem_cache_create, we have this situation: |
| - align contains the required alignment of the object |
| - cachep->obj_offset is 0 or equals align in case of CONFIG_DEBUG_SLAB |
| - size equals the size of the object, or object plus trailing redzone in case |
| of CONFIG_DEBUG_SLAB |
| |
| This spot tries to fill one page per object if the object is in certain size |
| limits, however setting obj_offset to PAGE_SIZE - size does break the object |
| alignment since size may not be aligned with the required alignment. |
| This patch simply adds an ALIGN(size, align) to the equation and fixes the |
| object size detection accordingly. |
| |
| This code in drivers/s390/cio/qdio_setup_init has lead to incorrectly aligned |
| slab objects (sizeof(struct qdio_q) equals 1792): |
| qdio_q_cache = kmem_cache_create("qdio_q", sizeof(struct qdio_q), |
| 256, 0, NULL); |
| |
| Acked-by: Christoph Lameter <cl@linux.com> |
| Signed-off-by: Carsten Otte <cotte@de.ibm.com> |
| Signed-off-by: Pekka Enberg <penberg@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| mm/slab.c | 4 ++-- |
| 1 file changed, 2 insertions(+), 2 deletions(-) |
| |
| --- a/mm/slab.c |
| +++ b/mm/slab.c |
| @@ -2262,8 +2262,8 @@ kmem_cache_create (const char *name, siz |
| } |
| #if FORCED_DEBUG && defined(CONFIG_DEBUG_PAGEALLOC) |
| if (size >= malloc_sizes[INDEX_L3 + 1].cs_size |
| - && cachep->obj_size > cache_line_size() && size < PAGE_SIZE) { |
| - cachep->obj_offset += PAGE_SIZE - size; |
| + && cachep->obj_size > cache_line_size() && ALIGN(size, align) < PAGE_SIZE) { |
| + cachep->obj_offset += PAGE_SIZE - ALIGN(size, align); |
| size = PAGE_SIZE; |
| } |
| #endif |