Cake - FQ_codel the next generation
 help / color / mirror / Atom feed
From: Jamal Hadi Salim <jhs@mojatatu.com>
To: "Toke Høiland-Jørgensen" <toke@toke.dk>
Cc: netdev@vger.kernel.org, "Jiri Pirko" <jiri@resnulli.us>,
	"David S . Miller" <davem@davemloft.net>,
	"Eric Dumazet" <edumazet@kernel.org>,
	"Jakub Kicinski" <kuba@kernel.org>,
	"Paolo Abeni" <pabeni@redhat.com>,
	"Simon Horman" <horms@kernel.org>,
	"Victor Nogueira" <victor@mojatatu.com>,
	"Björn Töpel" <bjorn@kernel.org>,
	cake@lists.bufferbloat.net, Sashiko <sashiko-bot@kernel.org>
Subject: [Cake] Re: [PATCH net-next v7 4/4] net/sched: cake: hash before segmenting and reject an overlong split
Date: Tue, 20 Oct 2026 06:08:57 -0400	[thread overview]
Message-ID: <CAM0EoM=rSqLatP2D72iKaeXSt95fTZvyP6wbPnvf_Ai53wq=ew@mail.gmail.com> (raw)
In-Reply-To: <878q3svjut.fsf@toke.dk>

On Tue, Oct 20, 2026 at 4:47 AM Toke Høiland-Jørgensen <toke@toke.dk> wrote:
>
> >> > +
> >> > +             segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK);
> >> > +             if (IS_ERR_OR_NULL(segs))
> >> > +                     return qdisc_drop(skb, sch, to_free);
> >> > +
> >> > +             /* The split path accounts the segment sum, not the
> >> > +              * stab-adjusted qdisc_pkt_len(), so check it here.
> >> > +              */
> >> > +             skb_list_walk_safe(segs, seg, nskb)
> >> > +                     slen += seg->len;
> >> > +
> >> > +             if (unlikely((u64)sch->qstats.backlog + slen > QDISC_MAX_BACKLOG)) {
> >> > +                     qdisc_qstats_overlimit(sch);
> >> > +                     /* __skb_gso_segment() puts SKB_GSO_CB at cb
> >> > +                      * offset 32, over tc_skb_cb.drop_reason; every
> >> > +                      * segment inherits it. Tag each one with the
> >> > +                      * qdisc drop reason.
> >> > +                      */
> >> > +                     skb_list_walk_safe(segs, seg, nskb)
> >> > +                             tcf_set_qdisc_drop_reason(seg,
> >> > +                                                       QDISC_DROP_OVERLIMIT);
> >> > +                     /* skb_gso_segment() moved sock_wfree to the tail
> >> > +                      * segment, so defer the list to to_free rather
> >> > +                      * than free it under the qdisc lock.
> >>
> >> I don't think this part of the comment is needed - we do all the drops
> >> using to_free, so the sock_wfree thing is irrelevant.
> >
> > I was trying to rationalize "the segs == skb fraglist". How about:
> > /* Fraglist GSO returns the original skb as head  (segs == skb), so
> > drop our ref first */
> > I can drop it if it seems obvious
>
> Yeah, that bit is fine to keep :)
>
> >> > +                      * Fraglist GSO returns the original skb as head
> >> > +                      * (segs == skb), so drop our ref first.
> >> > +                      */
> >> > +                     if (unlikely(segs == skb)) {
> >> > +                             consume_skb(skb);
> >> > +                             return qdisc_drop_all(segs, sch, to_free);
> >> > +                     }
> >> > +                     __qdisc_drop_all(segs, to_free);
> >> > +                     return qdisc_drop_reason(skb, sch, to_free,
> >> > +                                              QDISC_DROP_OVERLIMIT);
> >>
> >> Since you already set the drop reason above, there's not really any
> >> reason to use qdisc_drop_reason() anymore; so this logic can be
> >> simplified to simply:
> >>
> >>                         if (unlikely(segs == skb))
> >>                                 consume_skb(skb);
> >>                         return qdisc_drop_all(segs, sch, to_free);
> >>
> >
> > How does this look ?
> > tcf_set_qdisc_drop_reason(skb, QDISC_DROP_OVERLIMIT);
> > skb_list_walk_safe(segs, seg, nskb)
> >      tcf_set_qdisc_drop_reason(seg, QDISC_DROP_OVERLIMIT);
> >
> > if (unlikely(segs == skb)) {
> >         consume_skb(skb);
> >         return qdisc_drop_all(segs, sch, to_free);
> > }
> > __qdisc_drop_all(segs, to_free);
> > return qdisc_drop(skb, sch, to_free);
>
> Ah, right, got the 'segs' and 'skb' variables a bit confused, sorry
> about that.
>
> But, thinking about it some more:
>
> In both branches of your code above, we have a drop of the skb, and a
> drop_all of the segs. And the existing code already has an unconditional
> consume_skb() after segmentation, where none of the post-segmentation
> uses the 'skb' pointer.
>
> So wouldn't it be simpler to just add the consume_skb() unconditionally
> immediately after the skb_gso_segment() call? Something like this, on
> top of your patch:
>
> diff --git i/net/sched/sch_cake.c w/net/sched/sch_cake.c
> index 730c90af14bd..20173aaf973c 100644
> --- i/net/sched/sch_cake.c
> +++ w/net/sched/sch_cake.c
> @@ -1819,13 +1819,17 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
>         cake_hash_keys(skb, flow_mode, flow_override, host_override, &keys);
>
>         if (qdisc_pkt_segs(skb) > 1 && q->config->rate_flags & CAKE_FLAG_SPLIT_GSO) {
> -               struct sk_buff *nskb, *seg;
>                 netdev_features_t features = netif_skb_features(skb);
> +               struct sk_buff *nskb, *seg;
>
>                 segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK);
>                 if (IS_ERR_OR_NULL(segs))
>                         return qdisc_drop(skb, sch, to_free);
>
> +               /* we never use the original skb after splitting */
> +               consume_skb(skb);
> +               skb = NULL;
> +
>                 /* The split path accounts the segment sum, not the
>                  * stab-adjusted qdisc_pkt_len(), so check it here.
>                  */
> @@ -1842,20 +1846,8 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
>                         skb_list_walk_safe(segs, seg, nskb)
>                                 tcf_set_qdisc_drop_reason(seg,
>                                                           QDISC_DROP_OVERLIMIT);
> -                       /* skb_gso_segment() moved sock_wfree to the tail
> -                        * segment, so defer the list to to_free rather
> -                        * than free it under the qdisc lock.
> -                        *
> -                        * Fraglist GSO returns the original skb as head
> -                        * (segs == skb), so drop our ref first.
> -                        */
> -                       if (unlikely(segs == skb)) {
> -                               consume_skb(skb);
> -                               return qdisc_drop_all(segs, sch, to_free);
> -                       }
> -                       __qdisc_drop_all(segs, to_free);
> -                       return qdisc_drop_reason(skb, sch, to_free,
> -                                                QDISC_DROP_OVERLIMIT);
> +
> +                       return qdisc_drop_all(segs, sch, to_free);
>                 }
>         }
>
> @@ -1917,9 +1909,8 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
>                 WRITE_ONCE(b->backlogs[idx], b->backlogs[idx] + slen);
>
>                 qdisc_tree_reduce_backlog(sch, 1-numsegs, len-slen);
> -               consume_skb(skb);
>         } else {
> -               /* not splitting */
> +               /* not splitting - skb pointer still valid */
>                 int ack_pkt_len = 0;
>
>                 cobalt_set_enqueue_time(skb, now);
>
> >> > +             }
> >> > +     }
> >> > +
> >> > +     /* Admitted: resolve the flow. The mode is read once above, so
> >> > +      * extraction and resolution agree if cake_change() intervenes.
> >> > +      */
> >>
> >> The last sentence here is just distracting. Please drop.
> >>
> >
> > Ok.Will reword to: /* Admitted: resolve the flow. */
> >
> > I wont wait for the 7 days for sashiko to respond if we can reach a
> > quick consensus.
>
> Fine with me :)

