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

net_sched: sch_fq: prefetch one skb ahead in dequeue()

prefetch the skb that we are likely to dequeue at the next dequeue().

Also call fq_dequeue_skb() a bit sooner in fq_dequeue().

This reduces the window between read of q.qlen and
changes of fields in the cache line that could be dirtied
by another cpu trying to queue a packet.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20251121083256.674562-10-edumazet@google.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Eric Dumazet and committed by
Paolo Abeni
2f9babc0 3c1100f0

+5 -2
+5 -2
net/sched/sch_fq.c
··· 480 480 struct sk_buff *skb) 481 481 { 482 482 if (skb == flow->head) { 483 - flow->head = skb->next; 483 + struct sk_buff *next = skb->next; 484 + 485 + prefetch(next); 486 + flow->head = next; 484 487 } else { 485 488 rb_erase(&skb->rbnode, &flow->t_root); 486 489 skb->dev = qdisc_dev(sch); ··· 715 712 goto begin; 716 713 } 717 714 prefetch(&skb->end); 715 + fq_dequeue_skb(sch, f, skb); 718 716 if ((s64)(now - time_next_packet - q->ce_threshold) > 0) { 719 717 INET_ECN_set_ce(skb); 720 718 q->stat_ce_mark++; ··· 723 719 if (--f->qlen == 0) 724 720 q->inactive_flows++; 725 721 q->band_pkt_count[fq_skb_cb(skb)->band]--; 726 - fq_dequeue_skb(sch, f, skb); 727 722 } else { 728 723 head->first = f->next; 729 724 /* force a pass through old_flows to prevent starvation */