Messages in this thread | | | Date | Tue, 26 Aug 2008 15:55:14 -0400 | From | Jeff Garzik <> | Subject | Re: [Bug #11342] Linux 2.6.27-rc3: kernel BUG at mm/vmalloc.c - bisected |
| |
Linus Torvalds wrote: > The downsides of inlining are big enough from both a debugging and a real > code generation angle (eg stack usage like this), that the upsides > (_somesimes_ smaller kernel, possibly slightly faster code) simply aren't > relevant. > > So the "noinline" was random, yes, but this is a real issue. Looking at > checkstack output for a saner config (NR_CPUS=16), the top entries for me > are things like > > ide_generic_init [vmlinux]: 1384 > idefloppy_ioctl [vmlinux]: 1208 > e1000_check_options [vmlinux]: 1152 > ... > > which are "leaf" functions. They are broken as hell (the e1000 is > apparently because it builds structs on the stack that should all be > "static const", for example), but they are different from something like > the module init sequence in that they are not going to affect anything > else.
e1000_check_options builds a struct (singular) on the stack, really... struct e1000_option is reasonably small.
The problem, which has also shown itself in large ioctl-style switch{} statements, is that gcc will generate code such that the stack usage from independent code branches
if {cond1} { char buster1[1000]; foo(buster1); } else if (cond2) { char buster2[1000]; foo(buster2); }
are added together, not noticed as mutually exclusive.
Of course, adding 'static const' as you noted is a reasonable workaround, but gcc is really annoying WRT stack allocation in this manner.
I had problems in the past, before struct ethtool_ops, with like ethtool ioctl switch statements using gobs of stack. In fact, that was a big motivation for struct ethtool_ops.
Jeff
| |