diff options
author | Andrew Morton <akpm@linux-foundation.org> | 2009-02-12 16:43:17 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-02-12 16:43:17 -0800 |
commit | 99709372736a216f99eb32b76fba835a2bfc93a8 (patch) | |
tree | 62a84b976965436b841c65b63e52240d0b06bc29 /include/net | |
parent | fb0886745a75ce98bde3aac421adc69fe61a1905 (diff) | |
download | lwn-99709372736a216f99eb32b76fba835a2bfc93a8.tar.gz lwn-99709372736a216f99eb32b76fba835a2bfc93a8.zip |
net: don't use in_atomic() in gfp_any()
The problem is that in_atomic() will return false inside spinlocks if
CONFIG_PREEMPT=n. This will lead to deadlockable GFP_KERNEL allocations
from spinlocked regions.
Secondly, if CONFIG_PREEMPT=y, this bug solves itself because networking
will instead use GFP_ATOMIC from this callsite. Hence we won't get the
might_sleep() debugging warnings which would have informed us of the buggy
callsites.
Solve both these problems by switching to in_interrupt(). Now, if someone
runs a gfp_any() allocation from inside spinlock we will get the warning
if CONFIG_PREEMPT=y.
I reviewed all callsites and most of them were too complex for my little
brain and none of them documented their interface requirements. I have no
idea what this patch will do.
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net')
-rw-r--r-- | include/net/sock.h | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/include/net/sock.h b/include/net/sock.h index 5a3a151bd730..ce3b5b622683 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1308,7 +1308,7 @@ static inline int sock_writeable(const struct sock *sk) static inline gfp_t gfp_any(void) { - return in_atomic() ? GFP_ATOMIC : GFP_KERNEL; + return in_softirq() ? GFP_ATOMIC : GFP_KERNEL; } static inline long sock_rcvtimeo(const struct sock *sk, int noblock) |