diff options
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/en.h | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/en/qos.c | 87 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 7 |
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); |