Skip to content

Commit 23e19fd

Browse files
committed
Merge branch 'tcp_bbr-more-GSO-work'
Eric Dumazet says: ==================== tcp_bbr: more GSO work Playing with r8152 USB 1Gbit NIC, on both USB2 and USB3 slots, I found that BBR was performing poorly, because of TSO being limited to 16KB This patch series makes sure BBR is not under estimating number of packets that are needed to fill the pipe when a device has suboptimal TSO limits. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 7797dc4 + 71abf46 commit 23e19fd

File tree

3 files changed

+26
-28
lines changed

3 files changed

+26
-28
lines changed

include/net/tcp.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -511,8 +511,6 @@ __u32 cookie_v6_init_sequence(const struct sk_buff *skb, __u16 *mss);
511511
#endif
512512
/* tcp_output.c */
513513

514-
u32 tcp_tso_autosize(const struct sock *sk, unsigned int mss_now,
515-
int min_tso_segs);
516514
void __tcp_push_pending_frames(struct sock *sk, unsigned int cur_mss,
517515
int nonagle);
518516
int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs);
@@ -981,8 +979,8 @@ struct tcp_congestion_ops {
981979
u32 (*undo_cwnd)(struct sock *sk);
982980
/* hook for packet ack accounting (optional) */
983981
void (*pkts_acked)(struct sock *sk, const struct ack_sample *sample);
984-
/* suggest number of segments for each skb to transmit (optional) */
985-
u32 (*tso_segs_goal)(struct sock *sk);
982+
/* override sysctl_tcp_min_tso_segs */
983+
u32 (*min_tso_segs)(struct sock *sk);
986984
/* returns the multiplier used in tcp_sndbuf_expand (optional) */
987985
u32 (*sndbuf_expand)(struct sock *sk);
988986
/* call when packets are delivered to update cwnd and pacing rate,

net/ipv4/tcp_bbr.c

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,9 @@ struct bbr {
9797
packet_conservation:1, /* use packet conservation? */
9898
restore_cwnd:1, /* decided to revert cwnd to old value */
9999
round_start:1, /* start of packet-timed tx->ack round? */
100-
tso_segs_goal:7, /* segments we want in each skb we send */
101100
idle_restart:1, /* restarting after idle? */
102101
probe_rtt_round_done:1, /* a BBR_PROBE_RTT round at 4 pkts? */
103-
unused:5,
102+
unused:12,
104103
lt_is_sampling:1, /* taking long-term ("LT") samples now? */
105104
lt_rtt_cnt:7, /* round trips in long-term interval */
106105
lt_use_bw:1; /* use lt_bw as our bw estimate? */
@@ -261,23 +260,25 @@ static void bbr_set_pacing_rate(struct sock *sk, u32 bw, int gain)
261260
sk->sk_pacing_rate = rate;
262261
}
263262

264-
/* Return count of segments we want in the skbs we send, or 0 for default. */
265-
static u32 bbr_tso_segs_goal(struct sock *sk)
263+
/* override sysctl_tcp_min_tso_segs */
264+
static u32 bbr_min_tso_segs(struct sock *sk)
266265
{
267-
struct bbr *bbr = inet_csk_ca(sk);
268-
269-
return bbr->tso_segs_goal;
266+
return sk->sk_pacing_rate < (bbr_min_tso_rate >> 3) ? 1 : 2;
270267
}
271268

272-
static void bbr_set_tso_segs_goal(struct sock *sk)
269+
static u32 bbr_tso_segs_goal(struct sock *sk)
273270
{
274271
struct tcp_sock *tp = tcp_sk(sk);
275-
struct bbr *bbr = inet_csk_ca(sk);
276-
u32 min_segs;
272+
u32 segs, bytes;
273+
274+
/* Sort of tcp_tso_autosize() but ignoring
275+
* driver provided sk_gso_max_size.
276+
*/
277+
bytes = min_t(u32, sk->sk_pacing_rate >> sk->sk_pacing_shift,
278+
GSO_MAX_SIZE - 1 - MAX_TCP_HEADER);
279+
segs = max_t(u32, bytes / tp->mss_cache, bbr_min_tso_segs(sk));
277280

278-
min_segs = sk->sk_pacing_rate < (bbr_min_tso_rate >> 3) ? 1 : 2;
279-
bbr->tso_segs_goal = min(tcp_tso_autosize(sk, tp->mss_cache, min_segs),
280-
0x7FU);
281+
return min(segs, 0x7FU);
281282
}
282283

