mirror of https://gitee.com/openkylin/linux.git
mqprio: Modify mqprio to pass user parameters via ndo_setup_tc.
The configurable priority to traffic class mapping and the user specified queue ranges are used to configure the traffic class, overriding the hardware defaults when the 'hw' option is set to 0. However, when the 'hw' option is non-zero, the hardware QOS defaults are used. This patch makes it so that we can pass the data the user provided to ndo_setup_tc. This allows us to pull in the queue configuration if the user requested it as well as any additional hardware offload type requested by using a value other than 1 for the hw value. Finally it also provides a means for the device driver to return the level supported for the offload type via the qopt->hw value. Previously we were just always assuming the value to be 1, in the future values beyond just 1 may be supported. Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com> Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
2026fecf51
commit
56f36acd21
|
@ -1854,7 +1854,8 @@ static int xgbe_setup_tc(struct net_device *netdev, u32 handle, __be16 proto,
|
|||
if (tc_to_netdev->type != TC_SETUP_MQPRIO)
|
||||
return -EINVAL;
|
||||
|
||||
tc = tc_to_netdev->tc;
|
||||
tc_to_netdev->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
|
||||
tc = tc_to_netdev->mqprio->num_tc;
|
||||
|
||||
if (tc > pdata->hw_feat.tc_cnt)
|
||||
return -EINVAL;
|
||||
|
|
|
@ -4277,7 +4277,10 @@ int __bnx2x_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
|
|||
{
|
||||
if (tc->type != TC_SETUP_MQPRIO)
|
||||
return -EINVAL;
|
||||
return bnx2x_setup_tc(dev, tc->tc);
|
||||
|
||||
tc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
|
||||
|
||||
return bnx2x_setup_tc(dev, tc->mqprio->num_tc);
|
||||
}
|
||||
|
||||
/* called with rtnl_lock */
|
||||
|
|
|
@ -6905,7 +6905,9 @@ static int bnxt_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
|
|||
if (ntc->type != TC_SETUP_MQPRIO)
|
||||
return -EINVAL;
|
||||
|
||||
return bnxt_setup_mq_tc(dev, ntc->tc);
|
||||
ntc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
|
||||
|
||||
return bnxt_setup_mq_tc(dev, ntc->mqprio->num_tc);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RFS_ACCEL
|
||||
|
|
|
@ -346,33 +346,37 @@ static int dpaa_setup_tc(struct net_device *net_dev, u32 handle, __be16 proto,
|
|||
struct tc_to_netdev *tc)
|
||||
{
|
||||
struct dpaa_priv *priv = netdev_priv(net_dev);
|
||||
u8 num_tc;
|
||||
int i;
|
||||
|
||||
if (tc->type != TC_SETUP_MQPRIO)
|
||||
return -EINVAL;
|
||||
|
||||
if (tc->tc == priv->num_tc)
|
||||
tc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
|
||||
num_tc = tc->mqprio->num_tc;
|
||||
|
||||
if (num_tc == priv->num_tc)
|
||||
return 0;
|
||||
|
||||
if (!tc->tc) {
|
||||
if (!num_tc) {
|
||||
netdev_reset_tc(net_dev);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (tc->tc > DPAA_TC_NUM) {
|
||||
if (num_tc > DPAA_TC_NUM) {
|
||||
netdev_err(net_dev, "Too many traffic classes: max %d supported.\n",
|
||||
DPAA_TC_NUM);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
netdev_set_num_tc(net_dev, tc->tc);
|
||||
netdev_set_num_tc(net_dev, num_tc);
|
||||
|
||||
for (i = 0; i < tc->tc; i++)
|
||||
for (i = 0; i < num_tc; i++)
|
||||
netdev_set_tc_queue(net_dev, i, DPAA_TC_TXQ_NUM,
|
||||
i * DPAA_TC_TXQ_NUM);
|
||||
|
||||
out:
|
||||
priv->num_tc = tc->tc ? tc->tc : 1;
|
||||
priv->num_tc = num_tc ? : 1;
|
||||
netif_set_real_num_tx_queues(net_dev, priv->num_tc * DPAA_TC_TXQ_NUM);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1226,7 +1226,9 @@ static int __fm10k_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
|
|||
if (tc->type != TC_SETUP_MQPRIO)
|
||||
return -EINVAL;
|
||||
|
||||
return fm10k_setup_tc(dev, tc->tc);
|
||||
tc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
|
||||
|
||||
return fm10k_setup_tc(dev, tc->mqprio->num_tc);
|
||||
}
|
||||
|
||||
static void fm10k_assign_l2_accel(struct fm10k_intfc *interface,
|
||||
|
|
|
@ -5611,9 +5611,12 @@ static int __i40e_setup_tc(struct net_device *netdev, u32 handle, __be16 proto,
|
|||
struct tc_to_netdev *tc)
|
||||
#endif
|
||||
{
|
||||
if (handle != TC_H_ROOT || tc->type != TC_SETUP_MQPRIO)
|
||||
if (tc->type != TC_SETUP_MQPRIO)
|
||||
return -EINVAL;
|
||||
return i40e_setup_tc(netdev, tc->tc);
|
||||
|
||||
tc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
|
||||
|
||||
return i40e_setup_tc(netdev, tc->mqprio->num_tc);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -8948,7 +8948,9 @@ static int __ixgbe_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
|
|||
if (tc->type != TC_SETUP_MQPRIO)
|
||||
return -EINVAL;
|
||||
|
||||
return ixgbe_setup_tc(dev, tc->tc);
|
||||
tc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
|
||||
|
||||
return ixgbe_setup_tc(dev, tc->mqprio->num_tc);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI_IOV
|
||||
|
|
|
@ -92,7 +92,9 @@ static int __mlx4_en_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
|
|||
if (tc->type != TC_SETUP_MQPRIO)
|
||||
return -EINVAL;
|
||||
|
||||
return mlx4_en_setup_tc(dev, tc->tc);
|
||||
tc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
|
||||
|
||||
return mlx4_en_setup_tc(dev, tc->mqprio->num_tc);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RFS_ACCEL
|
||||
|
|
|
@ -2737,7 +2737,9 @@ static int mlx5e_ndo_setup_tc(struct net_device *dev, u32 handle,
|
|||
if (tc->type != TC_SETUP_MQPRIO)
|
||||
return -EINVAL;
|
||||
|
||||
return mlx5e_setup_tc(dev, tc->tc);
|
||||
tc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
|
||||
|
||||
return mlx5e_setup_tc(dev, tc->mqprio->num_tc);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -437,11 +437,13 @@ int ef4_setup_tc(struct net_device *net_dev, u32 handle, __be16 proto,
|
|||
if (ntc->type != TC_SETUP_MQPRIO)
|
||||
return -EINVAL;
|
||||
|
||||
num_tc = ntc->tc;
|
||||
num_tc = ntc->mqprio->num_tc;
|
||||
|
||||
if (ef4_nic_rev(efx) < EF4_REV_FALCON_B0 || num_tc > EF4_MAX_TX_TC)
|
||||
return -EINVAL;
|
||||
|
||||
ntc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
|
||||
|
||||
if (num_tc == net_dev->num_tc)
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -665,11 +665,13 @@ int efx_setup_tc(struct net_device *net_dev, u32 handle, __be16 proto,
|
|||
if (ntc->type != TC_SETUP_MQPRIO)
|
||||
return -EINVAL;
|
||||
|
||||
num_tc = ntc->tc;
|
||||
num_tc = ntc->mqprio->num_tc;
|
||||
|
||||
if (num_tc > EFX_MAX_TX_TC)
|
||||
return -EINVAL;
|
||||
|
||||
ntc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
|
||||
|
||||
if (num_tc == net_dev->num_tc)
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -1882,6 +1882,7 @@ static u16 netcp_select_queue(struct net_device *dev, struct sk_buff *skb,
|
|||
static int netcp_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
|
||||
struct tc_to_netdev *tc)
|
||||
{
|
||||
u8 num_tc;
|
||||
int i;
|
||||
|
||||
/* setup tc must be called under rtnl lock */
|
||||
|
@ -1890,15 +1891,18 @@ static int netcp_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
|
|||
if (tc->type != TC_SETUP_MQPRIO)
|
||||
return -EINVAL;
|
||||
|
||||
tc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
|
||||
num_tc = tc->mqprio->num_tc;
|
||||
|
||||
/* Sanity-check the number of traffic classes requested */
|
||||
if ((dev->real_num_tx_queues <= 1) ||
|
||||
(dev->real_num_tx_queues < tc->tc))
|
||||
(dev->real_num_tx_queues < num_tc))
|
||||
return -EINVAL;
|
||||
|
||||
/* Configure traffic class to queue mappings */
|
||||
if (tc->tc) {
|
||||
netdev_set_num_tc(dev, tc->tc);
|
||||
for (i = 0; i < tc->tc; i++)
|
||||
if (num_tc) {
|
||||
netdev_set_num_tc(dev, num_tc);
|
||||
for (i = 0; i < num_tc; i++)
|
||||
netdev_set_tc_queue(dev, i, 1, i);
|
||||
} else {
|
||||
netdev_reset_tc(dev);
|
||||
|
|
|
@ -786,11 +786,11 @@ struct tc_cls_u32_offload;
|
|||
struct tc_to_netdev {
|
||||
unsigned int type;
|
||||
union {
|
||||
u8 tc;
|
||||
struct tc_cls_u32_offload *cls_u32;
|
||||
struct tc_cls_flower_offload *cls_flower;
|
||||
struct tc_cls_matchall_offload *cls_mall;
|
||||
struct tc_cls_bpf_offload *cls_bpf;
|
||||
struct tc_mqprio_qopt *mqprio;
|
||||
};
|
||||
bool egress_dev;
|
||||
};
|
||||
|
|
|
@ -28,7 +28,6 @@ static void mqprio_destroy(struct Qdisc *sch)
|
|||
{
|
||||
struct net_device *dev = qdisc_dev(sch);
|
||||
struct mqprio_sched *priv = qdisc_priv(sch);
|
||||
struct tc_to_netdev tc = {.type = TC_SETUP_MQPRIO};
|
||||
unsigned int ntx;
|
||||
|
||||
if (priv->qdiscs) {
|
||||
|
@ -39,10 +38,15 @@ static void mqprio_destroy(struct Qdisc *sch)
|
|||
kfree(priv->qdiscs);
|
||||
}
|
||||
|
||||
if (priv->hw_offload && dev->netdev_ops->ndo_setup_tc)
|
||||
if (priv->hw_offload && dev->netdev_ops->ndo_setup_tc) {
|
||||
struct tc_mqprio_qopt offload = { 0 };
|
||||
struct tc_to_netdev tc = { .type = TC_SETUP_MQPRIO,
|
||||
{ .mqprio = &offload } };
|
||||
|
||||
dev->netdev_ops->ndo_setup_tc(dev, sch->handle, 0, &tc);
|
||||
else
|
||||
} else {
|
||||
netdev_set_num_tc(dev, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static int mqprio_parse_opt(struct net_device *dev, struct tc_mqprio_qopt *qopt)
|
||||
|
@ -144,14 +148,15 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt)
|
|||
* supplied and verified mapping
|
||||
*/
|
||||
if (qopt->hw) {
|
||||
struct tc_to_netdev tc = {.type = TC_SETUP_MQPRIO,
|
||||
{ .tc = qopt->num_tc }};
|
||||
struct tc_mqprio_qopt offload = *qopt;
|
||||
struct tc_to_netdev tc = { .type = TC_SETUP_MQPRIO,
|
||||
{ .mqprio = &offload } };
|
||||
|
||||
err = dev->netdev_ops->ndo_setup_tc(dev, sch->handle, 0, &tc);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
priv->hw_offload = qopt->hw;
|
||||
priv->hw_offload = offload.hw;
|
||||
} else {
|
||||
netdev_set_num_tc(dev, qopt->num_tc);
|
||||
for (i = 0; i < qopt->num_tc; i++)
|
||||
|
|
Loading…
Reference in New Issue