public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* Re: [RFC] 4KB stack + irq stack for x86
@ 2002-06-06 20:55 Ulrich Weigand
  2002-06-06 21:19 ` David Mosberger
  0 siblings, 1 reply; 27+ messages in thread
From: Ulrich Weigand @ 2002-06-06 20:55 UTC (permalink / raw)
  To: davidm; +Cc: Andi Kleen, linux-kernel


David Mosberger wrote:

>Just a minor nit: for ia64 it's either 32KB (for page sizes up to
>16KB) or 64KB (for 64KB page size).  The 32KB is conservative and
>based on the assumption that there can be up to 16 nested interrupts
>plus some other nested traps (such as unaligned faults).  A separate
>irq stack should let us reduce the per-task stack size.

So in the case of 8K page size, you need an order-2 allocation
for the stack, right?  How do you handle failures due to fragmentation?


Mit freundlichen Gruessen / Best Regards

Ulrich Weigand

--
  Dr. Ulrich Weigand
  Linux for S/390 Design & Development
  IBM Deutschland Entwicklung GmbH, Schoenaicher Str. 220, 71032 Boeblingen
  Phone: +49-7031/16-3727   ---   Email: Ulrich.Weigand@de.ibm.com



^ permalink raw reply	[flat|nested] 27+ messages in thread
[parent not found: <OF70FD985F.A9C66B00-ONC1256BD0.0069C993@de.ibm.com.suse.lists.linux.kernel>]
* Re: [RFC] 4KB stack + irq stack for x86
@ 2002-06-06 19:24 Ulrich Weigand
  0 siblings, 0 replies; 27+ messages in thread
From: Ulrich Weigand @ 2002-06-06 19:24 UTC (permalink / raw)
  To: Pete Zaitcev; +Cc: linux-kernel


Pete Zaitcev wrote:

>> Of course, the situation is particularly bad on s390, because every
>> function call needs at least 96 bytes on the stack (due to the register
>> save areas required by our ABI).
>
>How is this different from sparc64?

Well, I guess it's similar on sparc.  I'm not sure about the size of the
save areas needed on sparc, though.  In any case both sparc and s390 are
certainly much worse w.r.t. stack space usage than i386 ...

(*Really* ugly is s390x, because we need about twice as much stack on
average than on s390, but page size is still only 4K -- most other 64-bit
platforms have 8K page size ...)


Mit freundlichen Gruessen / Best Regards

Ulrich Weigand

--
  Dr. Ulrich Weigand
  Linux for S/390 Design & Development
  IBM Deutschland Entwicklung GmbH, Schoenaicher Str. 220, 71032 Boeblingen
  Phone: +49-7031/16-3727   ---   Email: Ulrich.Weigand@de.ibm.com


^ permalink raw reply	[flat|nested] 27+ messages in thread
* Re: [RFC] 4KB stack + irq stack for x86
@ 2002-06-06 13:32 Ulrich Weigand
  0 siblings, 0 replies; 27+ messages in thread
From: Ulrich Weigand @ 2002-06-06 13:32 UTC (permalink / raw)
  To: bcrl; +Cc: linux-kernel

Benjamin LaHaise wrote:

>Which is, honestly, a bug. The IO subsystem should not be capable of
>engaging in such deep recursion. ext2/ext3 barely allocate anything
>on the stack (0x90 bytes at most in only a couple of calls), the vm
>is in a similar state, and even the network stack's largest allocations
>are in syscalls and timer code. Face it, the majority of code that is
>or could cause problems are things that probably need fixing anyways.

Just FYI here's a stack trace of a real-world stack overflow
situation we caught on s390 (before we switched to separate
interrupt stacks).

What goes on is this:  system call does copy_from_user, which causes
a page fault, which goes through mm, filesystem, and buffer cache code,
calls alloc_pages there, which is out of memory and goes through
try_to_free_pages and the whole swap-out stack.  At this time an
interrupt hits, followed by softirq processing.  This runs the complete
TCP/IP stack and network device driver.  This finally calls into kfree,
which is the last straw ...  (Of course another interrupt could still
have occured at this point.)

Of course, the situation is particularly bad on s390, because every
function call needs at least 96 bytes on the stack (due to the register
save areas required by our ABI).

48 kfree                        [0x3bfae] SP=0x31ae7c8, FP=0x31ae828, SIZE=112
47 skb_release_data+170        [0x1ad632] SP=0x31ae838, FP=0x31ae898, SIZE=96
46 kfree_skbmem+54             [0x1ad672] SP=0x31ae898, FP=0x31ae8f8, SIZE=104
45 __kfree_skb+262             [0x1ad7ea] SP=0x31ae900, FP=0x31ae960, SIZE=96
44 lcs_txpacket+712            [0x18b63c] SP=0x31ae960, FP=0x31ae9c0, SIZE=120
43 qdisc_restart+184           [0x1b9ec0] SP=0x31ae9d8, FP=0x31aea38, SIZE=104
42 dev_queue_xmit+466          [0x1b18fe] SP=0x31aea40, FP=0x31aeaa0, SIZE=96
41 ip_output+340               [0x1c3cd8] SP=0x31aeaa0, FP=0x31aeb00, SIZE=96
40 ip_build_and_send_pkt+542   [0x1c38fe] SP=0x31aeb00, FP=0x31aeb60, SIZE=104
39 tcp_v4_send_synack+196      [0x1dbde8] SP=0x31aeb68, FP=0x31aebc8, SIZE=96
38 tcp_v4_conn_request+1030    [0x1dc25e] SP=0x31aebc8, FP=0x31aec28, SIZE=536
37 tcp_rcv_state_process+308   [0x1d44c4] SP=0x31aede0, FP=0x31aee40, SIZE=104
36 tcp_v4_do_rcv+292           [0x1dcb0c] SP=0x31aee48, FP=0x31aeea8, SIZE=96
35 tcp_v4_rcv+1436             [0x1dd124] SP=0x31aeea8, FP=0x31aef08, SIZE=96
34 ip_local_deliver+370        [0x1c090e] SP=0x31aef08, FP=0x31aef68, SIZE=96
33 ip_rcv+1122                 [0x1c0e26] SP=0x31aef68, FP=0x31aefc8, SIZE=112
32 net_rx_action+634           [0x1b241a] SP=0x31aefd8, FP=0x31af038, SIZE=144
31 do_softirq+168               [0x23ac8] SP=0x31af068, FP=0x31af0c8, SIZE=112
30 io_return_bh                 [0x13f96] SP=0x31af0d8, FP=0x31af138, SIZE=248
29 try_to_swap_out              [0x3dac8] SP=0x31af1d0, FP=0x31af230, SIZE=104
28 swap_out_pmd+320             [0x3de9c] SP=0x31af238, FP=0x31af298, SIZE=104
27 swap_out_vma+208             [0x3df8c] SP=0x31af2a0, FP=0x31af300, SIZE=144
26 swap_out_mm+130              [0x3e05a] SP=0x31af330, FP=0x31af390, SIZE=96
25 swap_out+268                 [0x3e19c] SP=0x31af390, FP=0x31af3f0, SIZE=96
24 refill_inactive+158          [0x3fbf2] SP=0x31af3f0, FP=0x31af450, SIZE=96
23 do_try_to_free_pages+132     [0x3fcb4] SP=0x31af450, FP=0x31af4b0, SIZE=96
22 try_to_free_pages+66         [0x3feaa] SP=0x31af4b0, FP=0x31af510, SIZE=96
21 __alloc_pages+580            [0x40f3c] SP=0x31af510, FP=0x31af570, SIZE=104
20 _alloc_pages+54              [0x40cee] SP=0x31af578, FP=0x31af5d8, SIZE=96
19 grow_buffers+140             [0x4dcb8] SP=0x31af5d8, FP=0x31af638, SIZE=96
18 refill_freelist+96           [0x4a7f4] SP=0x31af638, FP=0x31af698, SIZE=96
17 getblk+644                   [0x4b1d0] SP=0x31af698, FP=0x31af6f8, SIZE=96
16 bread+56                     [0x4b69c] SP=0x31af6f8, FP=0x31af758, SIZE=104
15 ext2_get_branch+156          [0x74fa0] SP=0x31af760, FP=0x31af7c0, SIZE=104
14 ext2_get_block+202           [0x753d2] SP=0x31af7c8, FP=0x31af828, SIZE=208
13 block_read_full_page+320     [0x4c788] SP=0x31af898, FP=0x31af8f8, SIZE=144
12 ext2_readpage+46             [0x758c6] SP=0x31af928, FP=0x31af988, SIZE=96
11 read_cluster_nonblocking+346 [0x34d52] SP=0x31af988, FP=0x31af9e8, SIZE=96
10 filemap_nopage+576           [0x36600] SP=0x31af9e8, FP=0x31afa48, SIZE=112
 9 do_no_page+142               [0x3198a] SP=0x31afa58, FP=0x31afab8, SIZE=96
 8 handle_mm_fault+262          [0x31bd6] SP=0x31afab8, FP=0x31afb18, SIZE=120
 7 do_page_fault+722            [0x12d5a] SP=0x31afb30, FP=0x31afb90, SIZE=104
 6 pgm_dn                       [0x13ef8] SP=0x31afb98, FP=0x31afbf8, SIZE=248
 5 tcp_sendmsg                 [0x1c9ed0] SP=0x31afc90, FP=0x31afcf0, SIZE=176
 4 inet_sendmsg+84             [0x1ea538] SP=0x31afd40, FP=0x31afda0, SIZE=96
 3 sock_sendmsg+132            [0x1a97c8] SP=0x31afda0, FP=0x31afe00, SIZE=120
 2 sock_write+186              [0x1a9a1e] SP=0x31afe18, FP=0x31afe78, SIZE=136
 1 sys_write+214                [0x47d2e] SP=0x31afea0, FP=0x31aff00, SIZE=104
 0 pgm_system_call+34           [0x138c0] SP=0x31aff08, FP=0x31aff68, SIZE=248


Mit freundlichen Gruessen / Best Regards

Ulrich Weigand

--
  Dr. Ulrich Weigand
  Linux for S/390 Design & Development
  IBM Deutschland Entwicklung GmbH, Schoenaicher Str. 220, 71032 Boeblingen
  Phone: +49-7031/16-3727   ---   Email: Ulrich.Weigand@de.ibm.com


^ permalink raw reply	[flat|nested] 27+ messages in thread
[parent not found: <20020604225539.F9111@redhat.com.suse.lists.linux.kernel>]
* [RFC] 4KB stack + irq stack for x86
@ 2002-06-05  2:55 Benjamin LaHaise
  2002-06-05 15:33 ` Linus Torvalds
  2002-06-05 22:15 ` Steve Lord
  0 siblings, 2 replies; 27+ messages in thread
From: Benjamin LaHaise @ 2002-06-05  2:55 UTC (permalink / raw)
  To: Linux Kernel; +Cc: Linus Torvalds

Hey folks,

Below is a patch against 2.5.20 that implements 4KB stacks for tasks, 
plus a seperate 4KB irq stack for use by interrupts.  There are a couple 
of reasons for doing this: 4KB stacks put less pressure on the VM 
subsystem, reduces the overall memory usage for systems with large 
numbers of tasks, and increases the reliability of the system when 
under heavy irq load by provide a fixed stack size for interrupt 
handlers that other kernel code will not eat into.

The interrupt stacks are stackable, so we could use multiple 
4KB irq stacks.  The thread_info structure is included in each 
interrupt stack, and has the current pointer copied into it upon 
entry.

Things can be made a bit more efficient by moving thread_info from the 
bottom of the stack to the top.  This would simplify the irq entry code 
a bit as the same pointer can be used for the thread_info code and top 
of stack.  The 2.4 version of the patch does this.  In addition, moving 
thread_info to the top of the stack results in better cache line 
sharing: thread_info is in the same cacheline as the first data pushed 
onto the irq stack.  Ditto for regular tasks.  I'll do this if there is 
interest in merging it.

I had been playing with 2.5KB stacks (4KB page minus 1.5K for task_struct), 
and it is possible given a few fixes for massive (>1KB) stack allocation 
in the pci layer and a few others.  So far 4KB hasn't overflowed on any 
of the tasks I normally run (checked using a stack overflow checker that 
follows).

Comments?

		-ben
-- 
"You will be reincarnated as a toad; and you will be much happier."


:r ~/patches/v2.5.20/v2.5.20-smallstack-A0.diff
diff -urN v2.5.20/arch/i386/config.in smallstack-2.5.20.diff/arch/i386/config.in
--- v2.5.20/arch/i386/config.in	Tue Jun  4 18:00:02 2002
+++ smallstack-2.5.20.diff/arch/i386/config.in	Tue Jun  4 19:30:54 2002
@@ -34,6 +34,7 @@
 #
 # Define implied options from the CPU selection here
 #
+define_bool CONFIG_X86_HAVE_CMOV n
 
 if [ "$CONFIG_M386" = "y" ]; then
    define_bool CONFIG_X86_CMPXCHG n
@@ -90,18 +91,21 @@
    define_bool CONFIG_X86_GOOD_APIC y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
    define_bool CONFIG_X86_PPRO_FENCE y
+   define_bool CONFIG_X86_HAVE_CMOV y
 fi
 if [ "$CONFIG_MPENTIUMIII" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
    define_bool CONFIG_X86_TSC y
    define_bool CONFIG_X86_GOOD_APIC y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
+   define_bool CONFIG_X86_HAVE_CMOV y
 fi
 if [ "$CONFIG_MPENTIUM4" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 7
    define_bool CONFIG_X86_TSC y
    define_bool CONFIG_X86_GOOD_APIC y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
+   define_bool CONFIG_X86_HAVE_CMOV y
 fi
 if [ "$CONFIG_MK6" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
@@ -115,6 +119,7 @@
    define_bool CONFIG_X86_GOOD_APIC y
    define_bool CONFIG_X86_USE_3DNOW y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
+   define_bool CONFIG_X86_HAVE_CMOV y
 fi
 if [ "$CONFIG_MELAN" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 4
@@ -131,6 +136,7 @@
 if [ "$CONFIG_MCRUSOE" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
    define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_HAVE_CMOV y
 fi
 if [ "$CONFIG_MWINCHIPC6" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
diff -urN v2.5.20/arch/i386/kernel/entry.S smallstack-2.5.20.diff/arch/i386/kernel/entry.S
--- v2.5.20/arch/i386/kernel/entry.S	Tue Jun  4 18:00:16 2002
+++ smallstack-2.5.20.diff/arch/i386/kernel/entry.S	Tue Jun  4 20:24:51 2002
@@ -163,7 +163,7 @@
 	movl %ecx,CS(%esp)	#
 	movl %esp, %ebx
 	pushl %ebx
-	andl $-8192, %ebx	# GET_THREAD_INFO
+	GET_THREAD_INFO_WITH_ESP(%ebx)
 	movl TI_EXEC_DOMAIN(%ebx), %edx	# Get the execution domain
 	movl 4(%edx), %edx	# Get the lcall7 handler for the domain
 	pushl $0x7
@@ -185,7 +185,7 @@
 	movl %ecx,CS(%esp)	#
 	movl %esp, %ebx
 	pushl %ebx
-	andl $-8192, %ebx	# GET_THREAD_INFO
+	GET_THREAD_INFO_WITH_ESP(%ebx)
 	movl TI_EXEC_DOMAIN(%ebx), %edx	# Get the execution domain
 	movl 4(%edx), %edx	# Get the lcall7 handler for the domain
 	pushl $0x27
@@ -361,7 +361,30 @@
 	SAVE_ALL
 	GET_THREAD_INFO(%ebx)
 	INC_PRE_COUNT(%ebx)
+
+	movl TI_IRQ_STACK(%ebx),%ecx
+	movl TI_TASK(%ebx),%edx
+	movl %esp,%eax
+	leal (THREAD_SIZE-4)(%ecx),%ebx
+	testl %ecx,%ecx			# is there a valid irq_stack?
+
+	# switch to the irq stack
+#ifdef CONFIG_X86_HAVE_CMOV
+	cmovnz %ebx,%esp
+#warning using cmov
+#else
+#warning cannot use cmov
+	jnz 1f
+	mov %ebx,%esp
+1:
+#endif
+
+	# update the task pointer in the irq stack
+	GET_THREAD_INFO(%ebx)
+	movl %edx,TI_TASK(%ebx)
+
 	call do_IRQ
+	movl %eax,%esp			# potentially restore non-irq stack
 	jmp ret_from_intr
 
 #define BUILD_INTERRUPT(name, nr)	\
diff -urN v2.5.20/arch/i386/kernel/head.S smallstack-2.5.20.diff/arch/i386/kernel/head.S
--- v2.5.20/arch/i386/kernel/head.S	Tue Jun  4 18:00:16 2002
+++ smallstack-2.5.20.diff/arch/i386/kernel/head.S	Mon Jun  3 22:25:16 2002
@@ -15,6 +15,7 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/desc.h>
+#include <asm/thread_info.h>
 
 #define OLD_CL_MAGIC_ADDR	0x90020
 #define OLD_CL_MAGIC		0xA33F
@@ -310,7 +311,7 @@
 	ret
 
 ENTRY(stack_start)
-	.long init_thread_union+8192
+	.long init_thread_union+THREAD_SIZE
 	.long __KERNEL_DS
 
 /* This is the default interrupt "handler" :-) */
diff -urN v2.5.20/arch/i386/kernel/init_task.c smallstack-2.5.20.diff/arch/i386/kernel/init_task.c
--- v2.5.20/arch/i386/kernel/init_task.c	Tue Jun  4 17:59:24 2002
+++ smallstack-2.5.20.diff/arch/i386/kernel/init_task.c	Tue Jun  4 20:25:47 2002
@@ -13,6 +13,9 @@
 static struct signal_struct init_signals = INIT_SIGNALS;
 struct mm_struct init_mm = INIT_MM(init_mm);
 
+union thread_union init_irq_union
+	__attribute__((__section__(".data.init_task")));
+
 /*
  * Initial thread structure.
  *
@@ -22,7 +25,15 @@
  */
 union thread_union init_thread_union 
 	__attribute__((__section__(".data.init_task"))) =
-		{ INIT_THREAD_INFO(init_task) };
+		{ { 
+			task:		&init_task,
+			exec_domain:	&default_exec_domain,
+			flags:		0,
+			cpu:		0,
+			addr_limit:	KERNEL_DS,
+			irq_stack:	&init_irq_union,
+		} };
+
 
 /*
  * Initial task structure.
diff -urN v2.5.20/arch/i386/kernel/irq.c smallstack-2.5.20.diff/arch/i386/kernel/irq.c
--- v2.5.20/arch/i386/kernel/irq.c	Tue Jun  4 17:59:47 2002
+++ smallstack-2.5.20.diff/arch/i386/kernel/irq.c	Tue Jun  4 21:01:16 2002
@@ -557,7 +557,8 @@
  * SMP cross-CPU interrupts have their own specific
  * handlers).
  */
-asmlinkage unsigned int do_IRQ(struct pt_regs regs)
+struct pt_regs *do_IRQ(struct pt_regs *regs) __attribute__((regparm(1)));
+struct pt_regs *do_IRQ(struct pt_regs *regs)
 {	
 	/* 
 	 * We ack quickly, we don't want the irq controller
@@ -569,7 +570,7 @@
 	 * 0 return value means that this irq is already being
 	 * handled by some other CPU. (or is disabled)
 	 */
-	int irq = regs.orig_eax & 0xff; /* high bits used in ret_from_ code  */
+	int irq = regs->orig_eax & 0xff; /* high bits used in ret_from_ code  */
 	int cpu = smp_processor_id();
 	irq_desc_t *desc = irq_desc + irq;
 	struct irqaction * action;
@@ -618,7 +619,7 @@
 	 */
 	for (;;) {
 		spin_unlock(&desc->lock);
-		handle_IRQ_event(irq, &regs, action);
+		handle_IRQ_event(irq, regs, action);
 		spin_lock(&desc->lock);
 		
 		if (!(desc->status & IRQ_PENDING))
@@ -636,7 +637,7 @@
 
 	if (softirq_pending(cpu))
 		do_softirq();
-	return 1;
+	return regs;
 }
 
 /**
diff -urN v2.5.20/arch/i386/kernel/process.c smallstack-2.5.20.diff/arch/i386/kernel/process.c
--- v2.5.20/arch/i386/kernel/process.c	Tue Jun  4 18:00:00 2002
+++ smallstack-2.5.20.diff/arch/i386/kernel/process.c	Tue Jun  4 20:47:40 2002
@@ -650,6 +650,7 @@
 
 	/* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
 
+	next_p->thread_info->irq_stack = prev_p->thread_info->irq_stack;
 	unlazy_fpu(prev_p);
 
 	/*
diff -urN v2.5.20/arch/i386/kernel/smpboot.c smallstack-2.5.20.diff/arch/i386/kernel/smpboot.c
--- v2.5.20/arch/i386/kernel/smpboot.c	Tue Jun  4 18:00:18 2002
+++ smallstack-2.5.20.diff/arch/i386/kernel/smpboot.c	Tue Jun  4 20:54:12 2002
@@ -72,6 +72,10 @@
 /* Per CPU bogomips and other parameters */
 struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
 
+extern union thread_union init_irq_union;
+union thread_union *irq_stacks[NR_CPUS] __cacheline_aligned =
+	{ &init_irq_union, };
+
 /* Set when the idlers are all forked */
 int smp_threads_ready;
 
@@ -808,6 +812,27 @@
 	return (send_status | accept_status);
 }
 
+static void __init setup_irq_stack(struct task_struct *p, int cpu)
+{
+	unsigned long stk;
+
+	stk = __get_free_pages(GFP_KERNEL, THREAD_ORDER);
+	if (!stk)
+		panic("I can't seem to allocate my irq stack.  Oh well, giving up.");
+
+	irq_stacks[cpu] = (void *)stk;
+	memset(irq_stacks[cpu], 0, THREAD_SIZE);
+	irq_stacks[cpu]->thread_info.cpu = cpu;
+	irq_stacks[cpu]->thread_info.preempt_count = 1;
+					/* interrupts are not preemptable */
+	p->thread_info->irq_stack = irq_stacks[cpu];
+
+	/* If we want to make the irq stack more than one unit
+	 * deep, we can chain then off of the irq_stack pointer
+	 * here.
+	 */
+}
+
 extern unsigned long cpu_initialized;
 
 static void __init do_boot_cpu (int apicid) 
@@ -831,6 +856,8 @@
 	if (IS_ERR(idle))
 		panic("failed fork for CPU %d", cpu);
 
+	setup_irq_stack(idle, cpu);
+
 	/*
 	 * We remove it from the pidhash and the runqueue
 	 * once we got the process:
@@ -848,7 +875,7 @@
 
 	/* So we see what's up   */
 	printk("Booting processor %d/%d eip %lx\n", cpu, apicid, start_eip);
-	stack_start.esp = (void *) (1024 + PAGE_SIZE + (char *)idle->thread_info);
+	stack_start.esp = (void *) (THREAD_SIZE + (char *)idle->thread_info);
 
 	/*
 	 * This grunge runs the startup process for
diff -urN v2.5.20/include/asm-i386/page.h smallstack-2.5.20.diff/include/asm-i386/page.h
--- v2.5.20/include/asm-i386/page.h	Tue Jun  4 18:00:18 2002
+++ smallstack-2.5.20.diff/include/asm-i386/page.h	Mon Jun  3 22:43:11 2002
@@ -3,7 +3,11 @@
 
 /* PAGE_SHIFT determines the page size */
 #define PAGE_SHIFT	12
+#ifndef __ASSEMBLY__
 #define PAGE_SIZE	(1UL << PAGE_SHIFT)
+#else
+#define PAGE_SIZE	(1 << PAGE_SHIFT)
+#endif
 #define PAGE_MASK	(~(PAGE_SIZE-1))
 
 #ifdef __KERNEL__
diff -urN v2.5.20/include/asm-i386/thread_info.h smallstack-2.5.20.diff/include/asm-i386/thread_info.h
--- v2.5.20/include/asm-i386/thread_info.h	Tue Jun  4 17:59:46 2002
+++ smallstack-2.5.20.diff/include/asm-i386/thread_info.h	Tue Jun  4 20:58:55 2002
@@ -9,6 +9,7 @@
 
 #ifdef __KERNEL__
 
+#include <asm/page.h>
 #ifndef __ASSEMBLY__
 #include <asm/processor.h>
 #endif
@@ -28,9 +29,11 @@
 	__s32			preempt_count; /* 0 => preemptable, <0 => BUG */
 
 	mm_segment_t		addr_limit;	/* thread address space:
+						   0 for interrupts: illegal
 					 	   0-0xBFFFFFFF for user-thead
 						   0-0xFFFFFFFF for kernel-thread
 						*/
+	struct thread_info	*irq_stack;	/* pointer to cpu irq stack */
 
 	__u8			supervisor_stack[0];
 };
@@ -44,6 +47,7 @@
 #define TI_CPU		0x0000000C
 #define TI_PRE_COUNT	0x00000010
 #define TI_ADDR_LIMIT	0x00000014
+#define TI_IRQ_STACK	0x00000018
 
 #endif
 
@@ -52,41 +56,40 @@
 /*
  * macros/functions for gaining access to the thread information structure
  */
-#ifndef __ASSEMBLY__
-#define INIT_THREAD_INFO(tsk)			\
-{						\
-	task:		&tsk,			\
-	exec_domain:	&default_exec_domain,	\
-	flags:		0,			\
-	cpu:		0,			\
-	addr_limit:	KERNEL_DS,		\
-}
+#define THREAD_ORDER	0
 
+#ifndef __ASSEMBLY__
 #define init_thread_info	(init_thread_union.thread_info)
 #define init_stack		(init_thread_union.stack)
 
+/* thread information allocation */
+#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER)
+#define alloc_thread_info() ((struct thread_info *) __get_free_pages(GFP_KERNEL,THREAD_ORDER))
+#define free_thread_info(ti) free_pages((unsigned long) (ti), THREAD_ORDER)
+#define get_thread_info(ti) get_task_struct((ti)->task)
+#define put_thread_info(ti) put_task_struct((ti)->task)
+
 /* how to get the thread information struct from C */
 static inline struct thread_info *current_thread_info(void)
 {
 	struct thread_info *ti;
-	__asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~8191UL));
+	__asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~(THREAD_SIZE - 1)));
 	return ti;
 }
 
-/* thread information allocation */
-#define THREAD_SIZE (2*PAGE_SIZE)
-#define alloc_thread_info() ((struct thread_info *) __get_free_pages(GFP_KERNEL,1))
-#define free_thread_info(ti) free_pages((unsigned long) (ti), 1)
-#define get_thread_info(ti) get_task_struct((ti)->task)
-#define put_thread_info(ti) put_task_struct((ti)->task)
-
 #else /* !__ASSEMBLY__ */
 
+#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER)
+
 /* how to get the thread information struct from ASM */
 #define GET_THREAD_INFO(reg) \
-	movl $-8192, reg; \
+	movl $-THREAD_SIZE, reg; \
 	andl %esp, reg
 
+/* use this one if reg already contains %esp */
+#define GET_THREAD_INFO_WITH_ESP(reg) \
+	andl $-THREAD_SIZE, reg
+
 #endif
 
 /*

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2002-06-09 18:52 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <mailman.1023370621.16639.linux-kernel2news@redhat.com>
2002-06-06 17:37 ` [RFC] 4KB stack + irq stack for x86 Pete Zaitcev
2002-06-07  1:06   ` David S. Miller
2002-06-06 20:55 Ulrich Weigand
2002-06-06 21:19 ` David Mosberger
2002-06-06 22:10   ` Martin J. Bligh
2002-06-07  0:59   ` William Lee Irwin III
     [not found] <OF70FD985F.A9C66B00-ONC1256BD0.0069C993@de.ibm.com.suse.lists.linux.kernel>
