On Tue, 2007-09-11 at 15:05 -0500, Eric Sandeen wrote:
I sent this same message to LKML a while ago, but thought I'd get it a more targeted audience:
========================= Noticed today that the combination of 4KSTACKS and DEBUG_STACKOVERFLOW config options is a bit deadly.
DEBUG_STACKOVERFLOW warns in do_IRQ if we're within THREAD_SIZE/8 of the end of useable stack space, or 512 bytes on a 4k stack.
If we are, then it goes down the dump_stack path, which uses most, if not all, of the remaining stack, thereby turning a well-intentioned warning into a full-blown catastrophe.
The callchain from the warning looks something like this, with stack usage shown as found on my x86 box:
4 dump_stack 4 show_trace 8 show_trace_log_lvl 4 dump_trace print_context_stack 12 print_trace_address print_symbol 232 __print_symbol 164 sprint_symbol 20 printk ___ 448
448 bytes to tell us that we're within 512 bytes (or less) of certain doom... and I think there's call overhead on top of that?
The large stack usage in those 2 functions is due to big char arrays, of size KSYM_NAME_LEN (128 bytes) and KSYM_SYMBOL_LEN (223 bytes).
IOW, the stack warning effectively reduces useful stack left in our itty bitty 4k stacks by over 10%.
...
=========================
In light of this, I'd like to propose that we turn off DEBUG_STACKOVERFLOW in Fedora, at least on x86/4KSTACKS. I think it does more harm than good; the warning is going to turn deadly most of the time.
I also had sent a patch to LKML to print whether or not the stack was overflowing, or had ever overflowed, on a kernel panic. It's not yet been merged.
... any comments? I can file a bug but thought some discussion might be in order.
Thanks,
Sorry for butting in... but isn't disabling STACKOVERFLOW the wrong answer to this problem? Does anyone see any reason why both sprint_symbol and __print_symbol shouldn't use dynamically allocated buffers instead of wasting stack space? *
- GIlboa * If performance is an issue, memory can be statically allocated per CPU with additional locking in dump_trace.