Merge tag 'trace-v5.5-3' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
[linux-2.6-microblaze.git] / net / tipc / socket.c
index a1c8d72..41688da 100644 (file)
@@ -532,7 +532,7 @@ static void __tipc_shutdown(struct socket *sock, int error)
        struct sock *sk = sock->sk;
        struct tipc_sock *tsk = tipc_sk(sk);
        struct net *net = sock_net(sk);
-       long timeout = CONN_TIMEOUT_DEFAULT;
+       long timeout = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT);
        u32 dnode = tsk_peer_node(tsk);
        struct sk_buff *skb;
 
@@ -540,12 +540,10 @@ static void __tipc_shutdown(struct socket *sock, int error)
        tipc_wait_for_cond(sock, &timeout, (!tsk->cong_link_cnt &&
                                            !tsk_conn_cong(tsk)));
 
-       /* Push out unsent messages or remove if pending SYN */
-       skb = skb_peek(&sk->sk_write_queue);
-       if (skb && !msg_is_syn(buf_msg(skb)))
-               tipc_sk_push_backlog(tsk);
-       else
-               __skb_queue_purge(&sk->sk_write_queue);
+       /* Push out delayed messages if in Nagle mode */
+       tipc_sk_push_backlog(tsk);
+       /* Remove pending SYN */
+       __skb_queue_purge(&sk->sk_write_queue);
 
        /* Reject all unreceived messages, except on an active connection
         * (which disconnects locally & sends a 'FIN+' to peer).
@@ -1248,9 +1246,14 @@ static void tipc_sk_push_backlog(struct tipc_sock *tsk)
        struct sk_buff_head *txq = &tsk->sk.sk_write_queue;
        struct net *net = sock_net(&tsk->sk);
        u32 dnode = tsk_peer_node(tsk);
+       struct sk_buff *skb = skb_peek(txq);
        int rc;
 
-       if (skb_queue_empty(txq) || tsk->cong_link_cnt)
+       if (!skb || tsk->cong_link_cnt)
+               return;
+
+       /* Do not send SYN again after congestion */
+       if (msg_is_syn(buf_msg(skb)))
                return;
 
        tsk->snt_unacked += tsk->snd_backlog;
@@ -1447,8 +1450,10 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dlen)
        rc = tipc_msg_build(hdr, m, 0, dlen, mtu, &pkts);
        if (unlikely(rc != dlen))
                return rc;
-       if (unlikely(syn && !tipc_msg_skb_clone(&pkts, &sk->sk_write_queue)))
+       if (unlikely(syn && !tipc_msg_skb_clone(&pkts, &sk->sk_write_queue))) {
+               __skb_queue_purge(&pkts);
                return -ENOMEM;
+       }
 
        trace_tipc_sk_sendmsg(sk, skb_peek(&pkts), TIPC_DUMP_SK_SNDQ, " ");
        rc = tipc_node_xmit(net, &pkts, dnode, tsk->portid);
@@ -2757,6 +2762,7 @@ static void tipc_sk_timeout(struct timer_list *t)
        if (sock_owned_by_user(sk)) {
                sk_reset_timer(sk, &sk->sk_timer, jiffies + HZ / 20);
                bh_unlock_sock(sk);
+               sock_put(sk);
                return;
        }