net_sched: implement ->change_tx_queue_len() for pfifo_fast
authorCong Wang <xiyou.wangcong@gmail.com>
Fri, 26 Jan 2018 02:26:24 +0000 (18:26 -0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 29 Jan 2018 17:42:15 +0000 (12:42 -0500)
pfifo_fast used to drop based on qdisc_dev(qdisc)->tx_queue_len,
so we have to resize skb array when we change tx_queue_len.

Other qdiscs which read tx_queue_len are fine because they
all save it to sch->limit or somewhere else in qdisc during init.
They don't have to implement this, it is nicer if they do so
that users don't have to re-configure qdisc after changing
tx_queue_len.

Cc: John Fastabend <john.fastabend@gmail.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/sched/sch_generic.c

index 08f9fa2..190570f 100644 (file)
@@ -763,6 +763,23 @@ static void pfifo_fast_destroy(struct Qdisc *sch)
        }
 }
 
+static int pfifo_fast_change_tx_queue_len(struct Qdisc *sch,
+                                         unsigned int new_len)
+{
+       struct pfifo_fast_priv *priv = qdisc_priv(sch);
+       struct skb_array *bands[PFIFO_FAST_BANDS];
+       int prio;
+
+       for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) {
+               struct skb_array *q = band2list(priv, prio);
+
+               bands[prio] = q;
+       }
+
+       return skb_array_resize_multiple(bands, PFIFO_FAST_BANDS, new_len,
+                                        GFP_KERNEL);
+}
+
 struct Qdisc_ops pfifo_fast_ops __read_mostly = {
        .id             =       "pfifo_fast",
        .priv_size      =       sizeof(struct pfifo_fast_priv),
@@ -773,6 +790,7 @@ struct Qdisc_ops pfifo_fast_ops __read_mostly = {
        .destroy        =       pfifo_fast_destroy,
        .reset          =       pfifo_fast_reset,
        .dump           =       pfifo_fast_dump,
+       .change_tx_queue_len =  pfifo_fast_change_tx_queue_len,
        .owner          =       THIS_MODULE,
        .static_flags   =       TCQ_F_NOLOCK | TCQ_F_CPUSTATS,
 };