On Mon, 2015-02-09 at 14:47 +0100, Michal Kazior wrote:
> diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
> index 65caf8b..5e249bf 100644
> --- a/net/ipv4/tcp_output.c
> +++ b/net/ipv4/tcp_output.c
> @@ -1996,6 +1996,7 @@ static bool tcp_write_xmit(struct sock *sk,
> unsigned int mss_now, int nonagle,
> max_segs = tcp_tso_autosize(sk, mss_now);
> while ((skb = tcp_send_head(sk))) {
> unsigned int limit;
> + unsigned int amount;
>
> tso_segs = tcp_init_tso_segs(sk, skb, mss_now);
> BUG_ON(!tso_segs);
> @@ -2053,7 +2054,9 @@ static bool tcp_write_xmit(struct sock *sk,
> unsigned int mss_now, int nonagle,
> * of queued bytes to ensure line rate.
> * One example is wifi aggregation (802.11 AMPDU)
> */
> - limit = max(2 * skb->truesize, sk->sk_pacing_rate >> 10);
> + amount = sk->sk_tx_completion_delay_us *
> + (sk->sk_pacing_rate >> 10);
> + limit = max(2 * skb->truesize, amount >> 10);
> limit = min_t(u32, limit, sysctl_tcp_limit_output_bytes);
>
> if (atomic_read(&sk->sk_wmem_alloc) > limit) {
This is not what I suggested.
If you test this on any other network device, you'll have
sk->sk_tx_completion_delay_us == 0
amount = 0 * (sk->sk_pacing_rate >> 10); --> 0
limit = max(2 * skb->truesize, amount >> 10); --> 2 * skb->truesize
So non TSO/GSO NIC will not be able to queue more than 2 MSS (one MSS
per skb)
Then if you store only the last tx completion, you have the possibility
of having a last packet of a train (say a retransmit) to make it very
low.
Ideally the formula would be in TCP something very fast to compute :
amount = (sk->sk_pacing_rate >> 10) + sk->tx_completion_delay_cushion;
limit = max(2 * skb->truesize, amount);
limit = min_t(u32, limit, sysctl_tcp_limit_output_bytes);
So a 'problematic' driver would have to do the math (64 bit maths) like
this :
sk->tx_completion_delay_cushion = ewma_tx_delay * sk->sk_pacing_rate;
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html