Recently, it was reported to me that you could provoke a double fault
panic with the NDISulator if you did "ifconfig ndis0 10.0.0.1/24," whereas "ifconfig ndis0 10.0.0.1/24 up" worked fine. The double fault was caused by the ifconfig thread running out of kernel stack space. (This was partly due to the NDIsulator using a couple of big buffers on the stack, but even after fixing that the double fault persisted.) It turns out that ndis_init() is called in both cases, but in the first case the code path passes through ieee80211_ioctl(), and it turns out ieee80211_ioctl() consumes a whopping 2400 bytes of stack space. Apparently, gcc -O2 causes the ieee80211_ioctl_get80211() routine to be inlined into ieee80211_ioctl(), and for some reason which I do not fully understand, this causes ieee80211_ioctl() to consume an extra 2K of stack space. To prevent this overly agressive optimization, ieee80211_ioctl_get80211() is now declared with __attribute__ ((noinline)). With this change, ieee80211_ioctl() now only reserves about 200 bytes of stack instead of 2400.
This commit is contained in:
parent
9c6519b0a2
commit
c788ca3e3c
@ -1224,6 +1224,25 @@ ieee80211_ioctl_getwmeparam(struct ieee80211com *ic, struct ieee80211req *ireq)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* When building the kernel with -O2 on the i386 architecture, gcc
|
||||
* seems to want to inline this function into ieee80211_ioctl()
|
||||
* (which is the only routine that calls it). When this happens,
|
||||
* ieee80211_ioctl() ends up consuming an additional 2K of stack
|
||||
* space. (Exactly why it needs so much is unclear.) The problem
|
||||
* is that it's possible for ieee80211_ioctl() to invoke other
|
||||
* routines (including driver init functions) which could then find
|
||||
* themselves perilously close to exhausting the stack.
|
||||
*
|
||||
* To avoid this, we deliberately prevent gcc from inlining this
|
||||
* routine. Another way to avoid this is to use less agressive
|
||||
* optimization when compiling this file (i.e. -O instead of -O2)
|
||||
* but special-casing the compilation of this one module in the
|
||||
* build system would be awkward.
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((noinline))
|
||||
#endif
|
||||
static int
|
||||
ieee80211_ioctl_get80211(struct ieee80211com *ic, u_long cmd, struct ieee80211req *ireq)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user