net/sched/sch_taprio.c

Source file repositories/reference/linux-study-clean/net/sched/sch_taprio.c

File Facts

System
Linux kernel
Corpus path
net/sched/sch_taprio.c
Extension
.c
Size
68743 bytes
Lines
2583
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

const struct net_device_ops *ops = dev->netdev_ops;
	struct tc_taprio_qopt_offload *offload;
	struct tc_taprio_caps caps;
	int tc, err = 0;

	if (!ops->ndo_setup_tc) {
		NL_SET_ERR_MSG(extack,
			       "Device does not support taprio offload");
		return -EOPNOTSUPP;
	}

	qdisc_offload_query_caps(dev, TC_SETUP_QDISC_TAPRIO,
				 &caps, sizeof(caps));

	if (!caps.supports_queue_max_sdu) {
		for (tc = 0; tc < TC_MAX_QUEUE; tc++) {
			if (q->max_sdu[tc]) {
				NL_SET_ERR_MSG_MOD(extack,
						   "Device does not handle queueMaxSDU");
				return -EOPNOTSUPP;
			}
		}
	}

	offload = taprio_offload_alloc(sched->num_entries);
	if (!offload) {
		NL_SET_ERR_MSG(extack,
			       "Not enough memory for enabling offload mode");
		return -ENOMEM;
	}
	offload->cmd = TAPRIO_CMD_REPLACE;
	offload->extack = extack;
	mqprio_qopt_reconstruct(dev, &offload->mqprio.qopt);
	offload->mqprio.extack = extack;
	taprio_sched_to_offload(dev, sched, offload, &caps);
	mqprio_fp_to_offload(q->fp, &offload->mqprio);

	for (tc = 0; tc < TC_MAX_QUEUE; tc++)
		offload->max_sdu[tc] = q->max_sdu[tc];

	err = ops->ndo_setup_tc(dev, TC_SETUP_QDISC_TAPRIO, offload);
	if (err < 0) {
		NL_SET_ERR_MSG_WEAK(extack,
				    "Device failed to setup taprio offload");
		goto done;
	}

	q->offloaded = true;

done:
	/* The offload structure may linger around via a reference taken by the
	 * device driver, so clear up the netlink extack pointer so that the
	 * driver isn't tempted to dereference data which stopped being valid
	 */
	offload->extack = NULL;
	offload->mqprio.extack = NULL;
	taprio_offload_free(offload);

	return err;
}

static int taprio_disable_offload(struct net_device *dev,
				  struct taprio_sched *q,
				  struct netlink_ext_ack *extack)
{
	const struct net_device_ops *ops = dev->netdev_ops;
	struct tc_taprio_qopt_offload *offload;
	int err;

	if (!q->offloaded)
		return 0;

	offload = taprio_offload_alloc(0);
	if (!offload) {
		NL_SET_ERR_MSG(extack,
			       "Not enough memory to disable offload mode");
		return -ENOMEM;
	}
	offload->cmd = TAPRIO_CMD_DESTROY;

	err = ops->ndo_setup_tc(dev, TC_SETUP_QDISC_TAPRIO, offload);
	if (err < 0) {
		NL_SET_ERR_MSG(extack,
			       "Device failed to disable offload");
		goto out;
	}

	q->offloaded = false;

out:

Annotation

Implementation Notes