diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 1b2e7cbb577f..fc8d9fc36942 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -1022,8 +1022,18 @@ static void __mptcp_clean_una(struct sock *sk) if (unlikely(dfrag == msk->first_pending)) { /* in recovery mode can see ack after the current snd head */ - if (WARN_ON_ONCE(!msk->recovery)) + if (!msk->recovery) { + pr_err("snd_una %llx snd_nxt %llx write_seq %llx " + "idsn %llx dfrag seq %llx len %d disconnects %d:%d " + "state %d %d\n", + snd_una, msk->snd_nxt, msk->write_seq, + mptcp_subflow_ctx(msk->first)->idsn, + dfrag->data_seq, dfrag->data_len, + sk->sk_disconnects, msk->disconnects, + sk->sk_state, sk->sk_socket ? sk->sk_socket->state: -1); + WARN_ON(1); break; + } WRITE_ONCE(msk->first_pending, mptcp_send_next(sk)); } @@ -1767,8 +1777,10 @@ static int mptcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg, * see mptcp_disconnect(). * Attempt it again outside the problematic scope. */ - if (!mptcp_disconnect(sk, 0)) + if (!mptcp_disconnect(sk, 0)) { + sk->sk_disconnects++; sk->sk_socket->state = SS_UNCONNECTED; + } } inet_clear_bit(DEFER_CONNECT, sk); @@ -3208,6 +3220,7 @@ static int mptcp_disconnect(struct sock *sk, int flags) if (msk->fastopening) return -EBUSY; + msk->disconnects++; mptcp_check_listen_stop(sk); mptcp_set_state(sk, TCP_CLOSE); diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 73526f1d768f..59a6e52f02a4 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -340,6 +340,7 @@ struct mptcp_sock { u64 rtt_us; /* last maximum rtt of subflows */ } rcvq_space; u8 scaling_ratio; + u16 disconnects; u32 subflow_id; u32 setsockopt_seq;