@@ -3707,10 +3707,8 @@ static int __iavf_setup_tc(struct net_device *netdev, void *type_data)
if (test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section))
return 0;
- netdev_lock(netdev);
netif_set_real_num_rx_queues(netdev, total_qps);
netif_set_real_num_tx_queues(netdev, total_qps);
- netdev_unlock(netdev);
return ret;
}
@@ -3322,6 +3322,8 @@ int dev_alloc_name(struct net_device *dev, const char *name);
int dev_open(struct net_device *dev, struct netlink_ext_ack *extack);
void dev_close(struct net_device *dev);
void dev_close_many(struct list_head *head, bool unlink);
+int dev_setup_tc(struct net_device *dev, enum tc_setup_type type,
+ void *type_data);
void dev_disable_lro(struct net_device *dev);
int dev_loopback_xmit(struct net *net, struct sock *sk, struct sk_buff *newskb);
u16 dev_pick_tx_zero(struct net_device *dev, struct sk_buff *skb,
@@ -1755,6 +1755,24 @@ void dev_close(struct net_device *dev)
}
EXPORT_SYMBOL(dev_close);
+int dev_setup_tc(struct net_device *dev, enum tc_setup_type type,
+ void *type_data)
+{
+ const struct net_device_ops *ops = dev->netdev_ops;
+ int ret;
+
+ ASSERT_RTNL();
+
+ if (!ops->ndo_setup_tc)
+ return -EOPNOTSUPP;
+
+ netdev_lock_ops(dev);
+ ret = ops->ndo_setup_tc(dev, type, type_data);
+ netdev_unlock_ops(dev);
+
+ return ret;
+}
+EXPORT_SYMBOL(dev_setup_tc);
/**
* dev_disable_lro - disable Large Receive Offload on a device
@@ -1738,10 +1738,7 @@ static int dsa_user_setup_ft_block(struct dsa_switch *ds, int port,
{
struct net_device *conduit = dsa_port_to_conduit(dsa_to_port(ds, port));
- if (!conduit->netdev_ops->ndo_setup_tc)
- return -EOPNOTSUPP;
-
- return conduit->netdev_ops->ndo_setup_tc(conduit, TC_SETUP_FT, type_data);
+ return dev_setup_tc(conduit, TC_SETUP_FT, type_data);
}
static int dsa_user_setup_tc(struct net_device *dev, enum tc_setup_type type,
@@ -1175,7 +1175,7 @@ static int nf_flow_table_offload_cmd(struct flow_block_offload *bo,
nf_flow_table_block_offload_init(bo, dev_net(dev), cmd, flowtable,
extack);
down_write(&flowtable->flow_block_lock);
- err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_FT, bo);
+ err = dev_setup_tc(dev, TC_SETUP_FT, bo);
up_write(&flowtable->flow_block_lock);
if (err < 0)
return err;
@@ -390,7 +390,7 @@ static int nft_block_offload_cmd(struct nft_base_chain *chain,
nft_flow_block_offload_init(&bo, dev_net(dev), cmd, chain, &extack);
- err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_BLOCK, &bo);
+ err = dev_setup_tc(dev, TC_SETUP_BLOCK, &bo);
if (err < 0)
return err;
@@ -835,7 +835,7 @@ static int tcf_block_offload_cmd(struct tcf_block *block,
if (dev->netdev_ops->ndo_setup_tc) {
int err;
- err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_BLOCK, &bo);
+ err = dev_setup_tc(dev, TC_SETUP_BLOCK, &bo);
if (err < 0) {
if (err != -EOPNOTSUPP)
NL_SET_ERR_MSG(extack, "Driver ndo_setup_tc failed");
@@ -836,7 +836,7 @@ int qdisc_offload_dump_helper(struct Qdisc *sch, enum tc_setup_type type,
if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc)
return 0;
- err = dev->netdev_ops->ndo_setup_tc(dev, type, type_data);
+ err = dev_setup_tc(dev, type, type_data);
if (err == -EOPNOTSUPP)
return 0;
@@ -858,7 +858,7 @@ void qdisc_offload_graft_helper(struct net_device *dev, struct Qdisc *sch,
if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc)
return;
- err = dev->netdev_ops->ndo_setup_tc(dev, type, type_data);
+ err = dev_setup_tc(dev, type, type_data);
/* Don't report error if the graft is part of destroy operation. */
if (!err || !new || new == &noop_qdisc)
@@ -880,7 +880,6 @@ void qdisc_offload_query_caps(struct net_device *dev,
enum tc_setup_type type,
void *caps, size_t caps_len)
{
- const struct net_device_ops *ops = dev->netdev_ops;
struct tc_query_caps_base base = {
.type = type,
.caps = caps,
@@ -888,8 +887,7 @@ void qdisc_offload_query_caps(struct net_device *dev,
memset(caps, 0, caps_len);
- if (ops->ndo_setup_tc)
- ops->ndo_setup_tc(dev, TC_QUERY_CAPS, &base);
+ dev_setup_tc(dev, TC_QUERY_CAPS, &base);
}
EXPORT_SYMBOL(qdisc_offload_query_caps);
@@ -251,7 +251,6 @@ static void cbs_disable_offload(struct net_device *dev,
struct cbs_sched_data *q)
{
struct tc_cbs_qopt_offload cbs = { };
- const struct net_device_ops *ops;
int err;
if (!q->offload)
@@ -260,14 +259,13 @@ static void cbs_disable_offload(struct net_device *dev,
q->enqueue = cbs_enqueue_soft;
q->dequeue = cbs_dequeue_soft;
- ops = dev->netdev_ops;
- if (!ops->ndo_setup_tc)
+ if (!dev->netdev_ops->ndo_setup_tc)
return;
cbs.queue = q->queue;
cbs.enable = 0;
- err = ops->ndo_setup_tc(dev, TC_SETUP_QDISC_CBS, &cbs);
+ err = dev_setup_tc(dev, TC_SETUP_QDISC_CBS, &cbs);
if (err < 0)
pr_warn("Couldn't disable CBS offload for queue %d\n",
cbs.queue);
@@ -294,7 +292,7 @@ static int cbs_enable_offload(struct net_device *dev, struct cbs_sched_data *q,
cbs.idleslope = opt->idleslope;
cbs.sendslope = opt->sendslope;
- err = ops->ndo_setup_tc(dev, TC_SETUP_QDISC_CBS, &cbs);
+ err = dev_setup_tc(dev, TC_SETUP_QDISC_CBS, &cbs);
if (err < 0) {
NL_SET_ERR_MSG(extack, "Specified device failed to setup cbs hardware offload");
return err;
@@ -297,20 +297,18 @@ static void etf_disable_offload(struct net_device *dev,
struct etf_sched_data *q)
{
struct tc_etf_qopt_offload etf = { };
- const struct net_device_ops *ops;
int err;
if (!q->offload)
return;
- ops = dev->netdev_ops;
- if (!ops->ndo_setup_tc)
+ if (!dev->netdev_ops->ndo_setup_tc)
return;
etf.queue = q->queue;
etf.enable = 0;
- err = ops->ndo_setup_tc(dev, TC_SETUP_QDISC_ETF, &etf);
+ err = dev_setup_tc(dev, TC_SETUP_QDISC_ETF, &etf);
if (err < 0)
pr_warn("Couldn't disable ETF offload for queue %d\n",
etf.queue);
@@ -331,7 +329,7 @@ static int etf_enable_offload(struct net_device *dev, struct etf_sched_data *q,
etf.queue = q->queue;
etf.enable = 1;
- err = ops->ndo_setup_tc(dev, TC_SETUP_QDISC_ETF, &etf);
+ err = dev_setup_tc(dev, TC_SETUP_QDISC_ETF, &etf);
if (err < 0) {
NL_SET_ERR_MSG(extack, "Specified device failed to setup ETF hardware offload");
return err;
@@ -142,7 +142,7 @@ static void ets_offload_change(struct Qdisc *sch)
qopt.replace_params.weights[i] = weight;
}
- dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_ETS, &qopt);
+ dev_setup_tc(dev, TC_SETUP_QDISC_ETS, &qopt);
}
static void ets_offload_destroy(struct Qdisc *sch)
@@ -156,7 +156,7 @@ static void ets_offload_destroy(struct Qdisc *sch)
qopt.command = TC_ETS_DESTROY;
qopt.handle = sch->handle;
qopt.parent = sch->parent;
- dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_ETS, &qopt);
+ dev_setup_tc(dev, TC_SETUP_QDISC_ETS, &qopt);
}
static void ets_offload_graft(struct Qdisc *sch, struct Qdisc *new,
@@ -67,7 +67,7 @@ static void fifo_offload_init(struct Qdisc *sch)
qopt.command = TC_FIFO_REPLACE;
qopt.handle = sch->handle;
qopt.parent = sch->parent;
- dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_FIFO, &qopt);
+ dev_setup_tc(dev, TC_SETUP_QDISC_FIFO, &qopt);
}
static void fifo_offload_destroy(struct Qdisc *sch)
@@ -81,7 +81,7 @@ static void fifo_offload_destroy(struct Qdisc *sch)
qopt.command = TC_FIFO_DESTROY;
qopt.handle = sch->handle;
qopt.parent = sch->parent;
- dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_FIFO, &qopt);
+ dev_setup_tc(dev, TC_SETUP_QDISC_FIFO, &qopt);
}
static int fifo_offload_dump(struct Qdisc *sch)
@@ -348,7 +348,7 @@ static void gred_offload(struct Qdisc *sch, enum tc_gred_command command)
opt->set.qstats = &sch->qstats;
}
- dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_GRED, opt);
+ dev_setup_tc(dev, TC_SETUP_QDISC_GRED, opt);
}
static int gred_offload_dump_stats(struct Qdisc *sch)
@@ -1041,7 +1041,7 @@ static void htb_work_func(struct work_struct *work)
static int htb_offload(struct net_device *dev, struct tc_htb_qopt_offload *opt)
{
- return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_HTB, opt);
+ return dev_setup_tc(dev, TC_SETUP_QDISC_HTB, opt);
}
static int htb_init(struct Qdisc *sch, struct nlattr *opt,
@@ -32,7 +32,7 @@ static int mq_offload(struct Qdisc *sch, enum tc_mq_command cmd)
if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc)
return -EOPNOTSUPP;
- return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_MQ, &opt);
+ return dev_setup_tc(dev, TC_SETUP_QDISC_MQ, &opt);
}
static int mq_offload_stats(struct Qdisc *sch)
@@ -67,8 +67,7 @@ static int mqprio_enable_offload(struct Qdisc *sch,
mqprio_fp_to_offload(priv->fp, &mqprio);
- err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_MQPRIO,
- &mqprio);
+ err = dev_setup_tc(dev, TC_SETUP_QDISC_MQPRIO, &mqprio);
if (err)
return err;
@@ -86,8 +85,7 @@ static void mqprio_disable_offload(struct Qdisc *sch)
switch (priv->mode) {
case TC_MQPRIO_MODE_DCB:
case TC_MQPRIO_MODE_CHANNEL:
- dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_MQPRIO,
- &mqprio);
+ dev_setup_tc(dev, TC_SETUP_QDISC_MQPRIO, &mqprio);
break;
}
}
@@ -158,7 +158,7 @@ static int prio_offload(struct Qdisc *sch, struct tc_prio_qopt *qopt)
opt.command = TC_PRIO_DESTROY;
}
- return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_PRIO, &opt);
+ return dev_setup_tc(dev, TC_SETUP_QDISC_PRIO, &opt);
}
static void
@@ -209,7 +209,7 @@ static int red_offload(struct Qdisc *sch, bool enable)
opt.command = TC_RED_DESTROY;
}
- return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED, &opt);
+ return dev_setup_tc(dev, TC_SETUP_QDISC_RED, &opt);
}
static void red_destroy(struct Qdisc *sch)
@@ -460,8 +460,7 @@ static int red_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
.xstats = &q->stats,
},
};
- dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED,
- &hw_stats_request);
+ dev_setup_tc(dev, TC_SETUP_QDISC_RED, &hw_stats_request);
}
st.early = q->stats.prob_drop + q->stats.forced_drop;
st.pdrop = q->stats.pdrop;
@@ -1539,7 +1539,7 @@ static int taprio_enable_offload(struct net_device *dev,
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);
+ err = dev_setup_tc(dev, TC_SETUP_QDISC_TAPRIO, offload);
if (err < 0) {
NL_SET_ERR_MSG_WEAK(extack,
"Device failed to setup taprio offload");
@@ -1564,7 +1564,6 @@ 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;
@@ -1579,7 +1578,7 @@ static int taprio_disable_offload(struct net_device *dev,
}
offload->cmd = TAPRIO_CMD_DESTROY;
- err = ops->ndo_setup_tc(dev, TC_SETUP_QDISC_TAPRIO, offload);
+ err = dev_setup_tc(dev, TC_SETUP_QDISC_TAPRIO, offload);
if (err < 0) {
NL_SET_ERR_MSG(extack,
"Device failed to disable offload");
@@ -2314,24 +2313,21 @@ static int taprio_dump_xstats(struct Qdisc *sch, struct gnet_dump *d,
struct tc_taprio_qopt_stats *stats)
{
struct net_device *dev = qdisc_dev(sch);
- const struct net_device_ops *ops;
struct sk_buff *skb = d->skb;
struct nlattr *xstats;
int err;
- ops = qdisc_dev(sch)->netdev_ops;
-
/* FIXME I could use qdisc_offload_dump_helper(), but that messes
* with sch->flags depending on whether the device reports taprio
* stats, and I'm not sure whether that's a good idea, considering
* that stats are optional to the offload itself
*/
- if (!ops->ndo_setup_tc)
+ if (!dev->netdev_ops->ndo_setup_tc)
return 0;
memset(stats, 0xff, sizeof(*stats));
- err = ops->ndo_setup_tc(dev, TC_SETUP_QDISC_TAPRIO, offload);
+ err = dev_setup_tc(dev, TC_SETUP_QDISC_TAPRIO, offload);
if (err == -EOPNOTSUPP)
return 0;
if (err)
@@ -155,7 +155,7 @@ static void tbf_offload_change(struct Qdisc *sch)
qopt.replace_params.max_size = q->max_size;
qopt.replace_params.qstats = &sch->qstats;
- dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_TBF, &qopt);
+ dev_setup_tc(dev, TC_SETUP_QDISC_TBF, &qopt);
}
static void tbf_offload_destroy(struct Qdisc *sch)
@@ -169,7 +169,7 @@ static void tbf_offload_destroy(struct Qdisc *sch)
qopt.command = TC_TBF_DESTROY;
qopt.handle = sch->handle;
qopt.parent = sch->parent;
- dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_TBF, &qopt);
+ dev_setup_tc(dev, TC_SETUP_QDISC_TBF, &qopt);
}
static int tbf_offload_dump(struct Qdisc *sch)
Introduce new dev_setup_tc that handles the details and call it from all qdiscs/classifiers. The instance lock is still applied only to the drivers that implement shaper API so only iavf is affected. Cc: Saeed Mahameed <saeed@kernel.org> Signed-off-by: Stanislav Fomichev <sdf@fomichev.me> --- drivers/net/ethernet/intel/iavf/iavf_main.c | 2 -- include/linux/netdevice.h | 2 ++ net/core/dev.c | 18 ++++++++++++++++++ net/dsa/user.c | 5 +---- net/netfilter/nf_flow_table_offload.c | 2 +- net/netfilter/nf_tables_offload.c | 2 +- net/sched/cls_api.c | 2 +- net/sched/sch_api.c | 8 +++----- net/sched/sch_cbs.c | 8 +++----- net/sched/sch_etf.c | 8 +++----- net/sched/sch_ets.c | 4 ++-- net/sched/sch_fifo.c | 4 ++-- net/sched/sch_gred.c | 2 +- net/sched/sch_htb.c | 2 +- net/sched/sch_mq.c | 2 +- net/sched/sch_mqprio.c | 6 ++---- net/sched/sch_prio.c | 2 +- net/sched/sch_red.c | 5 ++--- net/sched/sch_taprio.c | 12 ++++-------- net/sched/sch_tbf.c | 4 ++-- 20 files changed, 51 insertions(+), 49 deletions(-)