Commit da847246 authored by Jakub Kicinski's avatar Jakub Kicinski

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.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 76dd0728 1461d212
...@@ -67,6 +67,7 @@ struct taprio_sched { ...@@ -67,6 +67,7 @@ struct taprio_sched {
u32 flags; u32 flags;
enum tk_offsets tk_offset; enum tk_offsets tk_offset;
int clockid; int clockid;
bool offloaded;
atomic64_t picos_per_byte; /* Using picoseconds because for 10Gbps+ atomic64_t picos_per_byte; /* Using picoseconds because for 10Gbps+
* speeds it's sub-nanoseconds per byte * speeds it's sub-nanoseconds per byte
*/ */
...@@ -1279,6 +1280,8 @@ static int taprio_enable_offload(struct net_device *dev, ...@@ -1279,6 +1280,8 @@ static int taprio_enable_offload(struct net_device *dev,
goto done; goto done;
} }
q->offloaded = true;
done: done:
taprio_offload_free(offload); taprio_offload_free(offload);
...@@ -1293,12 +1296,9 @@ static int taprio_disable_offload(struct net_device *dev, ...@@ -1293,12 +1296,9 @@ static int taprio_disable_offload(struct net_device *dev,
struct tc_taprio_qopt_offload *offload; struct tc_taprio_qopt_offload *offload;
int err; int err;
if (!FULL_OFFLOAD_IS_ENABLED(q->flags)) if (!q->offloaded)
return 0; return 0;
if (!ops->ndo_setup_tc)
return -EOPNOTSUPP;
offload = taprio_offload_alloc(0); offload = taprio_offload_alloc(0);
if (!offload) { if (!offload) {
NL_SET_ERR_MSG(extack, NL_SET_ERR_MSG(extack,
...@@ -1314,6 +1314,8 @@ static int taprio_disable_offload(struct net_device *dev, ...@@ -1314,6 +1314,8 @@ static int taprio_disable_offload(struct net_device *dev,
goto out; goto out;
} }
q->offloaded = false;
out: out:
taprio_offload_free(offload); taprio_offload_free(offload);
...@@ -1949,12 +1951,14 @@ static int taprio_dump(struct Qdisc *sch, struct sk_buff *skb) ...@@ -1949,12 +1951,14 @@ static int taprio_dump(struct Qdisc *sch, struct sk_buff *skb)
static struct Qdisc *taprio_leaf(struct Qdisc *sch, unsigned long cl) 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 NULL;
return dev_queue->qdisc_sleeping; return q->qdiscs[ntx];
} }
static unsigned long taprio_find(struct Qdisc *sch, u32 classid) static unsigned long taprio_find(struct Qdisc *sch, u32 classid)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment