diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 39cff39ba93f..68be03e8dc45 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -982,33 +982,12 @@ enum hrtimer_restart tcp_pace_kick(struct hrtimer *timer) return HRTIMER_NORESTART; } -static void tcp_internal_pacing(struct sock *sk, const struct sk_buff *skb) +static void tcp_internal_pacing(struct sock *sk) { - struct tcp_sock *tp = tcp_sk(sk); - ktime_t expire, now; - u64 len_ns; - u32 rate; - if (!tcp_needs_internal_pacing(sk)) return; - rate = sk->sk_pacing_rate; - if (!rate || rate == ~0U) - return; - - len_ns = (u64)skb->len * NSEC_PER_SEC; - do_div(len_ns, rate); - now = ktime_get(); - /* If hrtimer is already armed, then our caller has not - * used tcp_pacing_check(). - */ - if (unlikely(hrtimer_is_queued(&tp->pacing_timer))) { - expire = hrtimer_get_softexpires(&tp->pacing_timer); - if (ktime_after(expire, now)) - now = expire; - if (hrtimer_try_to_cancel(&tp->pacing_timer) == 1) - __sock_put(sk); - } - hrtimer_start(&tp->pacing_timer, ktime_add_ns(now, len_ns), + hrtimer_start(&tcp_sk(sk)->pacing_timer, + ns_to_ktime(tcp_sk(sk)->tcp_wstamp_ns), HRTIMER_MODE_ABS_PINNED_SOFT); sock_hold(sk); } @@ -1033,7 +1012,8 @@ static void tcp_update_skb_after_send(struct sock *sk, struct sk_buff *skb) */ if (rate != ~0U && rate && tp->data_segs_out >= 10) { tp->tcp_wstamp_ns += div_u64((u64)skb->len * NSEC_PER_SEC, rate); - /* TODO: update internal pacing here */ + + tcp_internal_pacing(sk); } } list_move_tail(&skb->tcp_tsorted_anchor, &tp->tsorted_sent_queue); @@ -1174,7 +1154,6 @@ static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, tcp_event_data_sent(tp, sk); tp->data_segs_out += tcp_skb_pcount(skb); tp->bytes_sent += skb->len - tcp_header_size; - tcp_internal_pacing(sk, skb); } if (after(tcb->end_seq, tp->snd_nxt) || tcb->seq == tcb->end_seq)