diff options
author | Jakub Kicinski <kuba@kernel.org> | 2022-09-20 11:41:17 -0700 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2022-09-20 11:41:18 -0700 |
commit | da847246ab80610c5acca34df5893bee1d8cf7c2 (patch) | |
tree | c81c615a69b3b1b59df96ab81121f23b98b3ef4b | |
parent | 76dd07281338da6951fdab3432ced843fa87839c (diff) | |
parent | 1461d212ab277d8bba1a753d33e9afe03d81f9d4 (diff) | |
download | linux-da847246ab80610c5acca34df5893bee1d8cf7c2.tar.gz |
Merge branch 'fixes-for-tc-taprio-software-mode'
Vladimir Oltean says:
====================
Fixes for tc-taprio software mode
While working on some new features for tc-taprio, I found some strange
behavior which looked like bugs. I was able to eventually trigger a NULL
pointer dereference. This patch set fixes 2 issues I saw. Detailed
explanation in patches.
====================
Link: https://lore.kernel.org/r/20220915100802.2308279-1-vladimir.oltean@nxp.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r-- | net/sched/sch_taprio.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c index 0b941dd63d268..86675a79da1e4 100644 --- a/net/sched/sch_taprio.c +++ b/net/sched/sch_taprio.c @@ -67,6 +67,7 @@ struct taprio_sched { u32 flags; enum tk_offsets tk_offset; int clockid; + bool offloaded; atomic64_t picos_per_byte; /* Using picoseconds because for 10Gbps+ * speeds it's sub-nanoseconds per byte */ @@ -1279,6 +1280,8 @@ static int taprio_enable_offload(struct net_device *dev, goto done; } + q->offloaded = true; + done: taprio_offload_free(offload); @@ -1293,12 +1296,9 @@ static int taprio_disable_offload(struct net_device *dev, struct tc_taprio_qopt_offload *offload; int err; - if (!FULL_OFFLOAD_IS_ENABLED(q->flags)) + if (!q->offloaded) return 0; - if (!ops->ndo_setup_tc) - return -EOPNOTSUPP; - offload = taprio_offload_alloc(0); if (!offload) { NL_SET_ERR_MSG(extack, @@ -1314,6 +1314,8 @@ static int taprio_disable_offload(struct net_device *dev, goto out; } + q->offloaded = false; + out: taprio_offload_free(offload); @@ -1949,12 +1951,14 @@ start_error: static struct Qdisc *taprio_leaf(struct Qdisc *sch, unsigned long cl) { - struct netdev_queue *dev_queue = taprio_queue_get(sch, cl); + struct taprio_sched *q = qdisc_priv(sch); + struct net_device *dev = qdisc_dev(sch); + unsigned int ntx = cl - 1; - if (!dev_queue) + if (ntx >= dev->num_tx_queues) return NULL; - return dev_queue->qdisc_sleeping; + return q->qdiscs[ntx]; } static unsigned long taprio_find(struct Qdisc *sch, u32 classid) |