[PATCH v4 3/7] net/mlx5/hws: bwc - adding rules with larger action template
Maayan Kashani
mkashani at nvidia.com
Thu Jun 6 11:55:11 CEST 2024
From: Yevgeny Kliteynik <kliteyn at nvidia.com>
Current BWC implementation doesn't support a case when a rule is added
with AT that requires more action STEs than any other AT that already
exists on this matcher.
This patch adds this support: if such AT is required, we will add the
new AT and do full rehash to a new matcher that is created with all the
action templates, including the new larger AT.
Signed-off-by: Yevgeny Kliteynik <kliteyn at nvidia.com>
Acked-by: Dariusz Sosnowski <dsosnowski at nvidia.com>
---
drivers/net/mlx5/hws/mlx5dr_bwc.c | 68 ++++++++++++++++++++-------
drivers/net/mlx5/hws/mlx5dr_matcher.c | 4 +-
2 files changed, 52 insertions(+), 20 deletions(-)
diff --git a/drivers/net/mlx5/hws/mlx5dr_bwc.c b/drivers/net/mlx5/hws/mlx5dr_bwc.c
index bfc7dbf100..8a8a143f17 100644
--- a/drivers/net/mlx5/hws/mlx5dr_bwc.c
+++ b/drivers/net/mlx5/hws/mlx5dr_bwc.c
@@ -712,7 +712,7 @@ mlx5dr_bwc_matcher_move(struct mlx5dr_bwc_matcher *bwc_matcher)
}
static int
-mlx5dr_bwc_matcher_rehash(struct mlx5dr_bwc_matcher *bwc_matcher, bool rehash_size)
+mlx5dr_bwc_matcher_rehash_size(struct mlx5dr_bwc_matcher *bwc_matcher)
{
uint32_t num_of_rules;
int ret;
@@ -730,8 +730,7 @@ mlx5dr_bwc_matcher_rehash(struct mlx5dr_bwc_matcher *bwc_matcher, bool rehash_si
*/
num_of_rules = rte_atomic_load_explicit(&bwc_matcher->num_of_rules,
rte_memory_order_relaxed);
- if (rehash_size &&
- !mlx5dr_bwc_matcher_rehash_size_needed(bwc_matcher, num_of_rules))
+ if (!mlx5dr_bwc_matcher_rehash_size_needed(bwc_matcher, num_of_rules))
return 0;
/* Now we're done all the checking - do the rehash:
@@ -748,6 +747,19 @@ mlx5dr_bwc_matcher_rehash(struct mlx5dr_bwc_matcher *bwc_matcher, bool rehash_si
return mlx5dr_bwc_matcher_move(bwc_matcher);
}
+static int
+mlx5dr_bwc_matcher_rehash_at(struct mlx5dr_bwc_matcher *bwc_matcher)
+{
+ /* Rehash by action template doesn't require any additional checking.
+ * The bwc_matcher already contains the new action template.
+ * Just do the usual rehash:
+ * - create new matcher
+ * - move all the rules to the new matcher
+ * - destroy the old matcher
+ */
+ return mlx5dr_bwc_matcher_move(bwc_matcher);
+}
+
static struct mlx5dr_bwc_rule *
mlx5dr_bwc_rule_create_root(struct mlx5dr_bwc_matcher *bwc_matcher,
const struct rte_flow_item flow_items[],
@@ -775,7 +787,6 @@ mlx5dr_bwc_rule_create_hws(struct mlx5dr_bwc_matcher *bwc_matcher,
struct mlx5dr_bwc_rule *bwc_rule = NULL;
struct mlx5dr_rule_attr rule_attr;
rte_spinlock_t *queue_lock;
- bool rehash_size = false;
uint32_t num_of_rules;
uint16_t idx;
int at_idx;
@@ -791,7 +802,7 @@ mlx5dr_bwc_rule_create_hws(struct mlx5dr_bwc_matcher *bwc_matcher,
/* check if rehash needed due to missing action template */
at_idx = mlx5dr_bwc_matcher_find_at(bwc_matcher, rule_actions);
- if (at_idx < 0) {
+ if (unlikely(at_idx < 0)) {
/* we need to extend BWC matcher action templates array */
rte_spinlock_unlock(queue_lock);
mlx5dr_bwc_lock_all_queues(ctx);
@@ -810,13 +821,22 @@ mlx5dr_bwc_rule_create_hws(struct mlx5dr_bwc_matcher *bwc_matcher,
ret = mlx5dr_matcher_attach_at(bwc_matcher->matcher,
bwc_matcher->at[at_idx]);
if (unlikely(ret)) {
- mlx5dr_action_template_destroy(bwc_matcher->at[at_idx]);
- bwc_matcher->at[at_idx] = NULL;
- bwc_matcher->num_of_at--;
-
- mlx5dr_bwc_unlock_all_queues(ctx);
- DR_LOG(ERR, "BWC rule: failed attaching action template - %d", ret);
- return NULL;
+ /* Action template attach failed, possibly due to
+ * requiring more action STEs.
+ * Need to attempt creating new matcher with all
+ * the action templates, including the new one.
+ */
+ ret = mlx5dr_bwc_matcher_rehash_at(bwc_matcher);
+ if (unlikely(ret)) {
+ mlx5dr_action_template_destroy(bwc_matcher->at[at_idx]);
+ bwc_matcher->at[at_idx] = NULL;
+ bwc_matcher->num_of_at--;
+
+ mlx5dr_bwc_unlock_all_queues(ctx);
+
+ DR_LOG(ERR, "BWC rule insertion: rehash AT failed - %d", ret);
+ return NULL;
+ }
}
mlx5dr_bwc_unlock_all_queues(ctx);
@@ -826,9 +846,22 @@ mlx5dr_bwc_rule_create_hws(struct mlx5dr_bwc_matcher *bwc_matcher,
/* check if number of rules require rehash */
num_of_rules = rte_atomic_load_explicit(&bwc_matcher->num_of_rules,
rte_memory_order_relaxed);
- if (mlx5dr_bwc_matcher_rehash_size_needed(bwc_matcher, num_of_rules)) {
- rehash_size = true;
- goto rehash;
+ if (unlikely(mlx5dr_bwc_matcher_rehash_size_needed(bwc_matcher, num_of_rules))) {
+ rte_spinlock_unlock(queue_lock);
+
+ mlx5dr_bwc_lock_all_queues(ctx);
+ ret = mlx5dr_bwc_matcher_rehash_size(bwc_matcher);
+ mlx5dr_bwc_unlock_all_queues(ctx);
+
+ if (ret) {
+ DR_LOG(ERR, "BWC rule insertion: rehash size [%d -> %d] failed - %d",
+ bwc_matcher->size_log - MLX5DR_BWC_MATCHER_SIZE_LOG_STEP,
+ bwc_matcher->size_log,
+ ret);
+ return NULL;
+ }
+
+ rte_spinlock_lock(queue_lock);
}
bwc_rule = mlx5dr_bwc_rule_create_hws_sync(bwc_matcher,
@@ -847,14 +880,13 @@ mlx5dr_bwc_rule_create_hws(struct mlx5dr_bwc_matcher *bwc_matcher,
* It could be because there was collision, or some other problem.
* If we don't dive deeper than API, the only thing we know is that
* the status of completion is RTE_FLOW_OP_ERROR.
- * Try rehash and insert rule again - last chance.
+ * Try rehash by size and insert rule again - last chance.
*/
-rehash:
rte_spinlock_unlock(queue_lock);
mlx5dr_bwc_lock_all_queues(ctx);
- ret = mlx5dr_bwc_matcher_rehash(bwc_matcher, rehash_size);
+ ret = mlx5dr_bwc_matcher_rehash_size(bwc_matcher);
mlx5dr_bwc_unlock_all_queues(ctx);
if (ret) {
diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.c b/drivers/net/mlx5/hws/mlx5dr_matcher.c
index 2a84145566..aa5ab96d23 100644
--- a/drivers/net/mlx5/hws/mlx5dr_matcher.c
+++ b/drivers/net/mlx5/hws/mlx5dr_matcher.c
@@ -1347,7 +1347,7 @@ int mlx5dr_matcher_attach_at(struct mlx5dr_matcher *matcher,
int ret;
if (!matcher->attr.max_num_of_at_attach) {
- DR_LOG(ERR, "Num of current at (%d) exceed allowed value",
+ DR_LOG(DEBUG, "Num of current at (%d) exceed allowed value",
matcher->num_of_at);
rte_errno = ENOTSUP;
return -rte_errno;
@@ -1359,7 +1359,7 @@ int mlx5dr_matcher_attach_at(struct mlx5dr_matcher *matcher,
required_stes = at->num_of_action_stes - (!is_jumbo || at->only_term);
if (matcher->action_ste.max_stes < required_stes) {
- DR_LOG(ERR, "Required STEs [%d] exceeds initial action template STE [%d]",
+ DR_LOG(DEBUG, "Required STEs [%d] exceeds initial action template STE [%d]",
required_stes, matcher->action_ste.max_stes);
rte_errno = ENOMEM;
return -rte_errno;
--
2.21.0
More information about the dev
mailing list