283284
/* Save "last known good" cwnd so we can restore it after losses or PROBE_RTT */
@@ -348,7 +349,7 @@ static u32 bbr_target_cwnd(struct sock *sk, u32 bw, int gain)
348349
cwnd = (((w * gain) >> BBR_SCALE) + BW_UNIT - 1) / BW_UNIT;
349350

350351
/* Allow enough full-sized skbs in flight to utilize end systems. */
351-
cwnd += 3 * bbr->tso_segs_goal;
352+
cwnd += 3 * bbr_tso_segs_goal(sk);
352353

353354
/* Reduce delayed ACKs by rounding up cwnd to the next even number. */
354355
cwnd = (cwnd + 1) & ~1U;
@@ -824,7 +825,6 @@ static void bbr_main(struct sock *sk, const struct rate_sample *rs)
824825

825826
bw = bbr_bw(sk);
826827
bbr_set_pacing_rate(sk, bw, bbr->pacing_gain);
827-
bbr_set_tso_segs_goal(sk);
828828
bbr_set_cwnd(sk, rs, rs->acked_sacked, bw, bbr->cwnd_gain);
829829
}
830830

@@ -834,7 +834,6 @@ static void bbr_init(struct sock *sk)
834834
struct bbr *bbr = inet_csk_ca(sk);
835835

836836
bbr->prior_cwnd = 0;
837-
bbr->tso_segs_goal = 0; /* default segs per skb until first ACK */
838837
bbr->rtt_cnt = 0;
839838
bbr->next_rtt_delivered = 0;
840839
bbr->prev_ca_state = TCP_CA_Open;
@@ -936,7 +935,7 @@ static struct tcp_congestion_ops tcp_bbr_cong_ops __read_mostly = {
936935
.undo_cwnd = bbr_undo_cwnd,
937936
.cwnd_event = bbr_cwnd_event,
938937
.ssthresh = bbr_ssthresh,
939-
.tso_segs_goal = bbr_tso_segs_goal,
938+
.min_tso_segs = bbr_min_tso_segs,
940939
.get_info = bbr_get_info,
941940
.set_state = bbr_set_state,
942941
};

net/ipv4/tcp_output.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,8 +1703,8 @@ static bool tcp_nagle_check(bool partial, const struct tcp_sock *tp,
17031703
/* Return how many segs we'd like on a TSO packet,
17041704
* to send one TSO packet per ms
17051705
*/
1706-
u32 tcp_tso_autosize(const struct sock *sk, unsigned int mss_now,
1707-
int min_tso_segs)
1706+
static u32 tcp_tso_autosize(const struct sock *sk, unsigned int mss_now,
1707+
int min_tso_segs)
17081708
{
17091709
u32 bytes, segs;
17101710

@@ -1720,19 +1720,20 @@ u32 tcp_tso_autosize(const struct sock *sk, unsigned int mss_now,
17201720

17211721
return segs;
17221722
}
1723-
EXPORT_SYMBOL(tcp_tso_autosize);
17241723

17251724
/* Return the number of segments we want in the skb we are transmitting.
17261725
* See if congestion control module wants to decide; otherwise, autosize.
17271726
*/
17281727
static u32 tcp_tso_segs(struct sock *sk, unsigned int mss_now)
17291728
{
17301729
const struct tcp_congestion_ops *ca_ops = inet_csk(sk)->icsk_ca_ops;
1731-
u32 tso_segs = ca_ops->tso_segs_goal ? ca_ops->tso_segs_goal(sk) : 0;
1730+
u32 min_tso, tso_segs;
17321731

1733-
if (!tso_segs)
1734-
tso_segs = tcp_tso_autosize(sk, mss_now,
1735-
sock_net(sk)->ipv4.sysctl_tcp_min_tso_segs);
1732+
min_tso = ca_ops->min_tso_segs ?
1733+
ca_ops->min_tso_segs(sk) :
1734+
sock_net(sk)->ipv4.sysctl_tcp_min_tso_segs;
1735+
1736+
tso_segs = tcp_tso_autosize(sk, mss_now, min_tso);
17361737
return min_t(u32, tso_segs, sk->sk_gso_max_segs);
17371738
}
17381739

0 commit comments

Comments
 (0)