aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2008-09-20 07:21:33 -0400
committerPaul Mundt <lethal@linux-sh.org>2008-09-20 07:21:33 -0400
commitc15c5f8c2bf0b00d036c5c6b67264764a6e5dffc (patch)
treefb4aca715702ba76edb95424fd2a573fa3ed6a28 /arch
parentb817f7e020958c8f79842076c137daa6f72eb366 (diff)
sh: Support kernel stacks smaller than a page.
This follows the powerpc commit f6a616800e68b61807d0f7bb0d5dc70665ef8046 '[POWERPC] Fix kernel stack allocation alignment'. SH has traditionally forced the thread order to be relative to the page size, so there were never any situations where the same bug was triggered by slub. Regardless, the usage of > 8kB stacks for the larger page sizes is overkill, so we switch to using slab allocations there, as per the powerpc change. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/sh/include/asm/thread_info.h32
-rw-r--r--arch/sh/mm/init.c29
2 files changed, 43 insertions, 18 deletions
diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h
index 0a894cafb1dd..f09ac4806294 100644
--- a/arch/sh/include/asm/thread_info.h
+++ b/arch/sh/include/asm/thread_info.h
@@ -33,20 +33,12 @@ struct thread_info {
33#define PREEMPT_ACTIVE 0x10000000 33#define PREEMPT_ACTIVE 0x10000000
34 34
35#if defined(CONFIG_4KSTACKS) 35#if defined(CONFIG_4KSTACKS)
36#define THREAD_SIZE_ORDER (0) 36#define THREAD_SHIFT 12
37#elif defined(CONFIG_PAGE_SIZE_4KB)
38#define THREAD_SIZE_ORDER (1)
39#elif defined(CONFIG_PAGE_SIZE_8KB)
40#define THREAD_SIZE_ORDER (1)
41#elif defined(CONFIG_PAGE_SIZE_16KB)
42#define THREAD_SIZE_ORDER (0)
43#elif defined(CONFIG_PAGE_SIZE_64KB)
44#define THREAD_SIZE_ORDER (0)
45#else 37#else
46#error "Unknown thread size" 38#define THREAD_SHIFT 13
47#endif 39#endif
48 40
49#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) 41#define THREAD_SIZE (1 << THREAD_SHIFT)
50#define STACK_WARN (THREAD_SIZE >> 3) 42#define STACK_WARN (THREAD_SIZE >> 3)
51 43
52/* 44/*
@@ -94,15 +86,19 @@ static inline struct thread_info *current_thread_info(void)
94 return ti; 86 return ti;
95} 87}
96 88
89/* thread information allocation */
90#if THREAD_SHIFT >= PAGE_SHIFT
91
92#define THREAD_SIZE_ORDER (THREAD_SHIFT - PAGE_SHIFT)
93
94#else /* THREAD_SHIFT < PAGE_SHIFT */
95
97#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR 96#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
98 97
99/* thread information allocation */ 98extern struct thread_info *alloc_thread_info(struct task_struct *tsk);
100#ifdef CONFIG_DEBUG_STACK_USAGE 99extern void free_thread_info(struct thread_info *ti);
101#define alloc_thread_info(ti) kzalloc(THREAD_SIZE, GFP_KERNEL) 100
102#else 101#endif /* THREAD_SHIFT < PAGE_SHIFT */
103#define alloc_thread_info(ti) kmalloc(THREAD_SIZE, GFP_KERNEL)
104#endif
105#define free_thread_info(ti) kfree(ti)
106 102
107#endif /* __ASSEMBLY__ */ 103#endif /* __ASSEMBLY__ */
108 104
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index 31211bfdc6d8..2a53943924b2 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -265,6 +265,35 @@ void free_initrd_mem(unsigned long start, unsigned long end)
265} 265}
266#endif 266#endif
267 267
268#if THREAD_SHIFT < PAGE_SHIFT
269static struct kmem_cache *thread_info_cache;
270
271struct thread_info *alloc_thread_info(struct task_struct *tsk)
272{
273 struct thread_info *ti;
274
275 ti = kmem_cache_alloc(thread_info_cache, GFP_KERNEL);
276 if (unlikely(ti == NULL))
277 return NULL;
278#ifdef CONFIG_DEBUG_STACK_USAGE
279 memset(ti, 0, THREAD_SIZE);
280#endif
281 return ti;
282}
283
284void free_thread_info(struct thread_info *ti)
285{
286 kmem_cache_free(thread_info_cache, ti);
287}
288
289void thread_info_cache_init(void)
290{
291 thread_info_cache = kmem_cache_create("thread_info", THREAD_SIZE,
292 THREAD_SIZE, 0, NULL);
293 BUG_ON(thread_info_cache == NULL);
294}
295#endif /* THREAD_SHIFT < PAGE_SHIFT */
296
268#ifdef CONFIG_MEMORY_HOTPLUG 297#ifdef CONFIG_MEMORY_HOTPLUG
269int arch_add_memory(int nid, u64 start, u64 size) 298int arch_add_memory(int nid, u64 start, u64 size)
270{ 299{