aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSaeed Mahameed2021-02-09 15:43:56 -0800
committerSaeed Mahameed2022-07-19 13:32:51 -0700
commitaaffda6b36686a368d6569df3f92acfc7fc0fcd8 (patch)
tree6b56397e7ae2aa6e72517c1ea43bafa6e4f6edf4
parentdb83f24d89e614d224eb346e0cfdcc209993dea3 (diff)
net/mlx5e: HTB, hide and dynamically allocate mlx5e_htb structure
Move structure mlx5e_htb from the main driver include file "en.h" to be hidden in qos.c where the qos functionality is implemented, forward declare it for the rest of the driver and allocate it dynamically upon user demand only. Signed-off-by: Saeed Mahameed <saeedm@nvidia.com> Signed-off-by: Moshe Tal <moshet@nvidia.com> Reviewed-by: Tariq Toukan <tariqt@nvidia.com> Reviewed-by: Maxim Mikityanskiy <maximmi@nvidia.com>
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en.h8
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/qos.c87
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_main.c7
3 files changed, 70 insertions, 32 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index d2ed27575097..b07228f69b91 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -899,12 +899,8 @@ struct mlx5e_scratchpad {
cpumask_var_t cpumask;
};
-struct mlx5e_htb {
- DECLARE_HASHTABLE(qos_tc2node, order_base_2(MLX5E_QOS_MAX_LEAF_NODES));
- DECLARE_BITMAP(qos_used_qids, MLX5E_QOS_MAX_LEAF_NODES);
-};
-
struct mlx5e_trap;
+struct mlx5e_htb;
struct mlx5e_priv {
/* priv data path fields - start */
@@ -975,7 +971,7 @@ struct mlx5e_priv {
struct mlx5e_hv_vhca_stats_agent stats_agent;
#endif
struct mlx5e_scratchpad scratchpad;
- struct mlx5e_htb htb;
+ struct mlx5e_htb *htb;
struct mlx5e_mqprio_rl *mqprio_rl;
};
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/qos.c b/drivers/net/ethernet/mellanox/mlx5/core/en/qos.c
index 6136cad397dd..3848f06ac516 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/qos.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/qos.c
@@ -9,6 +9,11 @@
#define BYTES_IN_MBIT 125000
+struct mlx5e_htb {
+ DECLARE_HASHTABLE(qos_tc2node, order_base_2(MLX5E_QOS_MAX_LEAF_NODES));
+ DECLARE_BITMAP(qos_used_qids, MLX5E_QOS_MAX_LEAF_NODES);
+};
+
int mlx5e_qos_bytes_rate_check(struct mlx5_core_dev *mdev, u64 nbytes)
{
if (nbytes < BYTES_IN_MBIT) {
@@ -31,8 +36,9 @@ int mlx5e_qos_max_leaf_nodes(struct mlx5_core_dev *mdev)
int mlx5e_qos_cur_leaf_nodes(struct mlx5e_priv *priv)
{
- int last = find_last_bit(priv->htb.qos_used_qids, mlx5e_qos_max_leaf_nodes(priv->mdev));
+ int last;
+ last = find_last_bit(priv->htb->qos_used_qids, mlx5e_qos_max_leaf_nodes(priv->mdev));
return last == mlx5e_qos_max_leaf_nodes(priv->mdev) ? 0 : last + 1;
}
@@ -44,7 +50,7 @@ static int mlx5e_find_unused_qos_qid(struct mlx5e_priv *priv)
int res;
WARN_ONCE(!mutex_is_locked(&priv->state_lock), "%s: state_lock is not held\n", __func__);
- res = find_first_zero_bit(priv->htb.qos_used_qids, size);
+ res = find_first_zero_bit(priv->htb->qos_used_qids, size);
return res == size ? -ENOSPC : res;
}
@@ -76,10 +82,10 @@ mlx5e_sw_node_create_leaf(struct mlx5e_priv *priv, u16 classid, u16 qid,
node->parent = parent;
node->qid = qid;
- __set_bit(qid, priv->htb.qos_used_qids);
+ __set_bit(qid, priv->htb->qos_used_qids);
node->classid = classid;
- hash_add_rcu(priv->htb.qos_tc2node, &node->hnode, classid);
+ hash_add_rcu(priv->htb->qos_tc2node, &node->hnode, classid);
mlx5e_update_tx_netdev_queues(priv);
@@ -96,7 +102,7 @@ static struct mlx5e_qos_node *mlx5e_sw_node_create_root(struct mlx5e_priv *priv)
node->qid = MLX5E_QOS_QID_INNER;
node->classid = MLX5E_HTB_CLASSID_ROOT;
- hash_add_rcu(priv->htb.qos_tc2node, &node->hnode, node->classid);
+ hash_add_rcu(priv->htb->qos_tc2node, &node->hnode, node->classid);
return node;
}
@@ -105,7 +111,7 @@ static struct mlx5e_qos_node *mlx5e_sw_node_find(struct mlx5e_priv *priv, u32 cl
{
struct mlx5e_qos_node *node = NULL;
- hash_for_each_possible(priv->htb.qos_tc2node, node, hnode, classid) {
+ hash_for_each_possible(priv->htb->qos_tc2node, node, hnode, classid) {
if (node->classid == classid)
break;
}
@@ -117,7 +123,7 @@ static struct mlx5e_qos_node *mlx5e_sw_node_find_rcu(struct mlx5e_priv *priv, u3
{
struct mlx5e_qos_node *node = NULL;
- hash_for_each_possible_rcu(priv->htb.qos_tc2node, node, hnode, classid) {
+ hash_for_each_possible_rcu(priv->htb->qos_tc2node, node, hnode, classid) {
if (node->classid == classid)
break;
}
@@ -129,7 +135,7 @@ static void mlx5e_sw_node_delete(struct mlx5e_priv *priv, struct mlx5e_qos_node
{
hash_del_rcu(&node->hnode);
if (node->qid != MLX5E_QOS_QID_INNER) {
- __clear_bit(node->qid, priv->htb.qos_used_qids);
+ __clear_bit(node->qid, priv->htb->qos_used_qids);
mlx5e_update_tx_netdev_queues(priv);
}
/* Make sure this qid is no longer selected by mlx5e_select_queue, so
@@ -424,7 +430,7 @@ int mlx5e_qos_open_queues(struct mlx5e_priv *priv, struct mlx5e_channels *chs)
if (err)
return err;
- hash_for_each(priv->htb.qos_tc2node, bkt, node, hnode) {
+ hash_for_each(priv->htb->qos_tc2node, bkt, node, hnode) {
if (node->qid == MLX5E_QOS_QID_INNER)
continue;
err = mlx5e_open_qos_sq(priv, chs, node);
@@ -442,7 +448,7 @@ void mlx5e_qos_activate_queues(struct mlx5e_priv *priv)
struct mlx5e_qos_node *node = NULL;
int bkt;
- hash_for_each(priv->htb.qos_tc2node, bkt, node, hnode) {
+ hash_for_each(priv->htb->qos_tc2node, bkt, node, hnode) {
if (node->qid == MLX5E_QOS_QID_INNER)
continue;
mlx5e_activate_qos_sq(priv, node);
@@ -495,12 +501,6 @@ mlx5e_htb_root_add(struct mlx5e_priv *priv, u16 htb_maj_id, u16 htb_defcls,
qos_dbg(priv->mdev, "TC_HTB_CREATE handle %04x:, default :%04x\n", htb_maj_id, htb_defcls);
- if (!mlx5_qos_is_supported(priv->mdev)) {
- NL_SET_ERR_MSG_MOD(extack,
- "Missing QoS capabilities. Try disabling SRIOV or use a supported device.");
- return -EOPNOTSUPP;
- }
-
mlx5e_selq_prepare_htb(&priv->selq, htb_maj_id, htb_defcls);
opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
@@ -749,7 +749,7 @@ static struct mlx5e_qos_node *mlx5e_sw_node_find_by_qid(struct mlx5e_priv *priv,
struct mlx5e_qos_node *node = NULL;
int bkt;
- hash_for_each(priv->htb.qos_tc2node, bkt, node, hnode)
+ hash_for_each(priv->htb->qos_tc2node, bkt, node, hnode)
if (node->qid == qid)
break;
@@ -837,7 +837,7 @@ static int mlx5e_htb_leaf_del(struct mlx5e_priv *priv, u16 *classid,
/* Stop traffic to the old queue. */
WRITE_ONCE(node->qid, MLX5E_QOS_QID_INNER);
- __clear_bit(moved_qid, priv->htb.qos_used_qids);
+ __clear_bit(moved_qid, priv->htb->qos_used_qids);
if (opened) {
txq = netdev_get_tx_queue(priv->netdev,
@@ -849,7 +849,7 @@ static int mlx5e_htb_leaf_del(struct mlx5e_priv *priv, u16 *classid,
/* Prevent packets from the old class from getting into the new one. */
mlx5e_reset_qdisc(priv->netdev, moved_qid);
- __set_bit(qid, priv->htb.qos_used_qids);
+ __set_bit(qid, priv->htb->qos_used_qids);
WRITE_ONCE(node->qid, qid);
if (test_bit(MLX5E_STATE_OPENED, &priv->state)) {
@@ -960,7 +960,7 @@ mlx5e_qos_update_children(struct mlx5e_priv *priv, struct mlx5e_qos_node *node,
int err = 0;
int bkt;
- hash_for_each(priv->htb.qos_tc2node, bkt, child, hnode) {
+ hash_for_each(priv->htb->qos_tc2node, bkt, child, hnode) {
u32 old_bw_share = child->bw_share;
int err_one;
@@ -1027,16 +1027,57 @@ mlx5e_htb_node_modify(struct mlx5e_priv *priv, u16 classid, u64 rate, u64 ceil,
}
/* HTB API */
+
+static struct mlx5e_htb *mlx5e_htb_alloc(void)
+{
+ return kvzalloc(sizeof(struct mlx5e_htb), GFP_KERNEL);
+}
+
+static void mlx5e_htb_free(struct mlx5e_htb *htb)
+{
+ kvfree(htb);
+}
+
+static int mlx5e_htb_init(struct mlx5e_priv *priv, struct tc_htb_qopt_offload *htb)
+{
+ hash_init(priv->htb->qos_tc2node);
+
+ return mlx5e_htb_root_add(priv, htb->parent_classid, htb->classid, htb->extack);
+}
+
+static void mlx5e_htb_cleanup(struct mlx5e_priv *priv)
+{
+ mlx5e_htb_root_del(priv);
+}
+
int mlx5e_htb_setup_tc(struct mlx5e_priv *priv, struct tc_htb_qopt_offload *htb)
{
int res;
+ if (!priv->htb && htb->command != TC_HTB_CREATE)
+ return -EINVAL;
+
switch (htb->command) {
case TC_HTB_CREATE:
- return mlx5e_htb_root_add(priv, htb->parent_classid, htb->classid,
- htb->extack);
+ if (!mlx5_qos_is_supported(priv->mdev)) {
+ NL_SET_ERR_MSG_MOD(htb->extack,
+ "Missing QoS capabilities. Try disabling SRIOV or use a supported device.");
+ return -EOPNOTSUPP;
+ }
+ priv->htb = mlx5e_htb_alloc();
+ if (!priv->htb)
+ return -ENOMEM;
+ res = mlx5e_htb_init(priv, htb);
+ if (res) {
+ mlx5e_htb_free(priv->htb);
+ priv->htb = NULL;
+ }
+ return res;
case TC_HTB_DESTROY:
- return mlx5e_htb_root_del(priv);
+ mlx5e_htb_cleanup(priv);
+ mlx5e_htb_free(priv->htb);
+ priv->htb = NULL;
+ return 0;
case TC_HTB_LEAF_ALLOC_QUEUE:
res = mlx5e_htb_leaf_alloc_queue(priv, htb->classid, htb->parent_classid,
htb->rate, htb->ceil, htb->extack);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index fed24b5a0bae..127aaa1c1d19 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -2572,9 +2572,11 @@ static int mlx5e_netdev_set_tcs(struct net_device *netdev, u16 nch, u8 ntc,
int mlx5e_update_tx_netdev_queues(struct mlx5e_priv *priv)
{
- int qos_queues, nch, ntc, num_txqs, err;
+ int nch, ntc, num_txqs, err;
+ int qos_queues = 0;
- qos_queues = mlx5e_qos_cur_leaf_nodes(priv);
+ if (priv->htb)
+ qos_queues = mlx5e_qos_cur_leaf_nodes(priv);
nch = priv->channels.params.num_channels;
ntc = mlx5e_get_dcb_num_tc(&priv->channels.params);
@@ -5315,7 +5317,6 @@ int mlx5e_priv_init(struct mlx5e_priv *priv,
if (err)
goto err_free_cpumask;
- hash_init(priv->htb.qos_tc2node);
INIT_WORK(&priv->update_carrier_work, mlx5e_update_carrier_work);
INIT_WORK(&priv->set_rx_mode_work, mlx5e_set_rx_mode_work);
INIT_WORK(&priv->tx_timeout_work, mlx5e_tx_timeout_work);