lkml.org 
[lkml]   [1998]   [Jun]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: How much kernel stack do we need?
> 
> > I have a patch that makes the stack size configurable (I've even tested it...)
> > which I could provide if someone is interested.
>
> I am _very_ interested. I'll put it on the Linux MM
> (http://www.phys.uu.nl/~riel/mm-patch/) immediately!

I've attached the patch. I hope I caught everything that depends on the
kernel stack size. To change the stack size, all you should need to do is to
change the two new defines in asm/page.h.
Note that this patch only works for i386, the other ports are not updated
since I can't test them.

I've also attached the output of the stack checker script. It shows that the
patch is currently not safe (certainly not if you use NTFS or optcd, probably
not in other cases), but that it might be possible to make it safe.

Bernd

*** ./arch/i386/kernel/entry.S.orig-1 Wed Jun 17 19:37:19 1998
--- ./arch/i386/kernel/entry.S Thu Jun 18 12:59:58 1998
***************
*** 45,50 ****
--- 45,51 ----
#include <asm/segment.h>
#define ASSEMBLY
#include <asm/smp.h>
+ #include <asm/page.h>

EBX = 0x00
ECX = 0x04
*************** ENOSYS = 38
*** 109,115 ****

#define GET_CURRENT(reg) \
movl %esp, reg; \
! andl $-8192, reg;

ENTRY(lcall7)
pushfl # We get a different stack layout with call gates,
--- 110,116 ----

#define GET_CURRENT(reg) \
movl %esp, reg; \
! andl $-KERNEL_STACK_SIZE, reg;

ENTRY(lcall7)
pushfl # We get a different stack layout with call gates,
*************** ENTRY(lcall7)
*** 123,129 ****
movl %ecx,CS(%esp) #
movl %esp,%ebx
pushl %ebx
! andl $-8192,%ebx # GET_CURRENT
movl exec_domain(%ebx),%edx # Get the execution domain
movl 4(%edx),%edx # Get the lcall7 handler for the domain
call *%edx
--- 124,130 ----
movl %ecx,CS(%esp) #
movl %esp,%ebx
pushl %ebx
! andl $-KERNEL_STACK_SIZE,%ebx # GET_CURRENT
movl exec_domain(%ebx),%edx # Get the execution domain
movl 4(%edx),%edx # Get the lcall7 handler for the domain
call *%edx
*** ./arch/i386/kernel/irq.h.orig-1 Wed Jun 17 20:17:48 1998
--- ./arch/i386/kernel/irq.h Thu Jun 18 13:05:13 1998
*************** static inline void irq_exit(int cpu, uns
*** 140,149 ****
#define IRQ_NAME2(nr) nr##_interrupt(void)
#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)

- #define GET_CURRENT \
- "movl %esp, %ebx\n\t" \
- "andl $-8192, %ebx\n\t"
#ifdef __SMP__

/*
--- 140,145 ----
*** ./arch/i386/kernel/head.S.orig-1 Wed Jun 17 20:45:00 1998
--- ./arch/i386/kernel/head.S Thu Jun 18 12:58:30 1998
*************** rp_sidt:
*** 412,418 ****
ret

ENTRY(stack_start)
! .long SYMBOL_NAME(init_task_union)+8192
.long __KERNEL_DS

/* This is the default interrupt "handler" :-) */
--- 412,418 ----
ret

ENTRY(stack_start)
! .long SYMBOL_NAME(init_task_union)+KERNEL_STACK_SIZE
.long __KERNEL_DS

/* This is the default interrupt "handler" :-) */
*** ./arch/i386/kernel/process.c.orig-1 Thu Jun 18 12:37:51 1998
--- ./arch/i386/kernel/process.c Thu Jun 18 12:58:51 1998
*************** int copy_thread(int nr, unsigned long cl
*** 511,517 ****
p->tss.fs = __USER_DS;
p->tss.gs = __USER_DS;
p->tss.ss0 = __KERNEL_DS;
! p->tss.esp0 = 2*PAGE_SIZE + (unsigned long) p;
childregs = ((struct pt_regs *) (p->tss.esp0)) - 1;
p->tss.esp = (unsigned long) childregs;
#ifdef __SMP__
--- 511,517 ----
p->tss.fs = __USER_DS;
p->tss.gs = __USER_DS;
p->tss.ss0 = __KERNEL_DS;
! p->tss.esp0 = KERNEL_STACK_SIZE + (unsigned long) p;
childregs = ((struct pt_regs *) (p->tss.esp0)) - 1;
p->tss.esp = (unsigned long) childregs;
#ifdef __SMP__
*** ./arch/i386/lib/getuser.S.orig-1 Wed Jun 17 21:19:06 1998
--- ./arch/i386/lib/getuser.S Thu Jun 18 13:03:43 1998
***************
*** 21,26 ****
--- 21,29 ----
* as they get called from within inline assembly.
*/

+ #define ASSEMBLY
+ #include <asm/page.h>
+
addr_limit = 12

.text
*************** addr_limit = 12
*** 28,34 ****
.globl __get_user_1
__get_user_1:
movl %esp,%edx
! andl $0xffffe000,%edx
cmpl addr_limit(%edx),%eax
jae bad_get_user
1: movzbl (%eax),%edx
--- 31,37 ----
.globl __get_user_1
__get_user_1:
movl %esp,%edx
! andl $-KERNEL_STACK_SIZE,%edx
cmpl addr_limit(%edx),%eax
jae bad_get_user
1: movzbl (%eax),%edx
*************** __get_user_2:
*** 41,47 ****
addl $1,%eax
movl %esp,%edx
jc bad_get_user
! andl $0xffffe000,%edx
cmpl addr_limit(%edx),%eax
jae bad_get_user
2: movzwl -1(%eax),%edx
--- 44,50 ----
addl $1,%eax
movl %esp,%edx
jc bad_get_user
! andl $-KERNEL_STACK_SIZE,%edx
cmpl addr_limit(%edx),%eax
jae bad_get_user
2: movzwl -1(%eax),%edx
*************** __get_user_4:
*** 54,60 ****
addl $3,%eax
movl %esp,%edx
jc bad_get_user
! andl $0xffffe000,%edx
cmpl addr_limit(%edx),%eax
jae bad_get_user
3: movl -3(%eax),%edx
--- 57,63 ----
addl $3,%eax
movl %esp,%edx
jc bad_get_user
! andl $-KERNEL_STACK_SIZE,%edx
cmpl addr_limit(%edx),%eax
jae bad_get_user
3: movl -3(%eax),%edx
*** ./arch/i386/lib/putuser.S.orig-1 Thu Jun 18 12:33:33 1998
--- ./arch/i386/lib/putuser.S Thu Jun 18 13:03:29 1998
***************
*** 20,25 ****
--- 20,28 ----
* as they get called from within inline assembly.
*/

+ #define ASSEMBLY
+ #include <asm/page.h>
+
addr_limit = 12

.text
*************** addr_limit = 12
*** 27,33 ****
.globl __put_user_1
__put_user_1:
movl %esp,%ecx
! andl $0xffffe000,%ecx
cmpl addr_limit(%ecx),%eax
jae bad_put_user
1: movb %dl,(%eax)
--- 30,36 ----
.globl __put_user_1
__put_user_1:
movl %esp,%ecx
! andl $-KERNEL_STACK_SIZE,%ecx
cmpl addr_limit(%ecx),%eax
jae bad_put_user
1: movb %dl,(%eax)
*************** __put_user_2:
*** 40,46 ****
addl $1,%eax
movl %esp,%ecx
jc bad_put_user
! andl $0xffffe000,%ecx
cmpl addr_limit(%ecx),%eax
jae bad_put_user
2: movw %dx,-1(%eax)
--- 43,49 ----
addl $1,%eax
movl %esp,%ecx
jc bad_put_user
! andl $-KERNEL_STACK_SIZE,%ecx
cmpl addr_limit(%ecx),%eax
jae bad_put_user
2: movw %dx,-1(%eax)
*************** __put_user_4:
*** 53,59 ****
addl $3,%eax
movl %esp,%ecx
jc bad_put_user
! andl $0xffffe000,%ecx
cmpl addr_limit(%ecx),%eax
jae bad_put_user
3: movl %edx,-3(%eax)
--- 56,62 ----
addl $3,%eax
movl %esp,%ecx
jc bad_put_user
! andl $-KERNEL_STACK_SIZE,%ecx
cmpl addr_limit(%ecx),%eax
jae bad_put_user
3: movl %edx,-3(%eax)
*** ./include/asm-i386/processor.h.orig-1 Wed Jun 17 15:16:02 1998
--- ./include/asm-i386/processor.h Thu Jun 18 14:26:41 1998
*************** extern inline unsigned long thread_saved
*** 217,225 ****
/*
* NOTE! The task struct and the stack go together
*/
#define alloc_task_struct() \
! ((struct task_struct *) __get_free_pages(GFP_KERNEL,1))
! #define free_task_struct(p) free_pages((unsigned long)(p),1)

#define init_task (init_task_union.task)
#define init_stack (init_task_union.stack)
--- 217,226 ----
/*
* NOTE! The task struct and the stack go together
*/
+
#define alloc_task_struct() \
! ((struct task_struct *) __get_free_pages(GFP_KERNEL, KERNEL_STACK_ORDER))
! #define free_task_struct(p) free_pages((unsigned long)(p), KERNEL_STACK_ORDER)

#define init_task (init_task_union.task)
#define init_stack (init_task_union.stack)
*** ./include/asm-i386/current.h.orig-1 Wed Jun 17 15:16:06 1998
--- ./include/asm-i386/current.h Thu Jun 18 12:55:34 1998
***************
*** 1,10 ****
#ifndef _I386_CURRENT_H
#define _I386_CURRENT_H

static inline struct task_struct * get_current(void)
{
struct task_struct *current;
! __asm__("andl %%esp,%0; ":"=r" (current) : "0" (~8191UL));
return current;
}

--- 1,17 ----
#ifndef _I386_CURRENT_H
#define _I386_CURRENT_H

+ union task_union {
+ struct task_struct task;
+ unsigned long stack[KERNEL_STACK_SIZE / sizeof (unsigned long)];
+ };
+
+ extern union task_union init_task_union;
+
static inline struct task_struct * get_current(void)
{
struct task_struct *current;
! __asm__("andl %%esp,%0; ":"=r" (current) : "0" (~(KERNEL_STACK_SIZE - 1)));
return current;
}

*** ./include/asm-i386/page.h.orig-1 Thu Jun 18 12:58:11 1998
--- ./include/asm-i386/page.h Thu Jun 18 14:16:33 1998
*************** typedef unsigned long pgprot_t;
*** 87,92 ****
--- 87,98 ----
#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
#define MAP_NR(addr) (__pa(addr) >> PAGE_SHIFT)

+ /*
+ * Size and gfp order of a kernel stack.
+ */
+ #define KERNEL_STACK_ORDER 0
+ #define KERNEL_STACK_SIZE 4096
+
#endif /* __KERNEL__ */

#endif /* _I386_PAGE_H */
*** ./include/linux/sched.h.orig-1 Wed Jun 17 15:15:55 1998
--- ./include/linux/sched.h Thu Jun 18 14:26:41 1998
*************** struct task_struct {
*** 374,386 ****
/* locks */ INIT_LOCKS \
}

- union task_union {
- struct task_struct task;
- unsigned long stack[2048];
- };
- extern union task_union init_task_union;
-
extern struct mm_struct init_mm;
extern struct task_struct *task[NR_TASKS];

--- 374,379 ----


These are variable size arrays on the stack: "reorder" is from the eata
scsi driver.

c03af2ac <reorder+0x3c> subl %eax,%esp
c03af2a7 <reorder+0x37> subl %eax,%esp
c03af2a2 <reorder+0x32> subl %eax,%esp
c038b0f0 <reorder+0x3c> subl %eax,%esp
c038b0eb <reorder+0x37> subl %eax,%esp
c038b0e6 <reorder+0x32> subl %eax,%esp
c02f8de9 <DumpData+0x21> subl %eax,%esp
c018f823 <ncp_rename+0x4b> subl %eax,%esp
c018f80c <ncp_rename+0x34> subl %eax,%esp
c018f5e3 <ncp_rmdir+0x27> subl %eax,%esp
c018f499 <ncp_mkdir+0x35> subl %eax,%esp
c018f31c <ncp_create+0x30> subl %eax,%esp
c018eedb <ncp_lookup+0x3f> subl %eax,%esp
c018e57e <ncp_lookup_validate+0x46> subl %eax,%esp
c01716b1 <nfs_sillyrename+0x41> subl %edi,%esp

These are the sizes of stack frames for particularly excessive functions.
The compiler used was egcs-1.0.3.

c2c ewrk3_ioctl
a64 cdromread (this is in optcd)
81c ntfs_get_free_cluster_count
5c0 UMSDOS_ioctl_dir
584 huft_build
520 inflate_dynamic
490 inflate_fixed
40c coda_follow_link
408 root_nfs_name
3bc dmascc_init
388 rd_load_image
304 wv_hw_reset
2f4 gdth_halt
2e8 wavelan_ioctl
2b0 elf_core_dump
298 eata2x_detect
288 vt_ioctl
26c umsdos_find
254 block_write
24c block_read
248 umsdos_rename_f
248 umsdos_readdir_x
244 UMSDOS_unlink
238 isdn_ioctl
230 umsdos_lookup_x
224 UMSDOS_link
218 xd_wd_init_drive
218 fdomain_16x0_biosparam
218 cdrom_read_intr
210 arc90io_rx
210 arc20020_rx
20c init_pdc4030
208 xd_seagate_init_drive
204 isa_getid
200 scsi_make_blocked_list
200 print_selftest
200 mcdx_open
200 eata_pio_detect
200 eata_detect
200 cdrom_buffer_sectors
200 br_avl_remove
200 br_avl_insert
1e8 reiserfs_delete_item
1cc reiserfs_cut_from_item
1cc isdn_set_allcfg
1c0 eata_proc_info
1b0 isdn_get_allcfg
1ac reiserfs_paste_into_item
1a8 reiserfs_insert_item
1a4 secure_tcp_syn_cookie
1a4 depca_ioctl
1a4 check_tcp_syn_cookie
19c ip_setsockopt
198 ncp_lookup
198 aout_core_dump
194 hfs_cat_move
18c gdth_set_asc_info
180 ncp_lookup_validate
180 idetape_chrdev_ioctl
180 gdth_set_info
178 ncp_read_super
178 ncp_mkdir
178 ncp_create
174 set_serial_info
174 capi_message2str
170 fat_readdirx
170 adfs_readdir
16c do_reiserfs_rename
168 ncp_make_open
168 extract_entropy
168 cdu31a_init
164 aic7xxx_detect
160 set_serial_info
160 actcapi_dispatch
15c nlmclnt_proc
15c internal_notify_change
158 umsdos_writeentry
158 idefloppy_get_capacity
150 nlmclnt_reclaim
150 idefloppy_get_flexible_disk_page
150 device_exists
144 umsdos_isempty
144 coda_venus_readdir
140 vortex_probe1
13c idetape_space_over_filemarks
13c idetape_rewind_tape
13c idetape_position_tape
13c idetape_mtioctop
13c idetape_get_mode_sense_results
13c idetape_flush_tape_buffers
13c idetape_chrdev_release
13c idetape_chrdev_open
13c idefloppy_release
13c idefloppy_open
13c cap_info_write
138 tcp_v4_conn_request
138 do_execve
134 sysv_file_read
134 read_core
134 cap_info_read
134 autofs_root_ioctl
130 qcam_ioctl
12c tcp_v6_conn_request
12c ni65_interrupt
12c load_elf_binary
12c cap_readdir
12c adfs_read_inode
128 vc_resize
128 nat_readdir
128 mcdx_xfer
128 UMSDOS_rmdir
128 UMSDOS_mkdir
128 B1_load_t4file
128 B1_load_config
124 stli_poll
124 lookup_inode
124 flush_dev
124 advansys_detect
120 umsdos_create_any
120 scan_scsis
120 hfs_do_read
120 autofs_notify_daemon
11c seagate_st0x_biosparam
11c qcam_ioctl
118 umsdos_locate_path
118 dbl_readdir
118 adfs_lookup
118 UMSDOS_readdir
114 check_devices
114 NCR53c8xx_run_tests
110 sys_sendmsg
10c load_seeprom
10c isofs_get_last_session
10c fat_read_super
108 lookup_by_inode
108 BusLogic_InitializeProbeInfoList
104 sys_recvmsg
104 scsi_test_unit_ready
104 scsi_request_sense
100 umsdos_evalrecsize
100 sys_reboot
100 msg
100 msg
100 msg
100 msg
100 check_scsidisk_media_change

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu

\
 
 \ /
  Last update: 2005-03-22 13:43    [W:0.857 / U:0.128 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site