mirror of
https://github.com/torvalds/linux.git
synced 2024-11-28 23:21:31 +00:00
dccp: annotate data-races in dccp_poll()
We changed tcp_poll() over time, bug never updated dccp.
Note that we also could remove dccp instead of maintaining it.
Fixes: 7c657876b6
("[DCCP]: Initial implementation")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://lore.kernel.org/r/20230818015820.2701595-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
76f33296d2
commit
cba3f17869
@ -315,11 +315,15 @@ EXPORT_SYMBOL_GPL(dccp_disconnect);
|
|||||||
__poll_t dccp_poll(struct file *file, struct socket *sock,
|
__poll_t dccp_poll(struct file *file, struct socket *sock,
|
||||||
poll_table *wait)
|
poll_table *wait)
|
||||||
{
|
{
|
||||||
__poll_t mask;
|
|
||||||
struct sock *sk = sock->sk;
|
struct sock *sk = sock->sk;
|
||||||
|
__poll_t mask;
|
||||||
|
u8 shutdown;
|
||||||
|
int state;
|
||||||
|
|
||||||
sock_poll_wait(file, sock, wait);
|
sock_poll_wait(file, sock, wait);
|
||||||
if (sk->sk_state == DCCP_LISTEN)
|
|
||||||
|
state = inet_sk_state_load(sk);
|
||||||
|
if (state == DCCP_LISTEN)
|
||||||
return inet_csk_listen_poll(sk);
|
return inet_csk_listen_poll(sk);
|
||||||
|
|
||||||
/* Socket is not locked. We are protected from async events
|
/* Socket is not locked. We are protected from async events
|
||||||
@ -328,20 +332,21 @@ __poll_t dccp_poll(struct file *file, struct socket *sock,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
mask = 0;
|
mask = 0;
|
||||||
if (sk->sk_err)
|
if (READ_ONCE(sk->sk_err))
|
||||||
mask = EPOLLERR;
|
mask = EPOLLERR;
|
||||||
|
shutdown = READ_ONCE(sk->sk_shutdown);
|
||||||
|
|
||||||
if (sk->sk_shutdown == SHUTDOWN_MASK || sk->sk_state == DCCP_CLOSED)
|
if (shutdown == SHUTDOWN_MASK || state == DCCP_CLOSED)
|
||||||
mask |= EPOLLHUP;
|
mask |= EPOLLHUP;
|
||||||
if (sk->sk_shutdown & RCV_SHUTDOWN)
|
if (shutdown & RCV_SHUTDOWN)
|
||||||
mask |= EPOLLIN | EPOLLRDNORM | EPOLLRDHUP;
|
mask |= EPOLLIN | EPOLLRDNORM | EPOLLRDHUP;
|
||||||
|
|
||||||
/* Connected? */
|
/* Connected? */
|
||||||
if ((1 << sk->sk_state) & ~(DCCPF_REQUESTING | DCCPF_RESPOND)) {
|
if ((1 << state) & ~(DCCPF_REQUESTING | DCCPF_RESPOND)) {
|
||||||
if (atomic_read(&sk->sk_rmem_alloc) > 0)
|
if (atomic_read(&sk->sk_rmem_alloc) > 0)
|
||||||
mask |= EPOLLIN | EPOLLRDNORM;
|
mask |= EPOLLIN | EPOLLRDNORM;
|
||||||
|
|
||||||
if (!(sk->sk_shutdown & SEND_SHUTDOWN)) {
|
if (!(shutdown & SEND_SHUTDOWN)) {
|
||||||
if (sk_stream_is_writeable(sk)) {
|
if (sk_stream_is_writeable(sk)) {
|
||||||
mask |= EPOLLOUT | EPOLLWRNORM;
|
mask |= EPOLLOUT | EPOLLWRNORM;
|
||||||
} else { /* send SIGIO later */
|
} else { /* send SIGIO later */
|
||||||
@ -359,7 +364,6 @@ __poll_t dccp_poll(struct file *file, struct socket *sock,
|
|||||||
}
|
}
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(dccp_poll);
|
EXPORT_SYMBOL_GPL(dccp_poll);
|
||||||
|
|
||||||
int dccp_ioctl(struct sock *sk, int cmd, int *karg)
|
int dccp_ioctl(struct sock *sk, int cmd, int *karg)
|
||||||
|
Loading…
Reference in New Issue
Block a user