Commit da847246 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

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: default avatarJakub Kicinski <kuba@kernel.org>
parents 76dd0728 1461d212
Loading
Loading
Loading
Loading
+11 −7
Original line number Diff line number Diff line
@@ -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 @@ 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)