I will resend with your suggestions.

pw-bot: cr

cheers,
jamal
> -Toke

      reply	other threads:[~2026-10-20 10:09 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-19 16:00 [Cake] [PATCH net-next v7 0/4] net/sched: cap the accounted backlog before it can wrap Jamal Hadi Salim
2026-10-19 16:00 ` [Cake] [PATCH net-next v7 1/4] net/sched: cake, fq_codel: return the classifier result to the caller Jamal Hadi Salim
2026-10-19 18:11   ` [Cake] " Toke Høiland-Jørgensen
2026-10-19 21:05     ` Jamal Hadi Salim
2026-10-20  8:58       ` Toke Høiland-Jørgensen
2026-10-20 10:06         ` Jamal Hadi Salim
2026-10-19 16:00 ` [Cake] [PATCH net-next v7 2/4] net/sched: cake: use a dedicated split-GSO list iterator Jamal Hadi Salim
2026-10-19 18:11   ` [Cake] " Toke Høiland-Jørgensen
2026-10-19 16:00 ` [Cake] [PATCH net-next v7 3/4] net/sched: cap the accounted backlog before it can wrap Jamal Hadi Salim
2026-10-19 18:20   ` [Cake] " Toke Høiland-Jørgensen
2026-10-19 21:08     ` Jamal Hadi Salim
2026-10-19 16:00 ` [Cake] [PATCH net-next v7 4/4] net/sched: cake: hash before segmenting and reject an overlong split Jamal Hadi Salim
2026-10-19 18:32   ` [Cake] " Toke Høiland-Jørgensen
2026-10-19 21:35     ` Jamal Hadi Salim
2026-10-20  8:47       ` Toke Høiland-Jørgensen
2026-10-20 10:08         ` Jamal Hadi Salim [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://lists.bufferbloat.net/postorius/lists/cake.lists.bufferbloat.net/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAM0EoM=rSqLatP2D72iKaeXSt95fTZvyP6wbPnvf_Ai53wq=ew@mail.gmail.com' \
    --to=jhs@mojatatu.com \
    --cc=bjorn@kernel.org \
    --cc=cake@lists.bufferbloat.net \
    --cc=davem@davemloft.net \
    --cc=edumazet@kernel.org \
    --cc=horms@kernel.org \
    --cc=jiri@resnulli.us \
    --cc=kuba@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=sashiko-bot@kernel.org \
    --cc=toke@toke.dk \
    --cc=victor@mojatatu.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox