@@ -603,7 +603,7 @@ static void unix_release_sock(struct sock *sk, int embrion)
603
603
/* Clear state */
604
604
unix_state_lock (sk );
605
605
sock_orphan (sk );
606
- sk -> sk_shutdown = SHUTDOWN_MASK ;
606
+ WRITE_ONCE ( sk -> sk_shutdown , SHUTDOWN_MASK ) ;
607
607
path = u -> path ;
608
608
u -> path .dentry = NULL ;
609
609
u -> path .mnt = NULL ;
@@ -628,7 +628,7 @@ static void unix_release_sock(struct sock *sk, int embrion)
628
628
if (sk -> sk_type == SOCK_STREAM || sk -> sk_type == SOCK_SEQPACKET ) {
629
629
unix_state_lock (skpair );
630
630
/* No more writes */
631
- skpair -> sk_shutdown = SHUTDOWN_MASK ;
631
+ WRITE_ONCE ( skpair -> sk_shutdown , SHUTDOWN_MASK ) ;
632
632
if (!skb_queue_empty (& sk -> sk_receive_queue ) || embrion )
633
633
WRITE_ONCE (skpair -> sk_err , ECONNRESET );
634
634
unix_state_unlock (skpair );
@@ -1442,7 +1442,7 @@ static long unix_wait_for_peer(struct sock *other, long timeo)
1442
1442
1443
1443
sched = !sock_flag (other , SOCK_DEAD ) &&
1444
1444
!(other -> sk_shutdown & RCV_SHUTDOWN ) &&
1445
- unix_recvq_full (other );
1445
+ unix_recvq_full_lockless (other );
1446
1446
1447
1447
unix_state_unlock (other );
1448
1448
@@ -3008,7 +3008,7 @@ static int unix_shutdown(struct socket *sock, int mode)
3008
3008
++ mode ;
3009
3009
3010
3010
unix_state_lock (sk );
3011
- sk -> sk_shutdown |= mode ;
3011
+ WRITE_ONCE ( sk -> sk_shutdown , sk -> sk_shutdown | mode ) ;
3012
3012
other = unix_peer (sk );
3013
3013
if (other )
3014
3014
sock_hold (other );
@@ -3028,7 +3028,7 @@ static int unix_shutdown(struct socket *sock, int mode)
3028
3028
if (mode & SEND_SHUTDOWN )
3029
3029
peer_mode |= RCV_SHUTDOWN ;
3030
3030
unix_state_lock (other );
3031
- other -> sk_shutdown |= peer_mode ;
3031
+ WRITE_ONCE ( other -> sk_shutdown , other -> sk_shutdown | peer_mode ) ;
3032
3032
unix_state_unlock (other );
3033
3033
other -> sk_state_change (other );
3034
3034
if (peer_mode == SHUTDOWN_MASK )
@@ -3160,16 +3160,18 @@ static __poll_t unix_poll(struct file *file, struct socket *sock, poll_table *wa
3160
3160
{
3161
3161
struct sock * sk = sock -> sk ;
3162
3162
__poll_t mask ;
3163
+ u8 shutdown ;
3163
3164
3164
3165
sock_poll_wait (file , sock , wait );
3165
3166
mask = 0 ;
3167
+ shutdown = READ_ONCE (sk -> sk_shutdown );
3166
3168
3167
3169
/* exceptional events? */
3168
3170
if (READ_ONCE (sk -> sk_err ))
3169
3171
mask |= EPOLLERR ;
3170
- if (sk -> sk_shutdown == SHUTDOWN_MASK )
3172
+ if (shutdown == SHUTDOWN_MASK )
3171
3173
mask |= EPOLLHUP ;
3172
- if (sk -> sk_shutdown & RCV_SHUTDOWN )
3174
+ if (shutdown & RCV_SHUTDOWN )
3173
3175
mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM ;
3174
3176
3175
3177
/* readable? */
@@ -3203,19 +3205,21 @@ static __poll_t unix_dgram_poll(struct file *file, struct socket *sock,
3203
3205
struct sock * sk = sock -> sk , * other ;
3204
3206
unsigned int writable ;
3205
3207
__poll_t mask ;
3208
+ u8 shutdown ;
3206
3209
3207
3210
sock_poll_wait (file , sock , wait );
3208
3211
mask = 0 ;
3212
+ shutdown = READ_ONCE (sk -> sk_shutdown );
3209
3213
3210
3214
/* exceptional events? */
3211
3215
if (READ_ONCE (sk -> sk_err ) ||
3212
3216
!skb_queue_empty_lockless (& sk -> sk_error_queue ))
3213
3217
mask |= EPOLLERR |
3214
3218
(sock_flag (sk , SOCK_SELECT_ERR_QUEUE ) ? EPOLLPRI : 0 );
3215
3219
3216
- if (sk -> sk_shutdown & RCV_SHUTDOWN )
3220
+ if (shutdown & RCV_SHUTDOWN )
3217
3221
mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM ;
3218
- if (sk -> sk_shutdown == SHUTDOWN_MASK )
3222
+ if (shutdown == SHUTDOWN_MASK )
3219
3223
mask |= EPOLLHUP ;
3220
3224
3221
3225
/* readable? */
0 commit comments