2002-06-06 19:49 ` Andi Kleen
2002-06-06 20:27   ` David Mosberger
2002-06-07 11:28   ` Maciej W. Rozycki
  -- strict thread matches above, loose matches on Subject: below --
2002-06-06 19:24 Ulrich Weigand
2002-06-06 13:32 Ulrich Weigand
     [not found] <20020604225539.F9111@redhat.com.suse.lists.linux.kernel>
     [not found] ` <Pine.LNX.4.44.0206050820100.2941-100000@home.transmeta.com.suse.lists.linux.kernel>
     [not found]   ` <20020605144357.A4697@redhat.com.suse.lists.linux.kernel>
2002-06-05 20:40     ` Andi Kleen
2002-06-05 20:55       ` Linus Torvalds
2002-06-05  2:55 Benjamin LaHaise
2002-06-05 15:33 ` Linus Torvalds
2002-06-05 18:43   ` Benjamin LaHaise
2002-06-05 18:53     ` Linus Torvalds
2002-06-05 21:07       ` Benjamin LaHaise
2002-06-05 22:15 ` Steve Lord
2002-06-05 22:31   ` Benjamin LaHaise
2002-06-05 23:13     ` David S. Miller
2002-06-06  0:24       ` Larry McVoy
2002-06-06  1:15       ` Andi Kleen
2002-06-02 15:52         ` Pavel Machek
2002-06-09 18:50           ` Andi Kleen
2002-06-06  1:42         ` Benjamin LaHaise
2002-06-06  2:30           ` Stephen Lord

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox