Skip to content

Commit

Permalink
Merge branch 'taprio-auto-qmaxsdu-new-tx'
Browse files Browse the repository at this point in the history
Vladimir Oltean says:

====================
taprio automatic queueMaxSDU and new TXQ selection procedure

This patch set addresses 2 design limitations in the taprio software scheduler:

1. Software scheduling fundamentally prioritizes traffic incorrectly,
   in a way which was inspired from Intel igb/igc drivers and does not
   follow the inputs user space gives (traffic classes and TC to TXQ
   mapping). Patch 05/15 handles this, 01/15 - 04/15 are preparations
   for this work.

2. Software scheduling assumes that the gate for a traffic class closes
   as soon as the next interval begins. But this isn't true.
   If consecutive schedule entries have that traffic class gate open,
   there is no "gate close" event and taprio should keep dequeuing from
   that TC without interruptions. Patches 06/15 - 15/15 handle this.
   Patch 10/15 is a generic Qdisc change required for this to work.

Future development directions which depend on this patch set are:

- Propagating the automatic queueMaxSDU calculation down to offloading
  device drivers, instead of letting them calculate this, as
  vsc9959_tas_guard_bands_update() does today.

- A software data path for tc-taprio with preemptible traffic and
  Hold/Release events.

v1 at:
https://patchwork.kernel.org/project/netdevbpf/cover/[email protected]/
====================

Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
davem330 committed Feb 8, 2023
2 parents 6da13bf + 39b02d6 commit e6ebe6c
Show file tree
Hide file tree
Showing 5 changed files with 500 additions and 197 deletions.
18 changes: 18 additions & 0 deletions drivers/net/ethernet/intel/igb/igb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2810,6 +2810,22 @@ static int igb_offload_txtime(struct igb_adapter *adapter,
return 0;
}

static int igb_tc_query_caps(struct igb_adapter *adapter,
struct tc_query_caps_base *base)
{
switch (base->type) {
case TC_SETUP_QDISC_TAPRIO: {
struct tc_taprio_caps *caps = base->caps;

caps->broken_mqprio = true;

return 0;
}
default:
return -EOPNOTSUPP;
}
}

static LIST_HEAD(igb_block_cb_list);

static int igb_setup_tc(struct net_device *dev, enum tc_setup_type type,
Expand All @@ -2818,6 +2834,8 @@ static int igb_setup_tc(struct net_device *dev, enum tc_setup_type type,
struct igb_adapter *adapter = netdev_priv(dev);

switch (type) {
case TC_QUERY_CAPS:
return igb_tc_query_caps(adapter, type_data);
case TC_SETUP_QDISC_CBS:
return igb_offload_cbs(adapter, type_data);
case TC_SETUP_BLOCK:
Expand Down
6 changes: 3 additions & 3 deletions drivers/net/ethernet/intel/igc/igc_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -6214,10 +6214,10 @@ static int igc_tc_query_caps(struct igc_adapter *adapter,
case TC_SETUP_QDISC_TAPRIO: {
struct tc_taprio_caps *caps = base->caps;

if (hw->mac.type != igc_i225)
return -EOPNOTSUPP;
caps->broken_mqprio = true;

caps->gate_mask_per_txq = true;
if (hw->mac.type == igc_i225)
caps->gate_mask_per_txq = true;

return 0;
}
Expand Down
5 changes: 5 additions & 0 deletions include/net/pkt_sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,11 @@ struct tc_mqprio_qopt_offload {
struct tc_taprio_caps {
bool supports_queue_max_sdu:1;
bool gate_mask_per_txq:1;
/* Device expects lower TXQ numbers to have higher priority over higher
* TXQs, regardless of their TC mapping. DO NOT USE FOR NEW DRIVERS,
* INSTEAD ENFORCE A PROPER TC:TXQ MAPPING COMING FROM USER SPACE.
*/
bool broken_mqprio:1;
};

struct tc_taprio_sched_entry {
Expand Down
29 changes: 11 additions & 18 deletions net/sched/sch_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -1282,12 +1282,6 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
if (err)
goto err_out3;

if (ops->init) {
err = ops->init(sch, tca[TCA_OPTIONS], extack);
if (err != 0)
goto err_out5;
}

if (tca[TCA_STAB]) {
stab = qdisc_get_stab(tca[TCA_STAB], extack);
if (IS_ERR(stab)) {
Expand All @@ -1296,11 +1290,18 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
}
rcu_assign_pointer(sch->stab, stab);
}

if (ops->init) {
err = ops->init(sch, tca[TCA_OPTIONS], extack);
if (err != 0)
goto err_out5;
}

if (tca[TCA_RATE]) {
err = -EOPNOTSUPP;
if (sch->flags & TCQ_F_MQROOT) {
NL_SET_ERR_MSG(extack, "Cannot attach rate estimator to a multi-queue root qdisc");
goto err_out4;
goto err_out5;
}

err = gen_new_estimator(&sch->bstats,
Expand All @@ -1311,7 +1312,7 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
tca[TCA_RATE]);
if (err) {
NL_SET_ERR_MSG(extack, "Failed to generate new estimator");
goto err_out4;
goto err_out5;
}
}

Expand All @@ -1321,6 +1322,8 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
return sch;

err_out5:
qdisc_put_stab(rtnl_dereference(sch->stab));
err_out4:
/* ops->init() failed, we call ->destroy() like qdisc_create_dflt() */
if (ops->destroy)
ops->destroy(sch);
Expand All @@ -1332,16 +1335,6 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
err_out:
*errp = err;
return NULL;

err_out4:
/*
* Any broken qdiscs that would require a ops->reset() here?
* The qdisc was never in action so it shouldn't be necessary.
*/
qdisc_put_stab(rtnl_dereference(sch->stab));
if (ops->destroy)
ops->destroy(sch);
goto err_out3;
}

static int qdisc_change(struct Qdisc *sch, struct nlattr **tca,
Expand Down
Loading

0 comments on commit e6ebe6c

Please sign in to comment.