Messages in this thread | | | Date | Mon, 22 Jun 1998 15:11:18 +0200 (MET DST) | From | Bernd Schmidt <> | Subject | Re: 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
| |