Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S261158AbUCPKB2 (ORCPT ); Tue, 16 Mar 2004 05:01:28 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S263819AbUCPKB2 (ORCPT ); Tue, 16 Mar 2004 05:01:28 -0500 Received: from mx1.elte.hu ([157.181.1.137]:26269 "EHLO mx1.elte.hu") by vger.kernel.org with ESMTP id S261158AbUCPKBI (ORCPT ); Tue, 16 Mar 2004 05:01:08 -0500 Date: Tue, 16 Mar 2004 08:16:02 +0100 From: Ingo Molnar To: Zwane Mwaikambo Cc: Linux Kernel , Andrew Morton , Matt Mackall Subject: Re: [PATCH][2.6-mm] Fix 4G/4G w/ 8k+ stacks Message-ID: <20040316071601.GA2560@elte.hu> References: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.4.1i X-ELTE-SpamVersion: MailScanner 4.26.8-itk2 (ELTE 1.1) SpamAssassin 2.63 ClamAV 0.65 X-ELTE-VirusStatus: clean X-ELTE-SpamCheck: no X-ELTE-SpamCheck-Details: score=-4.9, required 5.9, autolearn=not spam, BAYES_00 -4.90 X-ELTE-SpamLevel: X-ELTE-SpamScore: -4 Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 9523 Lines: 235 looks good to me! Ingo * Zwane Mwaikambo wrote: > The 4/4 code right now is setup for 8k stacks, this patch should allow for > arbitrary stack sizes. Some parts are rather ugly (e.g. STACK_PAGE_COUNT) > so (abusive too) comments are welcome. > > I've tested it with 4k,8k and 16k stacks on UP and SMP, but i believe it > breaks with CONFIG_DEBUG_PAGEALLOC > > Index: linux-2.6.4-mm2/include/asm-i386/fixmap.h > =================================================================== > RCS file: /home/cvsroot/linux-2.6.4-mm2/include/asm-i386/fixmap.h,v > retrieving revision 1.1.1.1 > diff -u -p -B -r1.1.1.1 fixmap.h > --- linux-2.6.4-mm2/include/asm-i386/fixmap.h 15 Mar 2004 05:53:41 -0000 1.1.1.1 > +++ linux-2.6.4-mm2/include/asm-i386/fixmap.h 15 Mar 2004 16:01:20 -0000 > @@ -115,10 +115,10 @@ extern void __set_fixmap (enum fixed_add > * Leave one empty page between vmalloc'ed areas and > * the start of the fixmap. > * > - * IMPORTANT: dont change FIXADDR_TOP without adjusting KM_VSTACK0 > - * and KM_VSTACK1 so that the virtual stack is 8K aligned. > + * IMPORTANT: we have to align FIXADDR_TOP so that the virtual stack > + * is THREAD_SIZE aligned. > */ > -#define FIXADDR_TOP (0xffffe000UL) > +#define FIXADDR_TOP (0xffffe000UL & ~(THREAD_SIZE-1)) > #define __FIXADDR_SIZE (__end_of_permanent_fixed_addresses << PAGE_SHIFT) > #define FIXADDR_START (FIXADDR_TOP - __FIXADDR_SIZE) > > Index: linux-2.6.4-mm2/include/asm-i386/kmap_types.h > =================================================================== > RCS file: /home/cvsroot/linux-2.6.4-mm2/include/asm-i386/kmap_types.h,v > retrieving revision 1.1.1.1 > diff -u -p -B -r1.1.1.1 kmap_types.h > --- linux-2.6.4-mm2/include/asm-i386/kmap_types.h 15 Mar 2004 05:53:41 -0000 1.1.1.1 > +++ linux-2.6.4-mm2/include/asm-i386/kmap_types.h 15 Mar 2004 23:09:53 -0000 > @@ -2,15 +2,16 @@ > #define _ASM_KMAP_TYPES_H > > #include > +#include > > enum km_type { > /* > - * IMPORTANT: don't move these 3 entries, and only add entries in > - * pairs: the 4G/4G virtual stack must be 8K aligned on each cpu. > + * IMPORTANT: don't move these 3 entries, be wary when adding entries, > + * the 4G/4G virtual stack must be THREAD_SIZE aligned on each cpu. > */ > KM_BOUNCE_READ, > - KM_VSTACK1, > - KM_VSTACK0, > + KM_VSTACK_BASE, > + KM_VSTACK_TOP = KM_VSTACK_BASE + STACK_PAGE_COUNT-1, > > KM_LDT_PAGE15, > KM_LDT_PAGE0 = KM_LDT_PAGE15 + 16-1, > @@ -30,8 +31,8 @@ enum km_type { > KM_SOFTIRQ0, > KM_SOFTIRQ1, > /* > - * Add new entries in pairs: > - * the 4G/4G virtual stack must be 8K aligned on each cpu. > + * Be wary when adding entries: > + * the 4G/4G virtual stack must be THREAD_SIZE aligned on each cpu. > */ > KM_TYPE_NR > }; > Index: linux-2.6.4-mm2/include/asm-i386/processor.h > =================================================================== > RCS file: /home/cvsroot/linux-2.6.4-mm2/include/asm-i386/processor.h,v > retrieving revision 1.1.1.1 > diff -u -p -B -r1.1.1.1 processor.h > --- linux-2.6.4-mm2/include/asm-i386/processor.h 15 Mar 2004 05:53:41 -0000 1.1.1.1 > +++ linux-2.6.4-mm2/include/asm-i386/processor.h 15 Mar 2004 15:44:57 -0000 > @@ -401,10 +401,16 @@ struct tss_struct { > > #define ARCH_MIN_TASKALIGN 16 > > +#ifdef CONFIG_4KSTACKS > +#define STACK_PAGE_COUNT (4096/PAGE_SIZE) > +#else > +#define STACK_PAGE_COUNT (8192/PAGE_SIZE) /* THREAD_SIZE/PAGE_SIZE */ > +#endif > + > struct thread_struct { > /* cached TLS descriptors. */ > struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES]; > - void *stack_page0, *stack_page1; > + void *stack_page[STACK_PAGE_COUNT]; > unsigned long esp0; > unsigned long sysenter_cs; > unsigned long eip; > Index: linux-2.6.4-mm2/include/asm-i386/thread_info.h > =================================================================== > RCS file: /home/cvsroot/linux-2.6.4-mm2/include/asm-i386/thread_info.h,v > retrieving revision 1.1.1.1 > diff -u -p -B -r1.1.1.1 thread_info.h > --- linux-2.6.4-mm2/include/asm-i386/thread_info.h 15 Mar 2004 05:53:41 -0000 1.1.1.1 > +++ linux-2.6.4-mm2/include/asm-i386/thread_info.h 15 Mar 2004 15:49:56 -0000 > @@ -49,8 +49,10 @@ struct thread_info { > #endif > > #define PREEMPT_ACTIVE 0x4000000 > + > +/* if you change THREAD_SIZE here, don't forget to change STACK_PAGE_COUNT */ > #ifdef CONFIG_4KSTACKS > -#define THREAD_SIZE (4096) > +#define THREAD_SIZE (4096) > #else > #define THREAD_SIZE (8192) > #endif > Index: linux-2.6.4-mm2/arch/i386/kernel/entry_trampoline.c > =================================================================== > RCS file: /home/cvsroot/linux-2.6.4-mm2/arch/i386/kernel/entry_trampoline.c,v > retrieving revision 1.1.1.1 > diff -u -p -B -r1.1.1.1 entry_trampoline.c > --- linux-2.6.4-mm2/arch/i386/kernel/entry_trampoline.c 15 Mar 2004 05:53:30 -0000 1.1.1.1 > +++ linux-2.6.4-mm2/arch/i386/kernel/entry_trampoline.c 15 Mar 2004 08:52:48 -0000 > @@ -21,7 +21,9 @@ extern char __entry_tramp_start, __entry > void __init init_entry_mappings(void) > { > #ifdef CONFIG_X86_HIGH_ENTRY > + > void *tramp; > + int p; > > /* > * We need a high IDT and GDT for the 4G/4G split: > @@ -37,7 +39,7 @@ void __init init_entry_mappings(void) > /* > * Virtual kernel stack: > */ > - BUG_ON(__kmap_atomic_vaddr(KM_VSTACK0) & (THREAD_SIZE-1)); > + BUG_ON(__kmap_atomic_vaddr(KM_VSTACK_TOP) & (THREAD_SIZE-1)); > BUG_ON(sizeof(struct desc_struct)*NR_CPUS*GDT_ENTRIES > 2*PAGE_SIZE); > BUG_ON((unsigned int)&__entry_tramp_end - (unsigned int)&__entry_tramp_start > 2*PAGE_SIZE); > > @@ -45,15 +47,15 @@ void __init init_entry_mappings(void) > * set up the initial thread's virtual stack related > * fields: > */ > - current->thread.stack_page0 = virt_to_page((char *)current->thread_info); > - current->thread.stack_page1 = virt_to_page((char *)current->thread_info + PAGE_SIZE); > - current->thread_info->virtual_stack = (void *)__kmap_atomic_vaddr(KM_VSTACK0); > - > - __kunmap_atomic_type(KM_VSTACK0); > - __kunmap_atomic_type(KM_VSTACK1); > - __kmap_atomic(current->thread.stack_page0, KM_VSTACK0); > - __kmap_atomic(current->thread.stack_page1, KM_VSTACK1); > + for (p = 0; p < ARRAY_SIZE(current->thread.stack_page); p++) > + current->thread.stack_page[p] = virt_to_page((char *)current->thread_info + (p*PAGE_SIZE)); > + > + current->thread_info->virtual_stack = (void *)__kmap_atomic_vaddr(KM_VSTACK_TOP); > > + for (p = 0; p < ARRAY_SIZE(current->thread.stack_page); p++) { > + __kunmap_atomic_type(KM_VSTACK_TOP-p); > + __kmap_atomic(current->thread.stack_page[p], KM_VSTACK_TOP-p); > + } > #endif > current->thread_info->real_stack = (void *)current->thread_info; > current->thread_info->user_pgd = NULL; > Index: linux-2.6.4-mm2/arch/i386/kernel/process.c > =================================================================== > RCS file: /home/cvsroot/linux-2.6.4-mm2/arch/i386/kernel/process.c,v > retrieving revision 1.1.1.1 > diff -u -p -B -r1.1.1.1 process.c > --- linux-2.6.4-mm2/arch/i386/kernel/process.c 15 Mar 2004 05:53:30 -0000 1.1.1.1 > +++ linux-2.6.4-mm2/arch/i386/kernel/process.c 15 Mar 2004 08:08:42 -0000 > @@ -345,7 +345,7 @@ int copy_thread(int nr, unsigned long cl > { > struct pt_regs * childregs; > struct task_struct *tsk; > - int err; > + int err, i; > > childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1; > struct_cpy(childregs, regs); > @@ -360,10 +360,11 @@ int copy_thread(int nr, unsigned long cl > * get the two stack pages, for the virtual stack. > * > * IMPORTANT: this code relies on the fact that the task > - * structure is an 8K aligned piece of physical memory. > + * structure is an THREAD_SIZE aligned piece of physical memory. > */ > - p->thread.stack_page0 = virt_to_page((unsigned long)p->thread_info); > - p->thread.stack_page1 = virt_to_page((unsigned long)p->thread_info + PAGE_SIZE); > + for (i = 0; i < ARRAY_SIZE(p->thread.stack_page); i++) > + p->thread.stack_page[i] = > + virt_to_page((unsigned long)p->thread_info + (i*PAGE_SIZE)); > > p->thread.eip = (unsigned long) ret_from_fork; > p->thread_info->real_stack = p->thread_info; > @@ -519,22 +520,23 @@ struct task_struct fastcall * __switch_t > __unlazy_fpu(prev_p); > > #ifdef CONFIG_X86_HIGH_ENTRY > +{ > + int i; > /* > * Set the ptes of the virtual stack. (NOTE: a one-page TLB flush is > * needed because otherwise NMIs could interrupt the > * user-return code with a virtual stack and stale TLBs.) > */ > - __kunmap_atomic_type(KM_VSTACK0); > - __kunmap_atomic_type(KM_VSTACK1); > - __kmap_atomic(next->stack_page0, KM_VSTACK0); > - __kmap_atomic(next->stack_page1, KM_VSTACK1); > - > + for (i = 0; i < ARRAY_SIZE(next->stack_page); i++) { > + __kunmap_atomic_type(KM_VSTACK_TOP-i); > + __kmap_atomic(next->stack_page[i], KM_VSTACK_TOP-i); > + } > /* > * NOTE: here we rely on the task being the stack as well > */ > next_p->thread_info->virtual_stack = > - (void *)__kmap_atomic_vaddr(KM_VSTACK0); > - > + (void *)__kmap_atomic_vaddr(KM_VSTACK_TOP); > +} > #if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP) > /* > * If next was preempted on entry from userspace to kernel, - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/