summaryrefslogtreecommitdiff
path: root/net/core/sock.c
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2011-01-06 21:54:29 +0300
committerDavid S. Miller <davem@davemloft.net>2011-01-06 21:54:29 +0300
commit2c6607c611cb7bf0a6750bcea34a258144e302c5 (patch)
tree38156d2a938e5f346d7c4464e132132f7279dcba /net/core/sock.c
parent3610cda53f247e176bcbb7a7cca64bc53b12acdb (diff)
downloadlinux-2c6607c611cb7bf0a6750bcea34a258144e302c5.tar.xz
net: add POLLPRI to sock_def_readable()
Leonardo Chiquitto found poll() could block forever on tcp sockets and Urgent data was received, if the event flag only contains POLLPRI. He did a bisection and found commit 4938d7e0233 (poll: avoid extra wakeups in select/poll) was the source of the problem. Problem is TCP sockets use standard sock_def_readable() function for their sk_data_ready() handler, and sock_def_readable() doesnt signal POLLPRI. Only TCP is affected by the problem. Adding POLLPRI to the list of flags might trigger unnecessary schedules, but URGENT handling is such a seldom used feature this seems a good compromise. Thanks a lot to Leonardo for providing the bisection result and a test program as well. Reference : http://www.spinics.net/lists/netdev/msg151793.html Reported-and-bisected-by: Leonardo Chiquitto <leonardo.lists@gmail.com> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Tested-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/sock.c')
-rw-r--r--net/core/sock.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/net/core/sock.c b/net/core/sock.c
index a6b9e8061f34..a658aeb6d554 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1908,7 +1908,7 @@ static void sock_def_readable(struct sock *sk, int len)
rcu_read_lock();
wq = rcu_dereference(sk->sk_wq);
if (wq_has_sleeper(wq))
- wake_up_interruptible_sync_poll(&wq->wait, POLLIN |
+ wake_up_interruptible_sync_poll(&wq->wait, POLLIN | POLLPRI |
POLLRDNORM | POLLRDBAND);
sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
rcu_read_unlock();