Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The stack size used in kernel development

I'm developing an operating system and rather than programming the kernel, I'm designing the kernel. This operating system is targeted at the x86 architecture and my target is for modern computers. The estimated number of required RAM is 256Mb or more.

What is a good size to make the stack for each thread run on the system? Should I try to design the system in such a way that the stack can be extended automatically if the maximum length is reached?

I think if I remember correctly that a page in RAM is 4k or 4096 bytes and that just doesn't seem like a lot to me. I can definitely see times, especially when using lots of recursion, that I would want to have more than 1000 integars in RAM at once. Now, the real solution would be to have the program doing this by using malloc and manage its own memory resources, but really I would like to know the user opinion on this.

Is 4k big enough for a stack with modern computer programs? Should the stack be bigger than that? Should the stack be auto-expanding to accommodate any types of sizes? I'm interested in this both from a practical developer's standpoint and a security standpoint.

Is 4k too big for a stack? Considering normal program execution, especially from the point of view of classes in C++, I notice that good source code tends to malloc/new the data it needs when classes are created, to minimize the data being thrown around in a function call.

What I haven't even gotten into is the size of the processor's cache memory. Ideally, I think the stack would reside in the cache to speed things up and I'm not sure if I need to achieve this, or if the processor can handle it for me. I was just planning on using regular boring old RAM for testing purposes. I can't decide. What are the options?

like image 320
Nicholas Flynt Avatar asked Oct 13 '08 04:10

Nicholas Flynt


2 Answers

Stack size depends on what your threads are doing. My advice:

  • make the stack size a parameter at thread creation time (different threads will do different things, and hence will need different stack sizes)
  • provide a reasonable default for those who don't want to be bothered with specifying a stack size (4K appeals to the control freak in me, as it will cause the stack-profligate to, er, get the signal pretty quickly)
  • consider how you will detect and deal with stack overflow. Detection can be tricky. You can put guard pages--empty--at the ends of your stack, and that will generally work. But you are relying on the behavior of the Bad Thread not to leap over that moat and start polluting what lays beyond. Generally that won't happen...but then, that's what makes the really tough bugs tough. An airtight mechanism involves hacking your compiler to generate stack checking code. As for dealing with a stack overflow, you will need a dedicated stack somewhere else on which the offending thread (or its guardian angel, whoever you decide that is--you're the OS designer, after all) will run.
  • I would strongly recommend marking the ends of your stack with a distinctive pattern, so that when your threads run over the ends (and they always do), you can at least go in post-mortem and see that something did in fact run off its stack. A page of 0xDEADBEEF or something like that is handy.

By the way, x86 page sizes are generally 4k, but they do not have to be. You can go with a 64k size or even larger. The usual reason for larger pages is to avoid TLB misses. Again, I would make it a kernel configuration or run-time parameter.

like image 106
bog Avatar answered Sep 30 '22 15:09

bog


Search for KERNEL_STACK_SIZE in linux kernel source code and you will find that it is very much architecture dependent - PAGE_SIZE, or 2*PAGE_SIZE etc (below is just some results - many intermediate output are deleted).

./arch/cris/include/asm/processor.h:
#define KERNEL_STACK_SIZE PAGE_SIZE

./arch/ia64/include/asm/ptrace.h:
# define KERNEL_STACK_SIZE_ORDER        3
# define KERNEL_STACK_SIZE_ORDER        2
# define KERNEL_STACK_SIZE_ORDER        1
# define KERNEL_STACK_SIZE_ORDER        0
#define IA64_STK_OFFSET         ((1 << KERNEL_STACK_SIZE_ORDER)*PAGE_SIZE)
#define KERNEL_STACK_SIZE       IA64_STK_OFFSET

./arch/ia64/include/asm/mca.h:
    u64 mca_stack[KERNEL_STACK_SIZE/8];
    u64 init_stack[KERNEL_STACK_SIZE/8];

./arch/ia64/include/asm/thread_info.h:
#define THREAD_SIZE         KERNEL_STACK_SIZE

./arch/ia64/include/asm/mca_asm.h:
#define MCA_PT_REGS_OFFSET      ALIGN16(KERNEL_STACK_SIZE-IA64_PT_REGS_SIZE)

./arch/parisc/include/asm/processor.h:
#define KERNEL_STACK_SIZE   (4*PAGE_SIZE)

./arch/xtensa/include/asm/ptrace.h:
#define KERNEL_STACK_SIZE (2 * PAGE_SIZE)

./arch/microblaze/include/asm/processor.h:
# define KERNEL_STACK_SIZE  0x2000
like image 44
Peter Teoh Avatar answered Sep 30 '22 15:09

Peter Teoh