Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net_sched: sch_fq: properly set sk->sk_pacing_status

If fq_classify() recycles a struct fq_flow because
a socket structure has been reallocated, we do not
set sk->sk_pacing_status immediately, but later if the
flow becomes detached.

This means that any flow requiring pacing (BBR, or SO_MAX_PACING_RATE)
might fallback to TCP internal pacing, which requires a per-socket
high resolution timer, and therefore more cpu cycles.

Fixes: 218af599fa63 ("tcp: internal implementation for pacing")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Soheil Hassas Yeganeh <soheil@google.com>
Cc: Neal Cardwell <ncardwell@google.com>
Acked-by: Soheil Hassas Yeganeh <soheil@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Eric Dumazet and committed by
David S. Miller
bb3d0b8b 4e55a11a

+8 -9
+8 -9
net/sched/sch_fq.c
··· 301 301 f->socket_hash != sk->sk_hash)) { 302 302 f->credit = q->initial_quantum; 303 303 f->socket_hash = sk->sk_hash; 304 + if (q->rate_enable) 305 + smp_store_release(&sk->sk_pacing_status, 306 + SK_PACING_FQ); 304 307 if (fq_flow_is_throttled(f)) 305 308 fq_flow_unset_throttled(q, f); 306 309 f->time_next_packet = 0ULL; ··· 325 322 326 323 fq_flow_set_detached(f); 327 324 f->sk = sk; 328 - if (skb->sk == sk) 325 + if (skb->sk == sk) { 329 326 f->socket_hash = sk->sk_hash; 327 + if (q->rate_enable) 328 + smp_store_release(&sk->sk_pacing_status, 329 + SK_PACING_FQ); 330 + } 330 331 f->credit = q->initial_quantum; 331 332 332 333 rb_link_node(&f->fq_node, parent, p); ··· 435 428 f->qlen++; 436 429 qdisc_qstats_backlog_inc(sch, skb); 437 430 if (fq_flow_is_detached(f)) { 438 - struct sock *sk = skb->sk; 439 - 440 431 fq_flow_add_tail(&q->new_flows, f); 441 432 if (time_after(jiffies, f->age + q->flow_refill_delay)) 442 433 f->credit = max_t(u32, f->credit, q->quantum); 443 - if (sk && q->rate_enable) { 444 - if (unlikely(smp_load_acquire(&sk->sk_pacing_status) != 445 - SK_PACING_FQ)) 446 - smp_store_release(&sk->sk_pacing_status, 447 - SK_PACING_FQ); 448 - } 449 434 q->inactive_flows--; 450 435 } 451 436