From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
patches@lists.linux.dev, Jamal Hadi Salim <jhs@mojatatu.com>,
Jiri Pirko <jiri@nvidia.com>, Paolo Abeni <pabeni@redhat.com>
Subject: [PATCH 6.1 001/195] net/sched: Retire CBQ qdisc
Date: Tue, 27 Feb 2024 14:24:22 +0100 [thread overview]
Message-ID: <20240227131610.444902810@linuxfoundation.org> (raw)
In-Reply-To: <20240227131610.391465389@linuxfoundation.org>
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <jhs@mojatatu.com>
commit 051d442098421c28c7951625652f61b1e15c4bd5 upstream.
While this amazing qdisc has served us well over the years it has not been
getting any tender love and care and has bitrotted over time.
It has become mostly a shooting target for syzkaller lately.
For this reason, we are retiring it. Goodbye CBQ - we loved you.
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Acked-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/sched/Kconfig | 17
net/sched/Makefile | 1
net/sched/sch_cbq.c | 1727 ------------
tools/testing/selftests/tc-testing/tc-tests/qdiscs/cbq.json | 184 -
4 files changed, 1929 deletions(-)
delete mode 100644 net/sched/sch_cbq.c
delete mode 100644 tools/testing/selftests/tc-testing/tc-tests/qdiscs/cbq.json
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -45,23 +45,6 @@ if NET_SCHED
comment "Queueing/Scheduling"
-config NET_SCH_CBQ
- tristate "Class Based Queueing (CBQ)"
- help
- Say Y here if you want to use the Class-Based Queueing (CBQ) packet
- scheduling algorithm. This algorithm classifies the waiting packets
- into a tree-like hierarchy of classes; the leaves of this tree are
- in turn scheduled by separate algorithms.
-
- See the top of <file:net/sched/sch_cbq.c> for more details.
-
- CBQ is a commonly used scheduler, so if you're unsure, you should
- say Y here. Then say Y to all the queueing algorithms below that you
- want to use as leaf disciplines.
-
- To compile this code as a module, choose M here: the
- module will be called sch_cbq.
-
config NET_SCH_HTB
tristate "Hierarchical Token Bucket (HTB)"
help
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -33,7 +33,6 @@ obj-$(CONFIG_NET_ACT_TUNNEL_KEY)+= act_t
obj-$(CONFIG_NET_ACT_CT) += act_ct.o
obj-$(CONFIG_NET_ACT_GATE) += act_gate.o
obj-$(CONFIG_NET_SCH_FIFO) += sch_fifo.o
-obj-$(CONFIG_NET_SCH_CBQ) += sch_cbq.o
obj-$(CONFIG_NET_SCH_HTB) += sch_htb.o
obj-$(CONFIG_NET_SCH_HFSC) += sch_hfsc.o
obj-$(CONFIG_NET_SCH_RED) += sch_red.o
--- a/net/sched/sch_cbq.c
+++ /dev/null
@@ -1,1727 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * net/sched/sch_cbq.c Class-Based Queueing discipline.
- *
- * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/skbuff.h>
-#include <net/netlink.h>
-#include <net/pkt_sched.h>
-#include <net/pkt_cls.h>
-
-
-/* Class-Based Queueing (CBQ) algorithm.
- =======================================
-
- Sources: [1] Sally Floyd and Van Jacobson, "Link-sharing and Resource
- Management Models for Packet Networks",
- IEEE/ACM Transactions on Networking, Vol.3, No.4, 1995
-
- [2] Sally Floyd, "Notes on CBQ and Guaranteed Service", 1995
-
- [3] Sally Floyd, "Notes on Class-Based Queueing: Setting
- Parameters", 1996
-
- [4] Sally Floyd and Michael Speer, "Experimental Results
- for Class-Based Queueing", 1998, not published.
-
- -----------------------------------------------------------------------
-
- Algorithm skeleton was taken from NS simulator cbq.cc.
- If someone wants to check this code against the LBL version,
- he should take into account that ONLY the skeleton was borrowed,
- the implementation is different. Particularly:
-
- --- The WRR algorithm is different. Our version looks more
- reasonable (I hope) and works when quanta are allowed to be
- less than MTU, which is always the case when real time classes
- have small rates. Note, that the statement of [3] is
- incomplete, delay may actually be estimated even if class
- per-round allotment is less than MTU. Namely, if per-round
- allotment is W*r_i, and r_1+...+r_k = r < 1
-
- delay_i <= ([MTU/(W*r_i)]*W*r + W*r + k*MTU)/B
-
- In the worst case we have IntServ estimate with D = W*r+k*MTU
- and C = MTU*r. The proof (if correct at all) is trivial.
-
-
- --- It seems that cbq-2.0 is not very accurate. At least, I cannot
- interpret some places, which look like wrong translations
- from NS. Anyone is advised to find these differences
- and explain to me, why I am wrong 8).
-
- --- Linux has no EOI event, so that we cannot estimate true class
- idle time. Workaround is to consider the next dequeue event
- as sign that previous packet is finished. This is wrong because of
- internal device queueing, but on a permanently loaded link it is true.
- Moreover, combined with clock integrator, this scheme looks
- very close to an ideal solution. */
-
-struct cbq_sched_data;
-
-
-struct cbq_class {
- struct Qdisc_class_common common;
- struct cbq_class *next_alive; /* next class with backlog in this priority band */
-
-/* Parameters */
- unsigned char priority; /* class priority */
- unsigned char priority2; /* priority to be used after overlimit */
- unsigned char ewma_log; /* time constant for idle time calculation */
-
- u32 defmap;
-
- /* Link-sharing scheduler parameters */
- long maxidle; /* Class parameters: see below. */
- long offtime;
- long minidle;
- u32 avpkt;
- struct qdisc_rate_table *R_tab;
-
- /* General scheduler (WRR) parameters */
- long allot;
- long quantum; /* Allotment per WRR round */
- long weight; /* Relative allotment: see below */
-
- struct Qdisc *qdisc; /* Ptr to CBQ discipline */
- struct cbq_class *split; /* Ptr to split node */
- struct cbq_class *share; /* Ptr to LS parent in the class tree */
- struct cbq_class *tparent; /* Ptr to tree parent in the class tree */
- struct cbq_class *borrow; /* NULL if class is bandwidth limited;
- parent otherwise */
- struct cbq_class *sibling; /* Sibling chain */
- struct cbq_class *children; /* Pointer to children chain */
-
- struct Qdisc *q; /* Elementary queueing discipline */
-
-
-/* Variables */
- unsigned char cpriority; /* Effective priority */
- unsigned char delayed;
- unsigned char level; /* level of the class in hierarchy:
- 0 for leaf classes, and maximal
- level of children + 1 for nodes.
- */
-
- psched_time_t last; /* Last end of service */
- psched_time_t undertime;
- long avgidle;
- long deficit; /* Saved deficit for WRR */
- psched_time_t penalized;
- struct gnet_stats_basic_sync bstats;
- struct gnet_stats_queue qstats;
- struct net_rate_estimator __rcu *rate_est;
- struct tc_cbq_xstats xstats;
-
- struct tcf_proto __rcu *filter_list;
- struct tcf_block *block;
-
- int filters;
-
- struct cbq_class *defaults[TC_PRIO_MAX + 1];
-};
-
-struct cbq_sched_data {
- struct Qdisc_class_hash clhash; /* Hash table of all classes */
- int nclasses[TC_CBQ_MAXPRIO + 1];
- unsigned int quanta[TC_CBQ_MAXPRIO + 1];
-
- struct cbq_class link;
-
- unsigned int activemask;
- struct cbq_class *active[TC_CBQ_MAXPRIO + 1]; /* List of all classes
- with backlog */
-
-#ifdef CONFIG_NET_CLS_ACT
- struct cbq_class *rx_class;
-#endif
- struct cbq_class *tx_class;
- struct cbq_class *tx_borrowed;
- int tx_len;
- psched_time_t now; /* Cached timestamp */
- unsigned int pmask;
-
- struct qdisc_watchdog watchdog; /* Watchdog timer,
- started when CBQ has
- backlog, but cannot
- transmit just now */
- psched_tdiff_t wd_expires;
- int toplevel;
- u32 hgenerator;
-};
-
-
-#define L2T(cl, len) qdisc_l2t((cl)->R_tab, len)
-
-static inline struct cbq_class *
-cbq_class_lookup(struct cbq_sched_data *q, u32 classid)
-{
- struct Qdisc_class_common *clc;
-
- clc = qdisc_class_find(&q->clhash, classid);
- if (clc == NULL)
- return NULL;
- return container_of(clc, struct cbq_class, common);
-}
-
-#ifdef CONFIG_NET_CLS_ACT
-
-static struct cbq_class *
-cbq_reclassify(struct sk_buff *skb, struct cbq_class *this)
-{
- struct cbq_class *cl;
-
- for (cl = this->tparent; cl; cl = cl->tparent) {
- struct cbq_class *new = cl->defaults[TC_PRIO_BESTEFFORT];
-
- if (new != NULL && new != this)
- return new;
- }
- return NULL;
-}
-
-#endif
-
-/* Classify packet. The procedure is pretty complicated, but
- * it allows us to combine link sharing and priority scheduling
- * transparently.
- *
- * Namely, you can put link sharing rules (f.e. route based) at root of CBQ,
- * so that it resolves to split nodes. Then packets are classified
- * by logical priority, or a more specific classifier may be attached
- * to the split node.
- */
-
-static struct cbq_class *
-cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
-{
- struct cbq_sched_data *q = qdisc_priv(sch);
- struct cbq_class *head = &q->link;
- struct cbq_class **defmap;
- struct cbq_class *cl = NULL;
- u32 prio = skb->priority;
- struct tcf_proto *fl;
- struct tcf_result res;
-
- /*
- * Step 1. If skb->priority points to one of our classes, use it.
- */
- if (TC_H_MAJ(prio ^ sch->handle) == 0 &&
- (cl = cbq_class_lookup(q, prio)) != NULL)
- return cl;
-
- *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
- for (;;) {
- int result = 0;
- defmap = head->defaults;
-
- fl = rcu_dereference_bh(head->filter_list);
- /*
- * Step 2+n. Apply classifier.
- */
- result = tcf_classify(skb, NULL, fl, &res, true);
- if (!fl || result < 0)
- goto fallback;
- if (result == TC_ACT_SHOT)
- return NULL;
-
- cl = (void *)res.class;
- if (!cl) {
- if (TC_H_MAJ(res.classid))
- cl = cbq_class_lookup(q, res.classid);
- else if ((cl = defmap[res.classid & TC_PRIO_MAX]) == NULL)
- cl = defmap[TC_PRIO_BESTEFFORT];
-
- if (cl == NULL)
- goto fallback;
- }
- if (cl->level >= head->level)
- goto fallback;
-#ifdef CONFIG_NET_CLS_ACT
- switch (result) {
- case TC_ACT_QUEUED:
- case TC_ACT_STOLEN:
- case TC_ACT_TRAP:
- *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
- fallthrough;
- case TC_ACT_RECLASSIFY:
- return cbq_reclassify(skb, cl);
- }
-#endif
- if (cl->level == 0)
- return cl;
-
- /*
- * Step 3+n. If classifier selected a link sharing class,
- * apply agency specific classifier.
- * Repeat this procedure until we hit a leaf node.
- */
- head = cl;
- }
-
-fallback:
- cl = head;
-
- /*
- * Step 4. No success...
- */
- if (TC_H_MAJ(prio) == 0 &&
- !(cl = head->defaults[prio & TC_PRIO_MAX]) &&
- !(cl = head->defaults[TC_PRIO_BESTEFFORT]))
- return head;
-
- return cl;
-}
-
-/*
- * A packet has just been enqueued on the empty class.
- * cbq_activate_class adds it to the tail of active class list
- * of its priority band.
- */
-
-static inline void cbq_activate_class(struct cbq_class *cl)
-{
- struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
- int prio = cl->cpriority;
- struct cbq_class *cl_tail;
-
- cl_tail = q->active[prio];
- q->active[prio] = cl;
-
- if (cl_tail != NULL) {
- cl->next_alive = cl_tail->next_alive;
- cl_tail->next_alive = cl;
- } else {
- cl->next_alive = cl;
- q->activemask |= (1<<prio);
- }
-}
-
-/*
- * Unlink class from active chain.
- * Note that this same procedure is done directly in cbq_dequeue*
- * during round-robin procedure.
- */
-
-static void cbq_deactivate_class(struct cbq_class *this)
-{
- struct cbq_sched_data *q = qdisc_priv(this->qdisc);
- int prio = this->cpriority;
- struct cbq_class *cl;
- struct cbq_class *cl_prev = q->active[prio];
-
- do {
- cl = cl_prev->next_alive;
- if (cl == this) {
- cl_prev->next_alive = cl->next_alive;
- cl->next_alive = NULL;
-
- if (cl == q->active[prio]) {
- q->active[prio] = cl_prev;
- if (cl == q->active[prio]) {
- q->active[prio] = NULL;
- q->activemask &= ~(1<<prio);
- return;
- }
- }
- return;
- }
- } while ((cl_prev = cl) != q->active[prio]);
-}
-
-static void
-cbq_mark_toplevel(struct cbq_sched_data *q, struct cbq_class *cl)
-{
- int toplevel = q->toplevel;
-
- if (toplevel > cl->level) {
- psched_time_t now = psched_get_time();
-
- do {
- if (cl->undertime < now) {
- q->toplevel = cl->level;
- return;
- }
- } while ((cl = cl->borrow) != NULL && toplevel > cl->level);
- }
-}
-
-static int
-cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch,
- struct sk_buff **to_free)
-{
- struct cbq_sched_data *q = qdisc_priv(sch);
- int ret;
- struct cbq_class *cl = cbq_classify(skb, sch, &ret);
-
-#ifdef CONFIG_NET_CLS_ACT
- q->rx_class = cl;
-#endif
- if (cl == NULL) {
- if (ret & __NET_XMIT_BYPASS)
- qdisc_qstats_drop(sch);
- __qdisc_drop(skb, to_free);
- return ret;
- }
-
- ret = qdisc_enqueue(skb, cl->q, to_free);
- if (ret == NET_XMIT_SUCCESS) {
- sch->q.qlen++;
- cbq_mark_toplevel(q, cl);
- if (!cl->next_alive)
- cbq_activate_class(cl);
- return ret;
- }
-
- if (net_xmit_drop_count(ret)) {
- qdisc_qstats_drop(sch);
- cbq_mark_toplevel(q, cl);
- cl->qstats.drops++;
- }
- return ret;
-}
-
-/* Overlimit action: penalize leaf class by adding offtime */
-static void cbq_overlimit(struct cbq_class *cl)
-{
- struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
- psched_tdiff_t delay = cl->undertime - q->now;
-
- if (!cl->delayed) {
- delay += cl->offtime;
-
- /*
- * Class goes to sleep, so that it will have no
- * chance to work avgidle. Let's forgive it 8)
- *
- * BTW cbq-2.0 has a crap in this
- * place, apparently they forgot to shift it by cl->ewma_log.
- */
- if (cl->avgidle < 0)
- delay -= (-cl->avgidle) - ((-cl->avgidle) >> cl->ewma_log);
- if (cl->avgidle < cl->minidle)
- cl->avgidle = cl->minidle;
- if (delay <= 0)
- delay = 1;
- cl->undertime = q->now + delay;
-
- cl->xstats.overactions++;
- cl->delayed = 1;
- }
- if (q->wd_expires == 0 || q->wd_expires > delay)
- q->wd_expires = delay;
-
- /* Dirty work! We must schedule wakeups based on
- * real available rate, rather than leaf rate,
- * which may be tiny (even zero).
- */
- if (q->toplevel == TC_CBQ_MAXLEVEL) {
- struct cbq_class *b;
- psched_tdiff_t base_delay = q->wd_expires;
-
- for (b = cl->borrow; b; b = b->borrow) {
- delay = b->undertime - q->now;
- if (delay < base_delay) {
- if (delay <= 0)
- delay = 1;
- base_delay = delay;
- }
- }
-
- q->wd_expires = base_delay;
- }
-}
-
-/*
- * It is mission critical procedure.
- *
- * We "regenerate" toplevel cutoff, if transmitting class
- * has backlog and it is not regulated. It is not part of
- * original CBQ description, but looks more reasonable.
- * Probably, it is wrong. This question needs further investigation.
- */
-
-static inline void
-cbq_update_toplevel(struct cbq_sched_data *q, struct cbq_class *cl,
- struct cbq_class *borrowed)
-{
- if (cl && q->toplevel >= borrowed->level) {
- if (cl->q->q.qlen > 1) {
- do {
- if (borrowed->undertime == PSCHED_PASTPERFECT) {
- q->toplevel = borrowed->level;
- return;
- }
- } while ((borrowed = borrowed->borrow) != NULL);
- }
-#if 0
- /* It is not necessary now. Uncommenting it
- will save CPU cycles, but decrease fairness.
- */
- q->toplevel = TC_CBQ_MAXLEVEL;
-#endif
- }
-}
-
-static void
-cbq_update(struct cbq_sched_data *q)
-{
- struct cbq_class *this = q->tx_class;
- struct cbq_class *cl = this;
- int len = q->tx_len;
- psched_time_t now;
-
- q->tx_class = NULL;
- /* Time integrator. We calculate EOS time
- * by adding expected packet transmission time.
- */
- now = q->now + L2T(&q->link, len);
-
- for ( ; cl; cl = cl->share) {
- long avgidle = cl->avgidle;
- long idle;
-
- _bstats_update(&cl->bstats, len, 1);
-
- /*
- * (now - last) is total time between packet right edges.
- * (last_pktlen/rate) is "virtual" busy time, so that
- *
- * idle = (now - last) - last_pktlen/rate
- */
-
- idle = now - cl->last;
- if ((unsigned long)idle > 128*1024*1024) {
- avgidle = cl->maxidle;
- } else {
- idle -= L2T(cl, len);
-
- /* true_avgidle := (1-W)*true_avgidle + W*idle,
- * where W=2^{-ewma_log}. But cl->avgidle is scaled:
- * cl->avgidle == true_avgidle/W,
- * hence:
- */
- avgidle += idle - (avgidle>>cl->ewma_log);
- }
-
- if (avgidle <= 0) {
- /* Overlimit or at-limit */
-
- if (avgidle < cl->minidle)
- avgidle = cl->minidle;
-
- cl->avgidle = avgidle;
-
- /* Calculate expected time, when this class
- * will be allowed to send.
- * It will occur, when:
- * (1-W)*true_avgidle + W*delay = 0, i.e.
- * idle = (1/W - 1)*(-true_avgidle)
- * or
- * idle = (1 - W)*(-cl->avgidle);
- */
- idle = (-avgidle) - ((-avgidle) >> cl->ewma_log);
-
- /*
- * That is not all.
- * To maintain the rate allocated to the class,
- * we add to undertime virtual clock,
- * necessary to complete transmitted packet.
- * (len/phys_bandwidth has been already passed
- * to the moment of cbq_update)
- */
-
- idle -= L2T(&q->link, len);
- idle += L2T(cl, len);
-
- cl->undertime = now + idle;
- } else {
- /* Underlimit */
-
- cl->undertime = PSCHED_PASTPERFECT;
- if (avgidle > cl->maxidle)
- cl->avgidle = cl->maxidle;
- else
- cl->avgidle = avgidle;
- }
- if ((s64)(now - cl->last) > 0)
- cl->last = now;
- }
-
- cbq_update_toplevel(q, this, q->tx_borrowed);
-}
-
-static inline struct cbq_class *
-cbq_under_limit(struct cbq_class *cl)
-{
- struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
- struct cbq_class *this_cl = cl;
-
- if (cl->tparent == NULL)
- return cl;
-
- if (cl->undertime == PSCHED_PASTPERFECT || q->now >= cl->undertime) {
- cl->delayed = 0;
- return cl;
- }
-
- do {
- /* It is very suspicious place. Now overlimit
- * action is generated for not bounded classes
- * only if link is completely congested.
- * Though it is in agree with ancestor-only paradigm,
- * it looks very stupid. Particularly,
- * it means that this chunk of code will either
- * never be called or result in strong amplification
- * of burstiness. Dangerous, silly, and, however,
- * no another solution exists.
- */
- cl = cl->borrow;
- if (!cl) {
- this_cl->qstats.overlimits++;
- cbq_overlimit(this_cl);
- return NULL;
- }
- if (cl->level > q->toplevel)
- return NULL;
- } while (cl->undertime != PSCHED_PASTPERFECT && q->now < cl->undertime);
-
- cl->delayed = 0;
- return cl;
-}
-
-static inline struct sk_buff *
-cbq_dequeue_prio(struct Qdisc *sch, int prio)
-{
- struct cbq_sched_data *q = qdisc_priv(sch);
- struct cbq_class *cl_tail, *cl_prev, *cl;
- struct sk_buff *skb;
- int deficit;
-
- cl_tail = cl_prev = q->active[prio];
- cl = cl_prev->next_alive;
-
- do {
- deficit = 0;
-
- /* Start round */
- do {
- struct cbq_class *borrow = cl;
-
- if (cl->q->q.qlen &&
- (borrow = cbq_under_limit(cl)) == NULL)
- goto skip_class;
-
- if (cl->deficit <= 0) {
- /* Class exhausted its allotment per
- * this round. Switch to the next one.
- */
- deficit = 1;
- cl->deficit += cl->quantum;
- goto next_class;
- }
-
- skb = cl->q->dequeue(cl->q);
-
- /* Class did not give us any skb :-(
- * It could occur even if cl->q->q.qlen != 0
- * f.e. if cl->q == "tbf"
- */
- if (skb == NULL)
- goto skip_class;
-
- cl->deficit -= qdisc_pkt_len(skb);
- q->tx_class = cl;
- q->tx_borrowed = borrow;
- if (borrow != cl) {
-#ifndef CBQ_XSTATS_BORROWS_BYTES
- borrow->xstats.borrows++;
- cl->xstats.borrows++;
-#else
- borrow->xstats.borrows += qdisc_pkt_len(skb);
- cl->xstats.borrows += qdisc_pkt_len(skb);
-#endif
- }
- q->tx_len = qdisc_pkt_len(skb);
-
- if (cl->deficit <= 0) {
- q->active[prio] = cl;
- cl = cl->next_alive;
- cl->deficit += cl->quantum;
- }
- return skb;
-
-skip_class:
- if (cl->q->q.qlen == 0 || prio != cl->cpriority) {
- /* Class is empty or penalized.
- * Unlink it from active chain.
- */
- cl_prev->next_alive = cl->next_alive;
- cl->next_alive = NULL;
-
- /* Did cl_tail point to it? */
- if (cl == cl_tail) {
- /* Repair it! */
- cl_tail = cl_prev;
-
- /* Was it the last class in this band? */
- if (cl == cl_tail) {
- /* Kill the band! */
- q->active[prio] = NULL;
- q->activemask &= ~(1<<prio);
- if (cl->q->q.qlen)
- cbq_activate_class(cl);
- return NULL;
- }
-
- q->active[prio] = cl_tail;
- }
- if (cl->q->q.qlen)
- cbq_activate_class(cl);
-
- cl = cl_prev;
- }
-
-next_class:
- cl_prev = cl;
- cl = cl->next_alive;
- } while (cl_prev != cl_tail);
- } while (deficit);
-
- q->active[prio] = cl_prev;
-
- return NULL;
-}
-
-static inline struct sk_buff *
-cbq_dequeue_1(struct Qdisc *sch)
-{
- struct cbq_sched_data *q = qdisc_priv(sch);
- struct sk_buff *skb;
- unsigned int activemask;
-
- activemask = q->activemask & 0xFF;
- while (activemask) {
- int prio = ffz(~activemask);
- activemask &= ~(1<<prio);
- skb = cbq_dequeue_prio(sch, prio);
- if (skb)
- return skb;
- }
- return NULL;
-}
-
-static struct sk_buff *
-cbq_dequeue(struct Qdisc *sch)
-{
- struct sk_buff *skb;
- struct cbq_sched_data *q = qdisc_priv(sch);
- psched_time_t now;
-
- now = psched_get_time();
-
- if (q->tx_class)
- cbq_update(q);
-
- q->now = now;
-
- for (;;) {
- q->wd_expires = 0;
-
- skb = cbq_dequeue_1(sch);
- if (skb) {
- qdisc_bstats_update(sch, skb);
- sch->q.qlen--;
- return skb;
- }
-
- /* All the classes are overlimit.
- *
- * It is possible, if:
- *
- * 1. Scheduler is empty.
- * 2. Toplevel cutoff inhibited borrowing.
- * 3. Root class is overlimit.
- *
- * Reset 2d and 3d conditions and retry.
- *
- * Note, that NS and cbq-2.0 are buggy, peeking
- * an arbitrary class is appropriate for ancestor-only
- * sharing, but not for toplevel algorithm.
- *
- * Our version is better, but slower, because it requires
- * two passes, but it is unavoidable with top-level sharing.
- */
-
- if (q->toplevel == TC_CBQ_MAXLEVEL &&
- q->link.undertime == PSCHED_PASTPERFECT)
- break;
-
- q->toplevel = TC_CBQ_MAXLEVEL;
- q->link.undertime = PSCHED_PASTPERFECT;
- }
-
- /* No packets in scheduler or nobody wants to give them to us :-(
- * Sigh... start watchdog timer in the last case.
- */
-
- if (sch->q.qlen) {
- qdisc_qstats_overlimit(sch);
- if (q->wd_expires)
- qdisc_watchdog_schedule(&q->watchdog,
- now + q->wd_expires);
- }
- return NULL;
-}
-
-/* CBQ class maintenance routines */
-
-static void cbq_adjust_levels(struct cbq_class *this)
-{
- if (this == NULL)
- return;
-
- do {
- int level = 0;
- struct cbq_class *cl;
-
- cl = this->children;
- if (cl) {
- do {
- if (cl->level > level)
- level = cl->level;
- } while ((cl = cl->sibling) != this->children);
- }
- this->level = level + 1;
- } while ((this = this->tparent) != NULL);
-}
-
-static void cbq_normalize_quanta(struct cbq_sched_data *q, int prio)
-{
- struct cbq_class *cl;
- unsigned int h;
-
- if (q->quanta[prio] == 0)
- return;
-
- for (h = 0; h < q->clhash.hashsize; h++) {
- hlist_for_each_entry(cl, &q->clhash.hash[h], common.hnode) {
- /* BUGGGG... Beware! This expression suffer of
- * arithmetic overflows!
- */
- if (cl->priority == prio) {
- cl->quantum = (cl->weight*cl->allot*q->nclasses[prio])/
- q->quanta[prio];
- }
- if (cl->quantum <= 0 ||
- cl->quantum > 32*qdisc_dev(cl->qdisc)->mtu) {
- pr_warn("CBQ: class %08x has bad quantum==%ld, repaired.\n",
- cl->common.classid, cl->quantum);
- cl->quantum = qdisc_dev(cl->qdisc)->mtu/2 + 1;
- }
- }
- }
-}
-
-static void cbq_sync_defmap(struct cbq_class *cl)
-{
- struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
- struct cbq_class *split = cl->split;
- unsigned int h;
- int i;
-
- if (split == NULL)
- return;
-
- for (i = 0; i <= TC_PRIO_MAX; i++) {
- if (split->defaults[i] == cl && !(cl->defmap & (1<<i)))
- split->defaults[i] = NULL;
- }
-
- for (i = 0; i <= TC_PRIO_MAX; i++) {
- int level = split->level;
-
- if (split->defaults[i])
- continue;
-
- for (h = 0; h < q->clhash.hashsize; h++) {
- struct cbq_class *c;
-
- hlist_for_each_entry(c, &q->clhash.hash[h],
- common.hnode) {
- if (c->split == split && c->level < level &&
- c->defmap & (1<<i)) {
- split->defaults[i] = c;
- level = c->level;
- }
- }
- }
- }
-}
-
-static void cbq_change_defmap(struct cbq_class *cl, u32 splitid, u32 def, u32 mask)
-{
- struct cbq_class *split = NULL;
-
- if (splitid == 0) {
- split = cl->split;
- if (!split)
- return;
- splitid = split->common.classid;
- }
-
- if (split == NULL || split->common.classid != splitid) {
- for (split = cl->tparent; split; split = split->tparent)
- if (split->common.classid == splitid)
- break;
- }
-
- if (split == NULL)
- return;
-
- if (cl->split != split) {
- cl->defmap = 0;
- cbq_sync_defmap(cl);
- cl->split = split;
- cl->defmap = def & mask;
- } else
- cl->defmap = (cl->defmap & ~mask) | (def & mask);
-
- cbq_sync_defmap(cl);
-}
-
-static void cbq_unlink_class(struct cbq_class *this)
-{
- struct cbq_class *cl, **clp;
- struct cbq_sched_data *q = qdisc_priv(this->qdisc);
-
- qdisc_class_hash_remove(&q->clhash, &this->common);
-
- if (this->tparent) {
- clp = &this->sibling;
- cl = *clp;
- do {
- if (cl == this) {
- *clp = cl->sibling;
- break;
- }
- clp = &cl->sibling;
- } while ((cl = *clp) != this->sibling);
-
- if (this->tparent->children == this) {
- this->tparent->children = this->sibling;
- if (this->sibling == this)
- this->tparent->children = NULL;
- }
- } else {
- WARN_ON(this->sibling != this);
- }
-}
-
-static void cbq_link_class(struct cbq_class *this)
-{
- struct cbq_sched_data *q = qdisc_priv(this->qdisc);
- struct cbq_class *parent = this->tparent;
-
- this->sibling = this;
- qdisc_class_hash_insert(&q->clhash, &this->common);
-
- if (parent == NULL)
- return;
-
- if (parent->children == NULL) {
- parent->children = this;
- } else {
- this->sibling = parent->children->sibling;
- parent->children->sibling = this;
- }
-}
-
-static void
-cbq_reset(struct Qdisc *sch)
-{
- struct cbq_sched_data *q = qdisc_priv(sch);
- struct cbq_class *cl;
- int prio;
- unsigned int h;
-
- q->activemask = 0;
- q->pmask = 0;
- q->tx_class = NULL;
- q->tx_borrowed = NULL;
- qdisc_watchdog_cancel(&q->watchdog);
- q->toplevel = TC_CBQ_MAXLEVEL;
- q->now = psched_get_time();
-
- for (prio = 0; prio <= TC_CBQ_MAXPRIO; prio++)
- q->active[prio] = NULL;
-
- for (h = 0; h < q->clhash.hashsize; h++) {
- hlist_for_each_entry(cl, &q->clhash.hash[h], common.hnode) {
- qdisc_reset(cl->q);
-
- cl->next_alive = NULL;
- cl->undertime = PSCHED_PASTPERFECT;
- cl->avgidle = cl->maxidle;
- cl->deficit = cl->quantum;
- cl->cpriority = cl->priority;
- }
- }
-}
-
-
-static void cbq_set_lss(struct cbq_class *cl, struct tc_cbq_lssopt *lss)
-{
- if (lss->change & TCF_CBQ_LSS_FLAGS) {
- cl->share = (lss->flags & TCF_CBQ_LSS_ISOLATED) ? NULL : cl->tparent;
- cl->borrow = (lss->flags & TCF_CBQ_LSS_BOUNDED) ? NULL : cl->tparent;
- }
- if (lss->change & TCF_CBQ_LSS_EWMA)
- cl->ewma_log = lss->ewma_log;
- if (lss->change & TCF_CBQ_LSS_AVPKT)
- cl->avpkt = lss->avpkt;
- if (lss->change & TCF_CBQ_LSS_MINIDLE)
- cl->minidle = -(long)lss->minidle;
- if (lss->change & TCF_CBQ_LSS_MAXIDLE) {
- cl->maxidle = lss->maxidle;
- cl->avgidle = lss->maxidle;
- }
- if (lss->change & TCF_CBQ_LSS_OFFTIME)
- cl->offtime = lss->offtime;
-}
-
-static void cbq_rmprio(struct cbq_sched_data *q, struct cbq_class *cl)
-{
- q->nclasses[cl->priority]--;
- q->quanta[cl->priority] -= cl->weight;
- cbq_normalize_quanta(q, cl->priority);
-}
-
-static void cbq_addprio(struct cbq_sched_data *q, struct cbq_class *cl)
-{
- q->nclasses[cl->priority]++;
- q->quanta[cl->priority] += cl->weight;
- cbq_normalize_quanta(q, cl->priority);
-}
-
-static int cbq_set_wrr(struct cbq_class *cl, struct tc_cbq_wrropt *wrr)
-{
- struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
-
- if (wrr->allot)
- cl->allot = wrr->allot;
- if (wrr->weight)
- cl->weight = wrr->weight;
- if (wrr->priority) {
- cl->priority = wrr->priority - 1;
- cl->cpriority = cl->priority;
- if (cl->priority >= cl->priority2)
- cl->priority2 = TC_CBQ_MAXPRIO - 1;
- }
-
- cbq_addprio(q, cl);
- return 0;
-}
-
-static int cbq_set_fopt(struct cbq_class *cl, struct tc_cbq_fopt *fopt)
-{
- cbq_change_defmap(cl, fopt->split, fopt->defmap, fopt->defchange);
- return 0;
-}
-
-static const struct nla_policy cbq_policy[TCA_CBQ_MAX + 1] = {
- [TCA_CBQ_LSSOPT] = { .len = sizeof(struct tc_cbq_lssopt) },
- [TCA_CBQ_WRROPT] = { .len = sizeof(struct tc_cbq_wrropt) },
- [TCA_CBQ_FOPT] = { .len = sizeof(struct tc_cbq_fopt) },
- [TCA_CBQ_OVL_STRATEGY] = { .len = sizeof(struct tc_cbq_ovl) },
- [TCA_CBQ_RATE] = { .len = sizeof(struct tc_ratespec) },
- [TCA_CBQ_RTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE },
- [TCA_CBQ_POLICE] = { .len = sizeof(struct tc_cbq_police) },
-};
-
-static int cbq_opt_parse(struct nlattr *tb[TCA_CBQ_MAX + 1],
- struct nlattr *opt,
- struct netlink_ext_ack *extack)
-{
- int err;
-
- if (!opt) {
- NL_SET_ERR_MSG(extack, "CBQ options are required for this operation");
- return -EINVAL;
- }
-
- err = nla_parse_nested_deprecated(tb, TCA_CBQ_MAX, opt,
- cbq_policy, extack);
- if (err < 0)
- return err;
-
- if (tb[TCA_CBQ_WRROPT]) {
- const struct tc_cbq_wrropt *wrr = nla_data(tb[TCA_CBQ_WRROPT]);
-
- if (wrr->priority > TC_CBQ_MAXPRIO) {
- NL_SET_ERR_MSG(extack, "priority is bigger than TC_CBQ_MAXPRIO");
- err = -EINVAL;
- }
- }
- return err;
-}
-
-static int cbq_init(struct Qdisc *sch, struct nlattr *opt,
- struct netlink_ext_ack *extack)
-{
- struct cbq_sched_data *q = qdisc_priv(sch);
- struct nlattr *tb[TCA_CBQ_MAX + 1];
- struct tc_ratespec *r;
- int err;
-
- qdisc_watchdog_init(&q->watchdog, sch);
-
- err = cbq_opt_parse(tb, opt, extack);
- if (err < 0)
- return err;
-
- if (!tb[TCA_CBQ_RTAB] || !tb[TCA_CBQ_RATE]) {
- NL_SET_ERR_MSG(extack, "Rate specification missing or incomplete");
- return -EINVAL;
- }
-
- r = nla_data(tb[TCA_CBQ_RATE]);
-
- q->link.R_tab = qdisc_get_rtab(r, tb[TCA_CBQ_RTAB], extack);
- if (!q->link.R_tab)
- return -EINVAL;
-
- err = tcf_block_get(&q->link.block, &q->link.filter_list, sch, extack);
- if (err)
- goto put_rtab;
-
- err = qdisc_class_hash_init(&q->clhash);
- if (err < 0)
- goto put_block;
-
- q->link.sibling = &q->link;
- q->link.common.classid = sch->handle;
- q->link.qdisc = sch;
- q->link.q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
- sch->handle, NULL);
- if (!q->link.q)
- q->link.q = &noop_qdisc;
- else
- qdisc_hash_add(q->link.q, true);
-
- q->link.priority = TC_CBQ_MAXPRIO - 1;
- q->link.priority2 = TC_CBQ_MAXPRIO - 1;
- q->link.cpriority = TC_CBQ_MAXPRIO - 1;
- q->link.allot = psched_mtu(qdisc_dev(sch));
- q->link.quantum = q->link.allot;
- q->link.weight = q->link.R_tab->rate.rate;
-
- q->link.ewma_log = TC_CBQ_DEF_EWMA;
- q->link.avpkt = q->link.allot/2;
- q->link.minidle = -0x7FFFFFFF;
-
- q->toplevel = TC_CBQ_MAXLEVEL;
- q->now = psched_get_time();
-
- cbq_link_class(&q->link);
-
- if (tb[TCA_CBQ_LSSOPT])
- cbq_set_lss(&q->link, nla_data(tb[TCA_CBQ_LSSOPT]));
-
- cbq_addprio(q, &q->link);
- return 0;
-
-put_block:
- tcf_block_put(q->link.block);
-
-put_rtab:
- qdisc_put_rtab(q->link.R_tab);
- return err;
-}
-
-static int cbq_dump_rate(struct sk_buff *skb, struct cbq_class *cl)
-{
- unsigned char *b = skb_tail_pointer(skb);
-
- if (nla_put(skb, TCA_CBQ_RATE, sizeof(cl->R_tab->rate), &cl->R_tab->rate))
- goto nla_put_failure;
- return skb->len;
-
-nla_put_failure:
- nlmsg_trim(skb, b);
- return -1;
-}
-
-static int cbq_dump_lss(struct sk_buff *skb, struct cbq_class *cl)
-{
- unsigned char *b = skb_tail_pointer(skb);
- struct tc_cbq_lssopt opt;
-
- opt.flags = 0;
- if (cl->borrow == NULL)
- opt.flags |= TCF_CBQ_LSS_BOUNDED;
- if (cl->share == NULL)
- opt.flags |= TCF_CBQ_LSS_ISOLATED;
- opt.ewma_log = cl->ewma_log;
- opt.level = cl->level;
- opt.avpkt = cl->avpkt;
- opt.maxidle = cl->maxidle;
- opt.minidle = (u32)(-cl->minidle);
- opt.offtime = cl->offtime;
- opt.change = ~0;
- if (nla_put(skb, TCA_CBQ_LSSOPT, sizeof(opt), &opt))
- goto nla_put_failure;
- return skb->len;
-
-nla_put_failure:
- nlmsg_trim(skb, b);
- return -1;
-}
-
-static int cbq_dump_wrr(struct sk_buff *skb, struct cbq_class *cl)
-{
- unsigned char *b = skb_tail_pointer(skb);
- struct tc_cbq_wrropt opt;
-
- memset(&opt, 0, sizeof(opt));
- opt.flags = 0;
- opt.allot = cl->allot;
- opt.priority = cl->priority + 1;
- opt.cpriority = cl->cpriority + 1;
- opt.weight = cl->weight;
- if (nla_put(skb, TCA_CBQ_WRROPT, sizeof(opt), &opt))
- goto nla_put_failure;
- return skb->len;
-
-nla_put_failure:
- nlmsg_trim(skb, b);
- return -1;
-}
-
-static int cbq_dump_fopt(struct sk_buff *skb, struct cbq_class *cl)
-{
- unsigned char *b = skb_tail_pointer(skb);
- struct tc_cbq_fopt opt;
-
- if (cl->split || cl->defmap) {
- opt.split = cl->split ? cl->split->common.classid : 0;
- opt.defmap = cl->defmap;
- opt.defchange = ~0;
- if (nla_put(skb, TCA_CBQ_FOPT, sizeof(opt), &opt))
- goto nla_put_failure;
- }
- return skb->len;
-
-nla_put_failure:
- nlmsg_trim(skb, b);
- return -1;
-}
-
-static int cbq_dump_attr(struct sk_buff *skb, struct cbq_class *cl)
-{
- if (cbq_dump_lss(skb, cl) < 0 ||
- cbq_dump_rate(skb, cl) < 0 ||
- cbq_dump_wrr(skb, cl) < 0 ||
- cbq_dump_fopt(skb, cl) < 0)
- return -1;
- return 0;
-}
-
-static int cbq_dump(struct Qdisc *sch, struct sk_buff *skb)
-{
- struct cbq_sched_data *q = qdisc_priv(sch);
- struct nlattr *nest;
-
- nest = nla_nest_start_noflag(skb, TCA_OPTIONS);
- if (nest == NULL)
- goto nla_put_failure;
- if (cbq_dump_attr(skb, &q->link) < 0)
- goto nla_put_failure;
- return nla_nest_end(skb, nest);
-
-nla_put_failure:
- nla_nest_cancel(skb, nest);
- return -1;
-}
-
-static int
-cbq_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
-{
- struct cbq_sched_data *q = qdisc_priv(sch);
-
- q->link.xstats.avgidle = q->link.avgidle;
- return gnet_stats_copy_app(d, &q->link.xstats, sizeof(q->link.xstats));
-}
-
-static int
-cbq_dump_class(struct Qdisc *sch, unsigned long arg,
- struct sk_buff *skb, struct tcmsg *tcm)
-{
- struct cbq_class *cl = (struct cbq_class *)arg;
- struct nlattr *nest;
-
- if (cl->tparent)
- tcm->tcm_parent = cl->tparent->common.classid;
- else
- tcm->tcm_parent = TC_H_ROOT;
- tcm->tcm_handle = cl->common.classid;
- tcm->tcm_info = cl->q->handle;
-
- nest = nla_nest_start_noflag(skb, TCA_OPTIONS);
- if (nest == NULL)
- goto nla_put_failure;
- if (cbq_dump_attr(skb, cl) < 0)
- goto nla_put_failure;
- return nla_nest_end(skb, nest);
-
-nla_put_failure:
- nla_nest_cancel(skb, nest);
- return -1;
-}
-
-static int
-cbq_dump_class_stats(struct Qdisc *sch, unsigned long arg,
- struct gnet_dump *d)
-{
- struct cbq_sched_data *q = qdisc_priv(sch);
- struct cbq_class *cl = (struct cbq_class *)arg;
- __u32 qlen;
-
- cl->xstats.avgidle = cl->avgidle;
- cl->xstats.undertime = 0;
- qdisc_qstats_qlen_backlog(cl->q, &qlen, &cl->qstats.backlog);
-
- if (cl->undertime != PSCHED_PASTPERFECT)
- cl->xstats.undertime = cl->undertime - q->now;
-
- if (gnet_stats_copy_basic(d, NULL, &cl->bstats, true) < 0 ||
- gnet_stats_copy_rate_est(d, &cl->rate_est) < 0 ||
- gnet_stats_copy_queue(d, NULL, &cl->qstats, qlen) < 0)
- return -1;
-
- return gnet_stats_copy_app(d, &cl->xstats, sizeof(cl->xstats));
-}
-
-static int cbq_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
- struct Qdisc **old, struct netlink_ext_ack *extack)
-{
- struct cbq_class *cl = (struct cbq_class *)arg;
-
- if (new == NULL) {
- new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
- cl->common.classid, extack);
- if (new == NULL)
- return -ENOBUFS;
- }
-
- *old = qdisc_replace(sch, new, &cl->q);
- return 0;
-}
-
-static struct Qdisc *cbq_leaf(struct Qdisc *sch, unsigned long arg)
-{
- struct cbq_class *cl = (struct cbq_class *)arg;
-
- return cl->q;
-}
-
-static void cbq_qlen_notify(struct Qdisc *sch, unsigned long arg)
-{
- struct cbq_class *cl = (struct cbq_class *)arg;
-
- cbq_deactivate_class(cl);
-}
-
-static unsigned long cbq_find(struct Qdisc *sch, u32 classid)
-{
- struct cbq_sched_data *q = qdisc_priv(sch);
-
- return (unsigned long)cbq_class_lookup(q, classid);
-}
-
-static void cbq_destroy_class(struct Qdisc *sch, struct cbq_class *cl)
-{
- struct cbq_sched_data *q = qdisc_priv(sch);
-
- WARN_ON(cl->filters);
-
- tcf_block_put(cl->block);
- qdisc_put(cl->q);
- qdisc_put_rtab(cl->R_tab);
- gen_kill_estimator(&cl->rate_est);
- if (cl != &q->link)
- kfree(cl);
-}
-
-static void cbq_destroy(struct Qdisc *sch)
-{
- struct cbq_sched_data *q = qdisc_priv(sch);
- struct hlist_node *next;
- struct cbq_class *cl;
- unsigned int h;
-
-#ifdef CONFIG_NET_CLS_ACT
- q->rx_class = NULL;
-#endif
- /*
- * Filters must be destroyed first because we don't destroy the
- * classes from root to leafs which means that filters can still
- * be bound to classes which have been destroyed already. --TGR '04
- */
- for (h = 0; h < q->clhash.hashsize; h++) {
- hlist_for_each_entry(cl, &q->clhash.hash[h], common.hnode) {
- tcf_block_put(cl->block);
- cl->block = NULL;
- }
- }
- for (h = 0; h < q->clhash.hashsize; h++) {
- hlist_for_each_entry_safe(cl, next, &q->clhash.hash[h],
- common.hnode)
- cbq_destroy_class(sch, cl);
- }
- qdisc_class_hash_destroy(&q->clhash);
-}
-
-static int
-cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **tca,
- unsigned long *arg, struct netlink_ext_ack *extack)
-{
- int err;
- struct cbq_sched_data *q = qdisc_priv(sch);
- struct cbq_class *cl = (struct cbq_class *)*arg;
- struct nlattr *opt = tca[TCA_OPTIONS];
- struct nlattr *tb[TCA_CBQ_MAX + 1];
- struct cbq_class *parent;
- struct qdisc_rate_table *rtab = NULL;
-
- err = cbq_opt_parse(tb, opt, extack);
- if (err < 0)
- return err;
-
- if (tb[TCA_CBQ_OVL_STRATEGY] || tb[TCA_CBQ_POLICE]) {
- NL_SET_ERR_MSG(extack, "Neither overlimit strategy nor policing attributes can be used for changing class params");
- return -EOPNOTSUPP;
- }
-
- if (cl) {
- /* Check parent */
- if (parentid) {
- if (cl->tparent &&
- cl->tparent->common.classid != parentid) {
- NL_SET_ERR_MSG(extack, "Invalid parent id");
- return -EINVAL;
- }
- if (!cl->tparent && parentid != TC_H_ROOT) {
- NL_SET_ERR_MSG(extack, "Parent must be root");
- return -EINVAL;
- }
- }
-
- if (tb[TCA_CBQ_RATE]) {
- rtab = qdisc_get_rtab(nla_data(tb[TCA_CBQ_RATE]),
- tb[TCA_CBQ_RTAB], extack);
- if (rtab == NULL)
- return -EINVAL;
- }
-
- if (tca[TCA_RATE]) {
- err = gen_replace_estimator(&cl->bstats, NULL,
- &cl->rate_est,
- NULL,
- true,
- tca[TCA_RATE]);
- if (err) {
- NL_SET_ERR_MSG(extack, "Failed to replace specified rate estimator");
- qdisc_put_rtab(rtab);
- return err;
- }
- }
-
- /* Change class parameters */
- sch_tree_lock(sch);
-
- if (cl->next_alive != NULL)
- cbq_deactivate_class(cl);
-
- if (rtab) {
- qdisc_put_rtab(cl->R_tab);
- cl->R_tab = rtab;
- }
-
- if (tb[TCA_CBQ_LSSOPT])
- cbq_set_lss(cl, nla_data(tb[TCA_CBQ_LSSOPT]));
-
- if (tb[TCA_CBQ_WRROPT]) {
- cbq_rmprio(q, cl);
- cbq_set_wrr(cl, nla_data(tb[TCA_CBQ_WRROPT]));
- }
-
- if (tb[TCA_CBQ_FOPT])
- cbq_set_fopt(cl, nla_data(tb[TCA_CBQ_FOPT]));
-
- if (cl->q->q.qlen)
- cbq_activate_class(cl);
-
- sch_tree_unlock(sch);
-
- return 0;
- }
-
- if (parentid == TC_H_ROOT)
- return -EINVAL;
-
- if (!tb[TCA_CBQ_WRROPT] || !tb[TCA_CBQ_RATE] || !tb[TCA_CBQ_LSSOPT]) {
- NL_SET_ERR_MSG(extack, "One of the following attributes MUST be specified: WRR, rate or link sharing");
- return -EINVAL;
- }
-
- rtab = qdisc_get_rtab(nla_data(tb[TCA_CBQ_RATE]), tb[TCA_CBQ_RTAB],
- extack);
- if (rtab == NULL)
- return -EINVAL;
-
- if (classid) {
- err = -EINVAL;
- if (TC_H_MAJ(classid ^ sch->handle) ||
- cbq_class_lookup(q, classid)) {
- NL_SET_ERR_MSG(extack, "Specified class not found");
- goto failure;
- }
- } else {
- int i;
- classid = TC_H_MAKE(sch->handle, 0x8000);
-
- for (i = 0; i < 0x8000; i++) {
- if (++q->hgenerator >= 0x8000)
- q->hgenerator = 1;
- if (cbq_class_lookup(q, classid|q->hgenerator) == NULL)
- break;
- }
- err = -ENOSR;
- if (i >= 0x8000) {
- NL_SET_ERR_MSG(extack, "Unable to generate classid");
- goto failure;
- }
- classid = classid|q->hgenerator;
- }
-
- parent = &q->link;
- if (parentid) {
- parent = cbq_class_lookup(q, parentid);
- err = -EINVAL;
- if (!parent) {
- NL_SET_ERR_MSG(extack, "Failed to find parentid");
- goto failure;
- }
- }
-
- err = -ENOBUFS;
- cl = kzalloc(sizeof(*cl), GFP_KERNEL);
- if (cl == NULL)
- goto failure;
-
- gnet_stats_basic_sync_init(&cl->bstats);
- err = tcf_block_get(&cl->block, &cl->filter_list, sch, extack);
- if (err) {
- kfree(cl);
- goto failure;
- }
-
- if (tca[TCA_RATE]) {
- err = gen_new_estimator(&cl->bstats, NULL, &cl->rate_est,
- NULL, true, tca[TCA_RATE]);
- if (err) {
- NL_SET_ERR_MSG(extack, "Couldn't create new estimator");
- tcf_block_put(cl->block);
- kfree(cl);
- goto failure;
- }
- }
-
- cl->R_tab = rtab;
- rtab = NULL;
- cl->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid,
- NULL);
- if (!cl->q)
- cl->q = &noop_qdisc;
- else
- qdisc_hash_add(cl->q, true);
-
- cl->common.classid = classid;
- cl->tparent = parent;
- cl->qdisc = sch;
- cl->allot = parent->allot;
- cl->quantum = cl->allot;
- cl->weight = cl->R_tab->rate.rate;
-
- sch_tree_lock(sch);
- cbq_link_class(cl);
- cl->borrow = cl->tparent;
- if (cl->tparent != &q->link)
- cl->share = cl->tparent;
- cbq_adjust_levels(parent);
- cl->minidle = -0x7FFFFFFF;
- cbq_set_lss(cl, nla_data(tb[TCA_CBQ_LSSOPT]));
- cbq_set_wrr(cl, nla_data(tb[TCA_CBQ_WRROPT]));
- if (cl->ewma_log == 0)
- cl->ewma_log = q->link.ewma_log;
- if (cl->maxidle == 0)
- cl->maxidle = q->link.maxidle;
- if (cl->avpkt == 0)
- cl->avpkt = q->link.avpkt;
- if (tb[TCA_CBQ_FOPT])
- cbq_set_fopt(cl, nla_data(tb[TCA_CBQ_FOPT]));
- sch_tree_unlock(sch);
-
- qdisc_class_hash_grow(sch, &q->clhash);
-
- *arg = (unsigned long)cl;
- return 0;
-
-failure:
- qdisc_put_rtab(rtab);
- return err;
-}
-
-static int cbq_delete(struct Qdisc *sch, unsigned long arg,
- struct netlink_ext_ack *extack)
-{
- struct cbq_sched_data *q = qdisc_priv(sch);
- struct cbq_class *cl = (struct cbq_class *)arg;
-
- if (cl->filters || cl->children || cl == &q->link)
- return -EBUSY;
-
- sch_tree_lock(sch);
-
- qdisc_purge_queue(cl->q);
-
- if (cl->next_alive)
- cbq_deactivate_class(cl);
-
- if (q->tx_borrowed == cl)
- q->tx_borrowed = q->tx_class;
- if (q->tx_class == cl) {
- q->tx_class = NULL;
- q->tx_borrowed = NULL;
- }
-#ifdef CONFIG_NET_CLS_ACT
- if (q->rx_class == cl)
- q->rx_class = NULL;
-#endif
-
- cbq_unlink_class(cl);
- cbq_adjust_levels(cl->tparent);
- cl->defmap = 0;
- cbq_sync_defmap(cl);
-
- cbq_rmprio(q, cl);
- sch_tree_unlock(sch);
-
- cbq_destroy_class(sch, cl);
- return 0;
-}
-
-static struct tcf_block *cbq_tcf_block(struct Qdisc *sch, unsigned long arg,
- struct netlink_ext_ack *extack)
-{
- struct cbq_sched_data *q = qdisc_priv(sch);
- struct cbq_class *cl = (struct cbq_class *)arg;
-
- if (cl == NULL)
- cl = &q->link;
-
- return cl->block;
-}
-
-static unsigned long cbq_bind_filter(struct Qdisc *sch, unsigned long parent,
- u32 classid)
-{
- struct cbq_sched_data *q = qdisc_priv(sch);
- struct cbq_class *p = (struct cbq_class *)parent;
- struct cbq_class *cl = cbq_class_lookup(q, classid);
-
- if (cl) {
- if (p && p->level <= cl->level)
- return 0;
- cl->filters++;
- return (unsigned long)cl;
- }
- return 0;
-}
-
-static void cbq_unbind_filter(struct Qdisc *sch, unsigned long arg)
-{
- struct cbq_class *cl = (struct cbq_class *)arg;
-
- cl->filters--;
-}
-
-static void cbq_walk(struct Qdisc *sch, struct qdisc_walker *arg)
-{
- struct cbq_sched_data *q = qdisc_priv(sch);
- struct cbq_class *cl;
- unsigned int h;
-
- if (arg->stop)
- return;
-
- for (h = 0; h < q->clhash.hashsize; h++) {
- hlist_for_each_entry(cl, &q->clhash.hash[h], common.hnode) {
- if (!tc_qdisc_stats_dump(sch, (unsigned long)cl, arg))
- return;
- }
- }
-}
-
-static const struct Qdisc_class_ops cbq_class_ops = {
- .graft = cbq_graft,
- .leaf = cbq_leaf,
- .qlen_notify = cbq_qlen_notify,
- .find = cbq_find,
- .change = cbq_change_class,
- .delete = cbq_delete,
- .walk = cbq_walk,
- .tcf_block = cbq_tcf_block,
- .bind_tcf = cbq_bind_filter,
- .unbind_tcf = cbq_unbind_filter,
- .dump = cbq_dump_class,
- .dump_stats = cbq_dump_class_stats,
-};
-
-static struct Qdisc_ops cbq_qdisc_ops __read_mostly = {
- .next = NULL,
- .cl_ops = &cbq_class_ops,
- .id = "cbq",
- .priv_size = sizeof(struct cbq_sched_data),
- .enqueue = cbq_enqueue,
- .dequeue = cbq_dequeue,
- .peek = qdisc_peek_dequeued,
- .init = cbq_init,
- .reset = cbq_reset,
- .destroy = cbq_destroy,
- .change = NULL,
- .dump = cbq_dump,
- .dump_stats = cbq_dump_stats,
- .owner = THIS_MODULE,
-};
-
-static int __init cbq_module_init(void)
-{
- return register_qdisc(&cbq_qdisc_ops);
-}
-static void __exit cbq_module_exit(void)
-{
- unregister_qdisc(&cbq_qdisc_ops);
-}
-module_init(cbq_module_init)
-module_exit(cbq_module_exit)
-MODULE_LICENSE("GPL");
--- a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/cbq.json
+++ /dev/null
@@ -1,184 +0,0 @@
-[
- {
- "id": "3460",
- "name": "Create CBQ with default setting",
- "category": [
- "qdisc",
- "cbq"
- ],
- "plugins": {
- "requires": "nsPlugin"
- },
- "setup": [
- "$IP link add dev $DUMMY type dummy || /bin/true"
- ],
- "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root cbq bandwidth 10000 avpkt 9000",
- "expExitCode": "0",
- "verifyCmd": "$TC qdisc show dev $DUMMY",
- "matchPattern": "qdisc cbq 1: root refcnt [0-9]+ rate 10Kbit \\(bounded,isolated\\) prio no-transmit",
- "matchCount": "1",
- "teardown": [
- "$TC qdisc del dev $DUMMY handle 1: root",
- "$IP link del dev $DUMMY type dummy"
- ]
- },
- {
- "id": "0592",
- "name": "Create CBQ with mpu",
- "category": [
- "qdisc",
- "cbq"
- ],
- "plugins": {
- "requires": "nsPlugin"
- },
- "setup": [
- "$IP link add dev $DUMMY type dummy || /bin/true"
- ],
- "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root cbq bandwidth 10000 avpkt 9000 mpu 1000",
- "expExitCode": "0",
- "verifyCmd": "$TC qdisc show dev $DUMMY",
- "matchPattern": "qdisc cbq 1: root refcnt [0-9]+ rate 10Kbit \\(bounded,isolated\\) prio no-transmit",
- "matchCount": "1",
- "teardown": [
- "$TC qdisc del dev $DUMMY handle 1: root",
- "$IP link del dev $DUMMY type dummy"
- ]
- },
- {
- "id": "4684",
- "name": "Create CBQ with valid cell num",
- "category": [
- "qdisc",
- "cbq"
- ],
- "plugins": {
- "requires": "nsPlugin"
- },
- "setup": [
- "$IP link add dev $DUMMY type dummy || /bin/true"
- ],
- "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root cbq bandwidth 10000 avpkt 9000 cell 128",
- "expExitCode": "0",
- "verifyCmd": "$TC qdisc show dev $DUMMY",
- "matchPattern": "qdisc cbq 1: root refcnt [0-9]+ rate 10Kbit \\(bounded,isolated\\) prio no-transmit",
- "matchCount": "1",
- "teardown": [
- "$TC qdisc del dev $DUMMY handle 1: root",
- "$IP link del dev $DUMMY type dummy"
- ]
- },
- {
- "id": "4345",
- "name": "Create CBQ with invalid cell num",
- "category": [
- "qdisc",
- "cbq"
- ],
- "plugins": {
- "requires": "nsPlugin"
- },
- "setup": [
- "$IP link add dev $DUMMY type dummy || /bin/true"
- ],
- "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root cbq bandwidth 10000 avpkt 9000 cell 100",
- "expExitCode": "1",
- "verifyCmd": "$TC qdisc show dev $DUMMY",
- "matchPattern": "qdisc cbq 1: root refcnt [0-9]+ rate 10Kbit \\(bounded,isolated\\) prio no-transmit",
- "matchCount": "0",
- "teardown": [
- "$IP link del dev $DUMMY type dummy"
- ]
- },
- {
- "id": "4525",
- "name": "Create CBQ with valid ewma",
- "category": [
- "qdisc",
- "cbq"
- ],
- "plugins": {
- "requires": "nsPlugin"
- },
- "setup": [
- "$IP link add dev $DUMMY type dummy || /bin/true"
- ],
- "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root cbq bandwidth 10000 avpkt 9000 ewma 16",
- "expExitCode": "0",
- "verifyCmd": "$TC qdisc show dev $DUMMY",
- "matchPattern": "qdisc cbq 1: root refcnt [0-9]+ rate 10Kbit \\(bounded,isolated\\) prio no-transmit",
- "matchCount": "1",
- "teardown": [
- "$TC qdisc del dev $DUMMY handle 1: root",
- "$IP link del dev $DUMMY type dummy"
- ]
- },
- {
- "id": "6784",
- "name": "Create CBQ with invalid ewma",
- "category": [
- "qdisc",
- "cbq"
- ],
- "plugins": {
- "requires": "nsPlugin"
- },
- "setup": [
- "$IP link add dev $DUMMY type dummy || /bin/true"
- ],
- "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root cbq bandwidth 10000 avpkt 9000 ewma 128",
- "expExitCode": "1",
- "verifyCmd": "$TC qdisc show dev $DUMMY",
- "matchPattern": "qdisc cbq 1: root refcnt [0-9]+ rate 10Kbit \\(bounded,isolated\\) prio no-transmit",
- "matchCount": "0",
- "teardown": [
- "$IP link del dev $DUMMY type dummy"
- ]
- },
- {
- "id": "5468",
- "name": "Delete CBQ with handle",
- "category": [
- "qdisc",
- "cbq"
- ],
- "plugins": {
- "requires": "nsPlugin"
- },
- "setup": [
- "$IP link add dev $DUMMY type dummy || /bin/true",
- "$TC qdisc add dev $DUMMY handle 1: root cbq bandwidth 10000 avpkt 9000"
- ],
- "cmdUnderTest": "$TC qdisc del dev $DUMMY handle 1: root",
- "expExitCode": "0",
- "verifyCmd": "$TC qdisc show dev $DUMMY",
- "matchPattern": "qdisc cbq 1: root refcnt [0-9]+ rate 10Kbit \\(bounded,isolated\\) prio no-transmit",
- "matchCount": "0",
- "teardown": [
- "$IP link del dev $DUMMY type dummy"
- ]
- },
- {
- "id": "492a",
- "name": "Show CBQ class",
- "category": [
- "qdisc",
- "cbq"
- ],
- "plugins": {
- "requires": "nsPlugin"
- },
- "setup": [
- "$IP link add dev $DUMMY type dummy || /bin/true"
- ],
- "cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root cbq bandwidth 10000 avpkt 9000",
- "expExitCode": "0",
- "verifyCmd": "$TC class show dev $DUMMY",
- "matchPattern": "class cbq 1: root rate 10Kbit \\(bounded,isolated\\) prio no-transmit",
- "matchCount": "1",
- "teardown": [
- "$TC qdisc del dev $DUMMY handle 1: root",
- "$IP link del dev $DUMMY type dummy"
- ]
- }
-]
next prev parent reply other threads:[~2024-02-27 14:12 UTC|newest]
Thread overview: 208+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-27 13:24 [PATCH 6.1 000/195] 6.1.80-rc1 review Greg Kroah-Hartman
2024-02-27 13:24 ` Greg Kroah-Hartman [this message]
2024-02-27 13:24 ` [PATCH 6.1 002/195] net/sched: Retire ATM qdisc Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 003/195] net/sched: Retire dsmark qdisc Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 004/195] sched/rt: Disallow writing invalid values to sched_rt_period_us Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 005/195] sched/rt: sysctl_sched_rr_timeslice show default timeslice after reset Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 006/195] PCI: dwc: Fix a 64bit bug in dw_pcie_ep_raise_msix_irq() Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 007/195] riscv/efistub: Ensure GP-relative addressing is not used Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 008/195] dmaengine: apple-admac: Keep upper bits of REG_BUS_WIDTH Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 009/195] scsi: target: core: Add TMF to tmr_list handling Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 010/195] cifs: open_cached_dir should not rely on primary channel Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 011/195] dmaengine: shdma: increase size of dev_id Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 012/195] dmaengine: fsl-qdma: increase size of irq_name Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 013/195] wifi: cfg80211: fix missing interfaces when dumping Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 014/195] wifi: mac80211: fix race condition on enabling fast-xmit Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 015/195] fbdev: savage: Error out if pixclock equals zero Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 016/195] fbdev: sis: " Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 017/195] spi: hisi-sfc-v3xx: Return IRQ_NONE if no interrupts were detected Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 018/195] block: Fix WARNING in _copy_from_iter Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 019/195] smb: Work around Clang __bdos() type confusion Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 020/195] cifs: translate network errors on send to -ECONNABORTED Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 021/195] ahci: asm1166: correct count of reported ports Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 022/195] aoe: avoid potential deadlock at set_capacity Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 023/195] ahci: add 43-bit DMA address quirk for ASMedia ASM1061 controllers Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 024/195] MIPS: reserve exception vector space ONLY ONCE Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 025/195] platform/x86: touchscreen_dmi: Add info for the TECLAST X16 Plus tablet Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 026/195] ext4: avoid dividing by 0 in mb_update_avg_fragment_size() when block bitmap corrupt Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 027/195] ext4: avoid allocating blocks from corrupted group in ext4_mb_try_best_found() Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 028/195] ext4: avoid allocating blocks from corrupted group in ext4_mb_find_by_goal() Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 029/195] Input: goodix - accept ACPI resources with gpio_count == 3 && gpio_int_idx == 0 Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 030/195] dmaengine: ti: edma: Add some null pointer checks to the edma_probe Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 031/195] regulator: pwm-regulator: Add validity checks in continuous .get_voltage Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 032/195] nvmet-tcp: fix nvme tcp ida memory leak Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 033/195] usb: ucsi_acpi: Quirk to ack a connector change ack cmd Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 034/195] ALSA: usb-audio: Check presence of valid altsetting control Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 035/195] ASoC: sunxi: sun4i-spdif: Add support for Allwinner H616 Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 036/195] spi: sh-msiof: avoid integer overflow in constants Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 037/195] Input: xpad - add Lenovo Legion Go controllers Greg Kroah-Hartman
2024-02-27 13:24 ` [PATCH 6.1 038/195] misc: open-dice: Fix spurious lockdep warning Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 039/195] netfilter: conntrack: check SCTP_CID_SHUTDOWN_ACK for vtag setting in sctp_new Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 040/195] drm/amd/display: increased min_dcfclk_mhz and min_fclk_mhz Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 041/195] ASoC: wm_adsp: Dont overwrite fwf_name with the default Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 042/195] ALSA: usb-audio: Ignore clock selector errors for single connection Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 043/195] nvme-fc: do not wait in vain when unloading module Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 044/195] nvmet-fcloop: swap the list_add_tail arguments Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 045/195] nvmet-fc: release reference on target port Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 046/195] nvmet-fc: defer cleanup using RCU properly Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 047/195] nvmet-fc: hold reference on hostport match Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 048/195] nvmet-fc: abort command when there is no binding Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 049/195] nvmet-fc: avoid deadlock on delete association path Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 050/195] nvmet-fc: take ref count on tgtport before delete assoc Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 051/195] smb: client: increase number of PDUs allowed in a compound request Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 052/195] ext4: correct the hole length returned by ext4_map_blocks() Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 053/195] Input: i8042 - add Fujitsu Lifebook U728 to i8042 quirk table Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 054/195] fs/ntfs3: Modified fix directory element type detection Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 055/195] fs/ntfs3: Improve ntfs_dir_count Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 056/195] fs/ntfs3: Correct hard links updating when dealing with DOS names Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 057/195] fs/ntfs3: Print warning while fixing hard links count Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 058/195] fs/ntfs3: Fix detected field-spanning write (size 8) of single field "le->name" Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 059/195] fs/ntfs3: Add NULL ptr dereference checking at the end of attr_allocate_frame() Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 060/195] fs/ntfs3: Disable ATTR_LIST_ENTRY size check Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 061/195] fs/ntfs3: use non-movable memory for ntfs3 MFT buffer cache Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 062/195] fs/ntfs3: Prevent generic message "attempt to access beyond end of device" Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 063/195] fs/ntfs3: Correct function is_rst_area_valid Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 064/195] fs/ntfs3: Update inode->i_size after success write into compressed file Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 065/195] fs/ntfs3: Fix oob in ntfs_listxattr Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 066/195] wifi: mac80211: set station RX-NSS on reconfig Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 067/195] wifi: mac80211: adding missing drv_mgd_complete_tx() call Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 068/195] efi: runtime: Fix potential overflow of soft-reserved region size Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 069/195] efi: Dont add memblocks for soft-reserved memory Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 070/195] hwmon: (coretemp) Enlarge per package core count limit Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 071/195] scsi: lpfc: Use unsigned type for num_sge Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 072/195] scsi: ufs: core: Remove the ufshcd_release() in ufshcd_err_handling_prepare() Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 073/195] LoongArch: Select ARCH_ENABLE_THP_MIGRATION instead of redefining it Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 074/195] LoongArch: Select HAVE_ARCH_SECCOMP to use the common SECCOMP menu Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 075/195] firewire: core: send bus reset promptly on gap count error Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 076/195] drm/amdgpu: skip to program GFXDEC registers for suspend abort Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 077/195] drm/amdgpu: reset gpu for s3 suspend abort case Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 078/195] smb: client: set correct d_type for reparse points under DFS mounts Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 079/195] virtio-blk: Ensure no requests in virtqueues before deleting vqs Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 080/195] smb3: clarify mount warning Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 081/195] pmdomain: mediatek: fix race conditions with genpd Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 082/195] pmdomain: renesas: r8a77980-sysc: CR7 must be always on Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 083/195] IB/hfi1: Fix sdma.h tx->num_descs off-by-one error Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 084/195] LoongArch: Disable IRQ before init_fn() for nonboot CPUs Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 085/195] drm/ttm: Fix an invalid freeing on already freed page in error path Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 086/195] s390/cio: fix invalid -EBUSY on ccw_device_start Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 087/195] ata: libata-core: Do not try to set sleeping devices to standby Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 088/195] dm-crypt: recheck the integrity tag after a failure Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 089/195] Revert "parisc: Only list existing CPUs in cpu_possible_mask" Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 090/195] dm-integrity: recheck the integrity tag after a failure Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 091/195] dm-crypt: dont modify the data when using authenticated encryption Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 092/195] dm-verity: recheck the hash after a failure Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 093/195] cxl/pci: Fix disabling memory if DVSEC CXL Range does not match a CFMWS window Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 094/195] scsi: target: pscsi: Fix bio_put() for error case Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 095/195] scsi: core: Consult supported VPD page list prior to fetching page Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 096/195] mm/swap: fix race when skipping swapcache Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 097/195] mm/damon/lru_sort: fix quota status loss due to online tunings Greg Kroah-Hartman
2024-02-27 13:25 ` [PATCH 6.1 098/195] mm: memcontrol: clarify swapaccount=0 deprecation warning Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 099/195] platform/x86: intel-vbtn: Stop calling "VBDL" from notify_handler Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 100/195] platform/x86: touchscreen_dmi: Allow partial (prefix) matches for ACPI names Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 101/195] cachefiles: fix memory leak in cachefiles_add_cache() Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 102/195] md: Fix missing release of active_io for flush Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 103/195] KVM: arm64: vgic-its: Test for valid IRQ in MOVALL handler Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 104/195] KVM: arm64: vgic-its: Test for valid IRQ in its_sync_lpi_pending_table() Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 105/195] gtp: fix use-after-free and null-ptr-deref in gtp_genl_dump_pdp() Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 106/195] crypto: virtio/akcipher - Fix stack overflow on memcpy Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 107/195] irqchip/gic-v3-its: Do not assume vPE tables are preallocated Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 108/195] irqchip/sifive-plic: Enable interrupt if needed before EOI Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 109/195] PCI/MSI: Prevent MSI hardware interrupt number truncation Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 110/195] l2tp: pass correct message length to ip6_append_data Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 111/195] ARM: ep93xx: Add terminator to gpiod_lookup_table Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 112/195] x86/returnthunk: Allow different return thunks Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 113/195] Revert "x86/alternative: Make custom return thunk unconditional" Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 114/195] x86/alternative: Make custom return thunk unconditional Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 115/195] dm-integrity, dm-verity: reduce stack usage for recheck Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 116/195] erofs: fix refcount on the metabuf used for inode lookup Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 117/195] serial: amba-pl011: Fix DMA transmission in RS485 mode Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 118/195] usb: dwc3: gadget: Dont disconnect if not started Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 119/195] usb: cdnsp: blocked some cdns3 specific code Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 120/195] usb: cdnsp: fixed issue with incorrect detecting CDNSP family controllers Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 121/195] usb: cdns3: fixed memory use after free at cdns3_gadget_ep_disable() Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 122/195] usb: cdns3: fix memory double free when handle zero packet Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 123/195] usb: gadget: ncm: Avoid dropping datagrams of properly parsed NTBs Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 124/195] usb: roles: fix NULL pointer issue when put modules reference Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 125/195] usb: roles: dont get/set_role() when usb_role_switch is unregistered Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 126/195] mptcp: make userspace_pm_append_new_local_addr static Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 127/195] mptcp: add needs_id for userspace appending addr Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 128/195] mptcp: fix lockless access in subflow ULP diag Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 129/195] Revert "drm/amd/display: increased min_dcfclk_mhz and min_fclk_mhz" Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 130/195] IB/hfi1: Fix a memleak in init_credit_return Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 131/195] RDMA/bnxt_re: Return error for SRQ resize Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 132/195] RDMA/irdma: Fix KASAN issue with tasklet Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 133/195] RDMA/irdma: Validate max_send_wr and max_recv_wr Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 134/195] RDMA/irdma: Set the CQ read threshold for GEN 1 Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 135/195] RDMA/irdma: Add AE for too many RNRS Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 136/195] RDMA/srpt: Support specifying the srpt_service_guid parameter Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 137/195] iommufd/iova_bitmap: Bounds check mapped::pages access Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 138/195] iommufd/iova_bitmap: Switch iova_bitmap::bitmap to an u8 array Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 139/195] iommufd/iova_bitmap: Consider page offset for the pages to be pinned Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 140/195] RDMA/qedr: Fix qedr_create_user_qp error flow Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 141/195] arm64: dts: rockchip: set num-cs property for spi on px30 Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 142/195] RDMA/srpt: fix function pointer cast warnings Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 143/195] bpf, scripts: Correct GPL license name Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 144/195] scsi: smartpqi: Fix disable_managed_interrupts Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 145/195] scsi: jazz_esp: Only build if SCSI core is builtin Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 146/195] net: bridge: switchdev: Skip MDB replays of deferred events on offload Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 147/195] net: bridge: switchdev: Ensure deferred event delivery on unoffload Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 148/195] dccp/tcp: Unhash sk from ehash for tb2 alloc failure after check_estalblished() Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 149/195] net: ethernet: adi: requires PHYLIB support Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 150/195] nouveau: fix function cast warnings Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 151/195] x86/numa: Fix the address overlap check in numa_fill_memblks() Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 152/195] x86/numa: Fix the sort compare func used " Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 153/195] net: stmmac: Fix incorrect dereference in interrupt handlers Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 154/195] ipv4: properly combine dev_base_seq and ipv4.dev_addr_genid Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 155/195] ipv6: properly combine dev_base_seq and ipv6.dev_addr_genid Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 156/195] ata: ahci_ceva: fix error handling for Xilinx GT PHY support Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 157/195] bpf: Fix racing between bpf_timer_cancel_and_free and bpf_timer_cancel Greg Kroah-Hartman
2024-02-27 13:26 ` [PATCH 6.1 158/195] afs: Increase buffer size in afs_update_volume_status() Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 159/195] ipv6: sr: fix possible use-after-free and null-ptr-deref Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 160/195] net: dev: Convert sa_data to flexible array in struct sockaddr Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 161/195] arm64/sme: Restore SME registers on exit from suspend Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 162/195] platform/x86: thinkpad_acpi: Only update profile if successfully converted Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 163/195] octeontx2-af: Consider the action set by PF Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 164/195] s390: use the correct count for __iowrite64_copy() Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 165/195] bpf, sockmap: Fix NULL pointer dereference in sk_psock_verdict_data_ready() Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 166/195] tls: break out of main loop when PEEK gets a non-data record Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 167/195] tls: stop recv() if initial process_rx_list gave us non-DATA Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 168/195] tls: dont skip over different type records from the rx_list Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 169/195] netfilter: nf_tables: set dormant flag on hook register failure Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 170/195] netfilter: flowtable: simplify route logic Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 171/195] netfilter: nft_flow_offload: reset dst in route object after setting up flow Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 172/195] netfilter: nft_flow_offload: release dst in case direct xmit path is used Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 173/195] netfilter: nf_tables: rename function to destroy hook list Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 174/195] netfilter: nf_tables: register hooks last when adding new chain/flowtable Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 175/195] netfilter: nf_tables: use kzalloc for hook allocation Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 176/195] net: mctp: put sock on tag allocation failure Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 177/195] net: sparx5: Add spinlock for frame transmission from CPU Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 178/195] phonet: take correct lock to peek at the RX queue Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 179/195] phonet/pep: fix racy skb_queue_empty() use Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 180/195] Fix write to cloned skb in ipv6_hop_ioam() Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 181/195] net: phy: realtek: Fix rtl8211f_config_init() for RTL8211F(D)(I)-VD-CG PHY Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 182/195] drm/syncobj: call drm_syncobj_fence_add_wait when WAIT_AVAILABLE flag is set Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 183/195] drm/amd/display: Fix memory leak in dm_sw_fini() Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 184/195] i2c: imx: when being a target, mark the last read as processed Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 185/195] erofs: simplify compression configuration parser Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 186/195] erofs: fix inconsistent per-file compression format Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 187/195] mm/damon/reclaim: fix quota stauts loss due to online tunings Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 188/195] fs/aio: Restrict kiocb_set_cancel_fn() to I/O submitted via libaio Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 189/195] mm: zswap: fix missing folio cleanup in writeback race path Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 190/195] mptcp: userspace pm send RM_ADDR for ID 0 Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 191/195] mptcp: add needs_id for netlink appending addr Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 192/195] ata: ahci: add identifiers for ASM2116 series adapters Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 193/195] ahci: Extend ASM1061 43-bit DMA address quirk to other ASM106x parts Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 194/195] arp: Prevent overflow in arp_req_get() Greg Kroah-Hartman
2024-02-27 13:27 ` [PATCH 6.1 195/195] fs/ntfs3: Enhance the attribute size check Greg Kroah-Hartman
2024-02-27 17:46 ` [PATCH 6.1 000/195] 6.1.80-rc1 review SeongJae Park
2024-02-27 18:27 ` Pavel Machek
2024-02-27 19:02 ` Allen
2024-02-27 19:27 ` Florian Fainelli
2024-02-28 0:25 ` Kelsey Steele
2024-02-28 9:01 ` Naresh Kamboju
2024-02-28 13:39 ` Jon Hunter
2024-02-28 14:24 ` Yann Sionneau
2024-02-28 14:51 ` Conor Dooley
2024-02-28 16:41 ` Shuah Khan
2024-02-29 4:42 ` Ron Economos
2024-02-29 10:48 ` Shreeya Patel
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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240227131610.444902810@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=jhs@mojatatu.com \
--cc=jiri@nvidia.com \
--cc=pabeni@redhat.com \
--cc=patches@lists.linux.dev \
--cc=stable@vger.kernel.org \
/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