Due to how tcp_sendmsg() is implemented, we can have an empty skb at the tail of the write queue. Most [1] tcp_write_queue_empty() callers want to know if there is anything to send (payload and/or FIN) Instead of checking if the sk_write_queue is empty, we need to test if tp->write_seq == tp->snd_nxt [1] tcp_send_fin() was the only caller that expected to see if an skb was in the write queue, I have changed the code to reuse the tcp_write_queue_tail() result.
Showing the changes to include/net (1 of 2 files). Show all
Unified · Split
| @@ -1766,9 +1766,18 @@ static inline bool tcp_skb_is_last(const struct sock *sk, · 1765 unmodified lines | |||
| 1766 | return skb_queue_is_last(&sk->sk_write_queue, skb); | 1766 | return skb_queue_is_last(&sk->sk_write_queue, skb); |
| 1767 | } | 1767 | } |
| 1768 | 1768 | ||
| 1769 | /** | ||
| 1770 | * tcp_write_queue_empty - test if any payload (or FIN) is available in write queue | ||
| 1771 | * @sk: socket | ||
| 1772 | * | ||
| 1773 | * Since the write queue can have a temporary empty skb in it, | ||
| 1774 | * we must not use "return skb_queue_empty(&sk->sk_write_queue)" | ||
| 1775 | */ | ||
| 1769 | static inline bool tcp_write_queue_empty(const struct sock *sk) | 1776 | static inline bool tcp_write_queue_empty(const struct sock *sk) |
| 1770 | { | 1777 | { |
| 1771 | return skb_queue_empty(&sk->sk_write_queue); | 1778 | const struct tcp_sock *tp = tcp_sk(sk); |
| 1779 | |||
| 1780 | return tp->write_seq == tp->snd_nxt; | ||
| 1772 | } | 1781 | } |
| 1773 | 1782 | ||
| 1774 | static inline bool tcp_rtx_queue_empty(const struct sock *sk) | 1783 | static inline bool tcp_rtx_queue_empty(const struct sock *sk) |