Acked-by: Jon Maloy <[email protected]> ///jon
> -----Original Message----- > From: Tung Nguyen <[email protected]> > Sent: 14-Feb-19 01:42 > To: [email protected]; Jon Maloy > <[email protected]>; [email protected]; [email protected] > Subject: [tipc-discussion][PATCH v1 1/1] tipc: fix race condition causing hung > sendto > > When sending multicast messages via blocking socket, if sending link is > congested (tsk->cong_link_cnt is set to 1), the sending thread is put into > sleeping state. However, > tipc_sk_filter_rcv() is called under socket spin lock but > tipc_wait_for_cond() is not. So, there is no guarantee that the setting of > tsk- > >cong_link_cnt to 0 in tipc_sk_proto_rcv() in > CPU-1 will be perceived by CPU-0. If that is the case, the sending thread in > CPU-0 after being waken up, will continue to see > tsk->cong_link_cnt as 1 and put the sending thread into sleeping > state again. The sending thread will sleep forever. > > CPU-0 | CPU-1 > tipc_wait_for_cond() | > { | > // condition_ = !tsk->cong_link_cnt | > while ((rc_ = !(condition_))) { | > ... | > release_sock(sk_); | > wait_woken(); | > | if (!sock_owned_by_user(sk)) > | tipc_sk_filter_rcv() > | { > | ... > | tipc_sk_proto_rcv() > | { > | ... > | tsk->cong_link_cnt--; > | ... > | sk->sk_write_space(sk); > | ... > | } > | ... > | } > sched_annotate_sleep(); | > lock_sock(sk_); | > remove_wait_queue(); | > } | > } | > > This commit fixes it by adding memory barrier to tipc_sk_proto_rcv() and > tipc_wait_for_cond(). > > Signed-off-by: Tung Nguyen <[email protected]> > --- > net/tipc/socket.c | 4 ++++ > 1 file changed, 4 insertions(+) > > diff --git a/net/tipc/socket.c b/net/tipc/socket.c index > 1217c90a363b..d8f054d45941 100644 > --- a/net/tipc/socket.c > +++ b/net/tipc/socket.c > @@ -383,6 +383,8 @@ static int tipc_sk_sock_err(struct socket *sock, long > *timeout) > int rc_; \ > \ > while ((rc_ = !(condition_))) { \ > + /* coupled with smp_wmb() in tipc_sk_proto_rcv() */ \ > + smp_rmb(); \ > DEFINE_WAIT_FUNC(wait_, woken_wake_function); > \ > sk_ = (sock_)->sk; \ > rc_ = tipc_sk_sock_err((sock_), timeo_); \ > @@ -1982,6 +1984,8 @@ static void tipc_sk_proto_rcv(struct sock *sk, > return; > case SOCK_WAKEUP: > tipc_dest_del(&tsk->cong_links, msg_orignode(hdr), 0); > + /* coupled with smp_rmb() in tipc_wait_for_cond() */ > + smp_wmb(); > tsk->cong_link_cnt--; > wakeup = true; > break; > -- > 2.17.1 _______________________________________________ tipc-discussion mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/tipc-discussion
