* Bug in 2.6.11.11 - udp_poll(), fragments + CONFIG_HIGHMEM
@ 2005-05-30 14:42 Steven Hand
2005-05-30 21:17 ` Andrew Morton
2005-05-30 21:49 ` Herbert Xu
0 siblings, 2 replies; 5+ messages in thread
From: Steven Hand @ 2005-05-30 14:42 UTC (permalink / raw)
To: linux-net, linux-kernel; +Cc: davem, Steven.Hand
Summary: with CONFIG_HIGHMEM set, net/ipv4/udp.c::udp_poll()
fails when rx'ing an skb with fragments.
Present in [at least] 2.6.11.*, 2.6.10
Details:
User space code polling on a blocking socket fd receives an
skb with fragments -- this is very unlikely in the common
case but can happen with encapsulation etc; however its pretty
much guaranteed to happen under Xen 2.x when communicating
between dom0 and domU.
Example backtrace from console:
kernel: Badness in local_bh_enable at kernel/softirq.c:140
kernel: [local_bh_enable+130/144] local_bh_enable+0x82/0x90
kernel: [skb_checksum+317/704] skb_checksum+0x13d/0x2c0
kernel: [udp_poll+154/352] udp_poll+0x9a/0x160
kernel: [sock_poll+41/64] sock_poll+0x29/0x40
kernel: [do_pollfd+149/160] do_pollfd+0x95/0xa0
kernel: [do_poll+106/208] do_poll+0x6a/0xd0
kernel: [sys_poll+353/576] sys_poll+0x161/0x240
kernel: [sys_gettimeofday+60/144] sys_gettimeofday+0x3c/0x90
kernel: [__pollwait+0/208] __pollwait+0x0/0xd0
kernel: [syscall_call+7/11] syscall_call+0x7/0xb
Reconstructed forward trace:
net/ipv4/udp.c:1334 spin_lock_irq()
net/ipv4/udp.c:1336 udp_checksum_complete()
net/core/skbuff.c:1069 skb_shinfo(skb)->nr_frags > 1
net/core/skbuff.c:1086 kunmap_skb_frag()
net/core/skbuff.h:1087 local_bh_enable()
kernel/softirq.c:0140 WARN_ON(irqs_disabled());
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: Bug in 2.6.11.11 - udp_poll(), fragments + CONFIG_HIGHMEM 2005-05-30 14:42 Bug in 2.6.11.11 - udp_poll(), fragments + CONFIG_HIGHMEM Steven Hand @ 2005-05-30 21:17 ` Andrew Morton 2005-05-30 22:47 ` David S. Miller 2005-05-30 21:49 ` Herbert Xu 1 sibling, 1 reply; 5+ messages in thread From: Andrew Morton @ 2005-05-30 21:17 UTC (permalink / raw) To: Steven Hand; +Cc: linux-net, linux-kernel, davem, Steven.Hand Steven Hand <Steven.Hand@cl.cam.ac.uk> wrote: > > Summary: with CONFIG_HIGHMEM set, net/ipv4/udp.c::udp_poll() > fails when rx'ing an skb with fragments. > > Present in [at least] 2.6.11.*, 2.6.10 > > > Details: > > User space code polling on a blocking socket fd receives an > skb with fragments -- this is very unlikely in the common > case but can happen with encapsulation etc; however its pretty > much guaranteed to happen under Xen 2.x when communicating > between dom0 and domU. > > > Example backtrace from console: > > kernel: Badness in local_bh_enable at kernel/softirq.c:140 > kernel: [local_bh_enable+130/144] local_bh_enable+0x82/0x90 > kernel: [skb_checksum+317/704] skb_checksum+0x13d/0x2c0 > kernel: [udp_poll+154/352] udp_poll+0x9a/0x160 > kernel: [sock_poll+41/64] sock_poll+0x29/0x40 > kernel: [do_pollfd+149/160] do_pollfd+0x95/0xa0 > kernel: [do_poll+106/208] do_poll+0x6a/0xd0 > kernel: [sys_poll+353/576] sys_poll+0x161/0x240 > kernel: [sys_gettimeofday+60/144] sys_gettimeofday+0x3c/0x90 > kernel: [__pollwait+0/208] __pollwait+0x0/0xd0 > kernel: [syscall_call+7/11] syscall_call+0x7/0xb > Yes, that still seems to be there: udp_poll ->spin_lock_irq() ->udp_checksum_complete ->__udp_checksum_complete ->skb_checksum ->kmap_skb_frag ->local_bh_disable That local_bh_disable() in kmap_skb_frag() looks weird and might be unnecessary. Does anyone know what it's there for? Replace it with local_irq_save()? ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Bug in 2.6.11.11 - udp_poll(), fragments + CONFIG_HIGHMEM 2005-05-30 21:17 ` Andrew Morton @ 2005-05-30 22:47 ` David S. Miller 0 siblings, 0 replies; 5+ messages in thread From: David S. Miller @ 2005-05-30 22:47 UTC (permalink / raw) To: akpm; +Cc: Steven.Hand, linux-net, linux-kernel From: Andrew Morton <akpm@osdl.org> Date: Mon, 30 May 2005 14:17:14 -0700 > That local_bh_disable() in kmap_skb_frag() looks weird and might be > unnecessary. Does anyone know what it's there for? Replace it with > local_irq_save()? The SKB kmap types are to be used only from BH context. So the local_bh_disable() is really necessary. This limitation causes problems elsewhere too, for example if the tg3 driver has to do the 4GB DMA boundary workaround on transmit, then it tries to do a skb_copy() in IRQ disabled context, which thusly also tries to do some SKB kmapping and triggers the same assertion seen here. Both UDP and tg3 need to be fixed to not do these operations from such illegal contexts. It really stinks that this error on triggers with highmem enabled. We would have seen both bugs much earlier on otherwise. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Bug in 2.6.11.11 - udp_poll(), fragments + CONFIG_HIGHMEM 2005-05-30 14:42 Bug in 2.6.11.11 - udp_poll(), fragments + CONFIG_HIGHMEM Steven Hand 2005-05-30 21:17 ` Andrew Morton @ 2005-05-30 21:49 ` Herbert Xu 2005-05-30 22:50 ` David S. Miller 1 sibling, 1 reply; 5+ messages in thread From: Herbert Xu @ 2005-05-30 21:49 UTC (permalink / raw) To: Steven Hand; +Cc: linux-net, linux-kernel, davem, Steven.Hand, netdev Steven Hand <Steven.Hand@cl.cam.ac.uk> wrote: > > Reconstructed forward trace: > > net/ipv4/udp.c:1334 spin_lock_irq() > net/ipv4/udp.c:1336 udp_checksum_complete() > net/core/skbuff.c:1069 skb_shinfo(skb)->nr_frags > 1 > net/core/skbuff.c:1086 kunmap_skb_frag() > net/core/skbuff.h:1087 local_bh_enable() > kernel/softirq.c:0140 WARN_ON(irqs_disabled()); Thanks for catching this. The receive queue lock is never taken in IRQs (and should never be) so we can simply substitute bh for irq. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -738,7 +738,7 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long amount; amount = 0; - spin_lock_irq(&sk->sk_receive_queue.lock); + spin_lock_bh(&sk->sk_receive_queue.lock); skb = skb_peek(&sk->sk_receive_queue); if (skb != NULL) { /* @@ -748,7 +748,7 @@ int udp_ioctl(struct sock *sk, int cmd, */ amount = skb->len - sizeof(struct udphdr); } - spin_unlock_irq(&sk->sk_receive_queue.lock); + spin_unlock_bh(&sk->sk_receive_queue.lock); return put_user(amount, (int __user *)arg); } @@ -848,12 +848,12 @@ csum_copy_err: /* Clear queue. */ if (flags&MSG_PEEK) { int clear = 0; - spin_lock_irq(&sk->sk_receive_queue.lock); + spin_lock_bh(&sk->sk_receive_queue.lock); if (skb == skb_peek(&sk->sk_receive_queue)) { __skb_unlink(skb, &sk->sk_receive_queue); clear = 1; } - spin_unlock_irq(&sk->sk_receive_queue.lock); + spin_unlock_bh(&sk->sk_receive_queue.lock); if (clear) kfree_skb(skb); } @@ -1334,7 +1334,7 @@ unsigned int udp_poll(struct file *file, struct sk_buff_head *rcvq = &sk->sk_receive_queue; struct sk_buff *skb; - spin_lock_irq(&rcvq->lock); + spin_lock_bh(&rcvq->lock); while ((skb = skb_peek(rcvq)) != NULL) { if (udp_checksum_complete(skb)) { UDP_INC_STATS_BH(UDP_MIB_INERRORS); @@ -1345,7 +1345,7 @@ unsigned int udp_poll(struct file *file, break; } } - spin_unlock_irq(&rcvq->lock); + spin_unlock_bh(&rcvq->lock); /* nothing to see, move along */ if (skb == NULL) ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Bug in 2.6.11.11 - udp_poll(), fragments + CONFIG_HIGHMEM 2005-05-30 21:49 ` Herbert Xu @ 2005-05-30 22:50 ` David S. Miller 0 siblings, 0 replies; 5+ messages in thread From: David S. Miller @ 2005-05-30 22:50 UTC (permalink / raw) To: herbert; +Cc: Steven.Hand, linux-net, linux-kernel, netdev From: Herbert Xu <herbert@gondor.apana.org.au> Date: Tue, 31 May 2005 07:49:30 +1000 > Thanks for catching this. The receive queue lock is never taken > in IRQs (and should never be) so we can simply substitute bh for > irq. > > Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Applied, thanks Herbert. ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2005-05-30 22:54 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2005-05-30 14:42 Bug in 2.6.11.11 - udp_poll(), fragments + CONFIG_HIGHMEM Steven Hand 2005-05-30 21:17 ` Andrew Morton 2005-05-30 22:47 ` David S. Miller 2005-05-30 21:49 ` Herbert Xu 2005-05-30 22:50 ` David S. Miller
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®