]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - net/tipc/socket.c
net: use skb_queue_empty_lockless() in poll() handlers
[mirror_ubuntu-bionic-kernel.git] / net / tipc / socket.c
index af5ec882bfc0f504e928bf90ec137bfda20a8960..d6ce720eaa57eafd6f3c678da4d69ff61f49217d 100644 (file)
@@ -377,11 +377,13 @@ static int tipc_sk_sock_err(struct socket *sock, long *timeout)
 
 #define tipc_wait_for_cond(sock_, timeo_, condition_)                         \
 ({                                                                             \
+       DEFINE_WAIT_FUNC(wait_, woken_wake_function);                          \
        struct sock *sk_;                                                      \
        int rc_;                                                               \
                                                                               \
        while ((rc_ = !(condition_))) {                                        \
-               DEFINE_WAIT_FUNC(wait_, woken_wake_function);                  \
+               /* coupled with smp_wmb() in tipc_sk_proto_rcv() */            \
+               smp_rmb();                                                     \
                sk_ = (sock_)->sk;                                             \
                rc_ = tipc_sk_sock_err((sock_), timeo_);                       \
                if (rc_)                                                       \
@@ -728,12 +730,12 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
 
        switch (sk->sk_state) {
        case TIPC_ESTABLISHED:
-       case TIPC_CONNECTING:
                if (!tsk->cong_link_cnt && !tsk_conn_cong(tsk))
                        revents |= POLLOUT;
                /* fall thru' */
        case TIPC_LISTEN:
-               if (!skb_queue_empty(&sk->sk_receive_queue))
+       case TIPC_CONNECTING:
+               if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
                        revents |= POLLIN | POLLRDNORM;
                break;
        case TIPC_OPEN:
@@ -742,7 +744,7 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
                                revents |= POLLOUT;
                if (!tipc_sk_type_connectionless(sk))
                        break;
-               if (skb_queue_empty(&sk->sk_receive_queue))
+               if (skb_queue_empty_lockless(&sk->sk_receive_queue))
                        break;
                revents |= POLLIN | POLLRDNORM;
                break;
@@ -1012,7 +1014,7 @@ static int tipc_send_group_bcast(struct socket *sock, struct msghdr *m,
        struct sock *sk = sock->sk;
        struct net *net = sock_net(sk);
        struct tipc_sock *tsk = tipc_sk(sk);
-       struct tipc_nlist *dsts = tipc_group_dests(tsk->group);
+       struct tipc_nlist *dsts;
        struct tipc_mc_method *method = &tsk->mc_method;
        bool ack = method->mandatory && method->rcast;
        int blks = tsk_blocks(MCAST_H_SIZE + dlen);
@@ -1021,9 +1023,6 @@ static int tipc_send_group_bcast(struct socket *sock, struct msghdr *m,
        struct sk_buff_head pkts;
        int rc = -EHOSTUNREACH;
 
-       if (!dsts->local && !dsts->remote)
-               return -EHOSTUNREACH;
-
        /* Block or return if any destination link or member is congested */
        rc = tipc_wait_for_cond(sock, &timeout,
                                !tsk->cong_link_cnt && tsk->group &&
@@ -1031,6 +1030,10 @@ static int tipc_send_group_bcast(struct socket *sock, struct msghdr *m,
        if (unlikely(rc))
                return rc;
 
+       dsts = tipc_group_dests(tsk->group);
+       if (!dsts->local && !dsts->remote)
+               return -EHOSTUNREACH;
+
        /* Complete message header */
        if (dest) {
                msg_set_type(hdr, TIPC_GRP_MCAST_MSG);
@@ -1297,7 +1300,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dlen)
 
        if (unlikely(!dest)) {
                dest = &tsk->peer;
-               if (!syn || dest->family != AF_TIPC)
+               if (!syn && dest->family != AF_TIPC)
                        return -EDESTADDRREQ;
        }
 
@@ -1939,6 +1942,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;
@@ -2014,7 +2019,7 @@ static bool tipc_sk_filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
                        return true;
 
                /* If empty 'ACK-' message, wake up sleeping connect() */
-               sk->sk_data_ready(sk);
+               sk->sk_state_change(sk);
 
                /* 'ACK-' message is neither accepted nor rejected: */
                msg_set_dest_droppable(hdr, 1);