Skip to content

Commit

Permalink
Merge branch 'fixes-for-tc-taprio-software-mode'
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jakub Kicinski committed Sep 20, 2022
2 parents 76dd072 + 1461d21 commit da84724
Showing 1 changed file with 11 additions and 7 deletions.
18 changes: 11 additions & 7 deletions net/sched/sch_taprio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -1279,6 +1280,8 @@ static int taprio_enable_offload(struct net_device *dev,
goto done;
}

q->offloaded = true;

done:
taprio_offload_free(offload);

Expand All @@ -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,
Expand All @@ -1314,6 +1314,8 @@ static int taprio_disable_offload(struct net_device *dev,
goto out;
}

q->offloaded = false;

out:
taprio_offload_free(offload);

Expand Down Expand Up @@ -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)
{
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)
Expand Down

0 comments on commit da84724

Please sign in to comment.