From: Dariusz Sosnowski <dsosnowski@nvidia.com>
To: Viacheslav Ovsiienko <viacheslavo@nvidia.com>,
Ori Kam <orika@nvidia.com>, Suanming Mou <suanmingm@nvidia.com>,
Matan Azrad <matan@nvidia.com>
Cc: <dev@dpdk.org>, Raslan Darawsheh <rasland@nvidia.com>,
Bing Zhao <bingz@nvidia.com>
Subject: [PATCH v2 10/11] net/mlx5: reuse flow fields
Date: Thu, 29 Feb 2024 12:51:55 +0100 [thread overview]
Message-ID: <20240229115157.201671-11-dsosnowski@nvidia.com> (raw)
In-Reply-To: <20240229115157.201671-1-dsosnowski@nvidia.com>
Each time a flow is allocated in mlx5 PMD the whole buffer,
both rte_flow_hw and mlx5dr_rule parts, are zeroed.
This introduces some wasted work because:
- mlx5dr layer does not assume that mlx5dr_rule must be initialized,
- flow action translation in mlx5 PMD does not need most of the fields
of rte_flow_hw to be zeroed.
To reduce this wasted work, this patch introduces flags field to
flow definition. Each flow field which is not always initialized
during flow creation, will have a correspondent flag set if value is
valid (in other words - it was set during flow creation).
Utilizing this mechanism allows PMD to:
- remove zeroing from flow allocation,
- access some fields (especially from rte_flow_hw_aux) if and only if
corresponding flag is set.
Signed-off-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
---
drivers/net/mlx5/mlx5_flow.h | 24 ++++++++-
drivers/net/mlx5/mlx5_flow_hw.c | 93 +++++++++++++++++++++------------
2 files changed, 83 insertions(+), 34 deletions(-)
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index e8f4d2cb16..db65825eab 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -1279,6 +1279,26 @@ enum {
MLX5_FLOW_HW_FLOW_OP_TYPE_RSZ_TBL_MOVE,
};
+enum {
+ MLX5_FLOW_HW_FLOW_FLAG_CNT_ID = RTE_BIT32(0),
+ MLX5_FLOW_HW_FLOW_FLAG_FATE_JUMP = RTE_BIT32(1),
+ MLX5_FLOW_HW_FLOW_FLAG_FATE_HRXQ = RTE_BIT32(2),
+ MLX5_FLOW_HW_FLOW_FLAG_AGE_IDX = RTE_BIT32(3),
+ MLX5_FLOW_HW_FLOW_FLAG_MTR_ID = RTE_BIT32(4),
+ MLX5_FLOW_HW_FLOW_FLAG_MATCHER_SELECTOR = RTE_BIT32(5),
+ MLX5_FLOW_HW_FLOW_FLAG_UPD_FLOW = RTE_BIT32(6),
+};
+
+#define MLX5_FLOW_HW_FLOW_FLAGS_ALL ( \
+ MLX5_FLOW_HW_FLOW_FLAG_CNT_ID | \
+ MLX5_FLOW_HW_FLOW_FLAG_FATE_JUMP | \
+ MLX5_FLOW_HW_FLOW_FLAG_FATE_HRXQ | \
+ MLX5_FLOW_HW_FLOW_FLAG_AGE_IDX | \
+ MLX5_FLOW_HW_FLOW_FLAG_MTR_ID | \
+ MLX5_FLOW_HW_FLOW_FLAG_MATCHER_SELECTOR | \
+ MLX5_FLOW_HW_FLOW_FLAG_UPD_FLOW \
+ )
+
#ifdef PEDANTIC
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
@@ -1295,8 +1315,8 @@ struct rte_flow_hw {
uint32_t res_idx;
/** HWS flow rule index passed to mlx5dr. */
uint32_t rule_idx;
- /** Fate action type. */
- uint32_t fate_type;
+ /** Which flow fields (inline or in auxiliary struct) are used. */
+ uint32_t flags;
/** Ongoing flow operation type. */
uint8_t operation_type;
/** Index of pattern template this flow is based on. */
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 025f04ddde..979be4764a 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -2845,6 +2845,7 @@ flow_hw_shared_action_construct(struct rte_eth_dev *dev, uint32_t queue,
&rule_act->action,
&rule_act->counter.offset))
return -1;
+ flow->flags |= MLX5_FLOW_HW_FLOW_FLAG_CNT_ID;
flow->cnt_id = act_idx;
break;
case MLX5_INDIRECT_ACTION_TYPE_AGE:
@@ -2854,6 +2855,7 @@ flow_hw_shared_action_construct(struct rte_eth_dev *dev, uint32_t queue,
* it in flow destroy.
*/
mlx5_flow_hw_aux_set_age_idx(flow, aux, act_idx);
+ flow->flags |= MLX5_FLOW_HW_FLOW_FLAG_AGE_IDX;
if (action_flags & MLX5_FLOW_ACTION_INDIRECT_COUNT)
/*
* The mutual update for idirect AGE & COUNT will be
@@ -2869,6 +2871,7 @@ flow_hw_shared_action_construct(struct rte_eth_dev *dev, uint32_t queue,
¶m->queue_id, &age_cnt,
idx) < 0)
return -1;
+ flow->flags |= MLX5_FLOW_HW_FLOW_FLAG_CNT_ID;
flow->cnt_id = age_cnt;
param->nb_cnts++;
} else {
@@ -3174,7 +3177,7 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
rule_acts[act_data->action_dst].action =
(!!attr.group) ? jump->hws_action : jump->root_action;
flow->jump = jump;
- flow->fate_type = MLX5_FLOW_FATE_JUMP;
+ flow->flags |= MLX5_FLOW_HW_FLOW_FLAG_FATE_JUMP;
break;
case RTE_FLOW_ACTION_TYPE_RSS:
case RTE_FLOW_ACTION_TYPE_QUEUE:
@@ -3185,7 +3188,7 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
return -1;
rule_acts[act_data->action_dst].action = hrxq->action;
flow->hrxq = hrxq;
- flow->fate_type = MLX5_FLOW_FATE_QUEUE;
+ flow->flags |= MLX5_FLOW_HW_FLOW_FLAG_FATE_HRXQ;
break;
case MLX5_RTE_FLOW_ACTION_TYPE_RSS:
item_flags = table->its[it_idx]->item_flags;
@@ -3264,7 +3267,7 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
(!!attr.group) ? jump->hws_action :
jump->root_action;
flow->jump = jump;
- flow->fate_type = MLX5_FLOW_FATE_JUMP;
+ flow->flags |= MLX5_FLOW_HW_FLOW_FLAG_FATE_JUMP;
if (mlx5_aso_mtr_wait(priv->sh, MLX5_HW_INV_QUEUE, aso_mtr))
return -1;
break;
@@ -3284,6 +3287,7 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
if (age_idx == 0)
return -rte_errno;
mlx5_flow_hw_aux_set_age_idx(flow, aux, age_idx);
+ flow->flags |= MLX5_FLOW_HW_FLOW_FLAG_AGE_IDX;
if (at->action_flags & MLX5_FLOW_ACTION_INDIRECT_COUNT)
/*
* When AGE uses indirect counter, no need to
@@ -3306,6 +3310,7 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
);
if (ret != 0)
return ret;
+ flow->flags |= MLX5_FLOW_HW_FLOW_FLAG_CNT_ID;
flow->cnt_id = cnt_id;
break;
case MLX5_RTE_FLOW_ACTION_TYPE_COUNT:
@@ -3317,6 +3322,7 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
);
if (ret != 0)
return ret;
+ flow->flags |= MLX5_FLOW_HW_FLOW_FLAG_CNT_ID;
flow->cnt_id = act_data->shared_counter.id;
break;
case RTE_FLOW_ACTION_TYPE_CONNTRACK:
@@ -3349,6 +3355,7 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
return ret;
aux = mlx5_flow_hw_aux(dev->data->port_id, flow);
mlx5_flow_hw_aux_set_mtr_id(flow, aux, mtr_idx);
+ flow->flags |= MLX5_FLOW_HW_FLOW_FLAG_MTR_ID;
break;
case RTE_FLOW_ACTION_TYPE_NAT64:
nat64_c = action->conf;
@@ -3360,7 +3367,11 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
}
}
if (at->action_flags & MLX5_FLOW_ACTION_INDIRECT_COUNT) {
+ /* If indirect count is used, then CNT_ID flag should be set. */
+ MLX5_ASSERT(flow->flags & MLX5_FLOW_HW_FLOW_FLAG_CNT_ID);
if (at->action_flags & MLX5_FLOW_ACTION_INDIRECT_AGE) {
+ /* If indirect AGE is used, then AGE_IDX flag should be set. */
+ MLX5_ASSERT(flow->flags & MLX5_FLOW_HW_FLOW_FLAG_AGE_IDX);
aux = mlx5_flow_hw_aux(dev->data->port_id, flow);
age_idx = mlx5_flow_hw_aux_get_age_idx(flow, aux) &
MLX5_HWS_AGE_IDX_MASK;
@@ -3398,8 +3409,10 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
flow->res_idx - 1;
rule_acts[hw_acts->push_remove_pos].ipv6_ext.header = ap->ipv6_push_data;
}
- if (mlx5_hws_cnt_id_valid(hw_acts->cnt_id))
+ if (mlx5_hws_cnt_id_valid(hw_acts->cnt_id)) {
+ flow->flags |= MLX5_FLOW_HW_FLOW_FLAG_CNT_ID;
flow->cnt_id = hw_acts->cnt_id;
+ }
return 0;
}
@@ -3512,7 +3525,7 @@ flow_hw_async_flow_create(struct rte_eth_dev *dev,
"Port must be started before enqueueing flow operations");
return NULL;
}
- flow = mlx5_ipool_zmalloc(table->flow, &flow_idx);
+ flow = mlx5_ipool_malloc(table->flow, &flow_idx);
if (!flow)
goto error;
rule_acts = flow_hw_get_dr_action_buffer(priv, table, action_template_index, queue);
@@ -3531,6 +3544,7 @@ flow_hw_async_flow_create(struct rte_eth_dev *dev,
} else {
flow->res_idx = flow_idx;
}
+ flow->flags = 0;
/*
* Set the flow operation type here in order to know if the flow memory
* should be freed or not when get the result from dequeue.
@@ -3582,6 +3596,7 @@ flow_hw_async_flow_create(struct rte_eth_dev *dev,
(struct mlx5dr_rule *)flow->rule);
rte_rwlock_read_unlock(&table->matcher_replace_rwlk);
aux->matcher_selector = selector;
+ flow->flags |= MLX5_FLOW_HW_FLOW_FLAG_MATCHER_SELECTOR;
}
if (likely(!ret)) {
flow_hw_q_inc_flow_ops(priv, queue);
@@ -3655,7 +3670,7 @@ flow_hw_async_flow_create_by_index(struct rte_eth_dev *dev,
"Flow rule index exceeds table size");
return NULL;
}
- flow = mlx5_ipool_zmalloc(table->flow, &flow_idx);
+ flow = mlx5_ipool_malloc(table->flow, &flow_idx);
if (!flow)
goto error;
rule_acts = flow_hw_get_dr_action_buffer(priv, table, action_template_index, queue);
@@ -3674,6 +3689,7 @@ flow_hw_async_flow_create_by_index(struct rte_eth_dev *dev,
} else {
flow->res_idx = flow_idx;
}
+ flow->flags = 0;
/*
* Set the flow operation type here in order to know if the flow memory
* should be freed or not when get the result from dequeue.
@@ -3715,6 +3731,7 @@ flow_hw_async_flow_create_by_index(struct rte_eth_dev *dev,
(struct mlx5dr_rule *)flow->rule);
rte_rwlock_read_unlock(&table->matcher_replace_rwlk);
aux->matcher_selector = selector;
+ flow->flags |= MLX5_FLOW_HW_FLOW_FLAG_MATCHER_SELECTOR;
}
if (likely(!ret)) {
flow_hw_q_inc_flow_ops(priv, queue);
@@ -3802,6 +3819,7 @@ flow_hw_async_flow_update(struct rte_eth_dev *dev,
} else {
nf->res_idx = of->res_idx;
}
+ nf->flags = 0;
/* Indicate the construction function to set the proper fields. */
nf->operation_type = MLX5_FLOW_HW_FLOW_OP_TYPE_UPDATE;
/*
@@ -3831,6 +3849,7 @@ flow_hw_async_flow_update(struct rte_eth_dev *dev,
*/
of->operation_type = MLX5_FLOW_HW_FLOW_OP_TYPE_UPDATE;
of->user_data = user_data;
+ of->flags |= MLX5_FLOW_HW_FLOW_FLAG_UPD_FLOW;
rule_attr.user_data = of;
ret = mlx5dr_rule_action_update((struct mlx5dr_rule *)of->rule,
action_template_index, rule_acts, &rule_attr);
@@ -3925,13 +3944,14 @@ flow_hw_age_count_release(struct mlx5_priv *priv, uint32_t queue,
uint32_t *cnt_queue;
uint32_t age_idx = aux->orig.age_idx;
+ MLX5_ASSERT(flow->flags & MLX5_FLOW_HW_FLOW_FLAG_CNT_ID);
if (mlx5_hws_cnt_is_shared(priv->hws_cpool, flow->cnt_id)) {
- if (age_idx && !mlx5_hws_age_is_indirect(age_idx)) {
+ if ((flow->flags & MLX5_FLOW_HW_FLOW_FLAG_AGE_IDX) &&
+ !mlx5_hws_age_is_indirect(age_idx)) {
/* Remove this AGE parameter from indirect counter. */
mlx5_hws_cnt_age_set(priv->hws_cpool, flow->cnt_id, 0);
/* Release the AGE parameter. */
mlx5_hws_age_action_destroy(priv, age_idx, error);
- mlx5_flow_hw_aux_set_age_idx(flow, aux, 0);
}
return;
}
@@ -3939,8 +3959,7 @@ flow_hw_age_count_release(struct mlx5_priv *priv, uint32_t queue,
cnt_queue = mlx5_hws_cnt_is_pool_shared(priv) ? NULL : &queue;
/* Put the counter first to reduce the race risk in BG thread. */
mlx5_hws_cnt_pool_put(priv->hws_cpool, cnt_queue, &flow->cnt_id);
- flow->cnt_id = 0;
- if (age_idx) {
+ if (flow->flags & MLX5_FLOW_HW_FLOW_FLAG_AGE_IDX) {
if (mlx5_hws_age_is_indirect(age_idx)) {
uint32_t idx = age_idx & MLX5_HWS_AGE_IDX_MASK;
@@ -3949,7 +3968,6 @@ flow_hw_age_count_release(struct mlx5_priv *priv, uint32_t queue,
/* Release the AGE parameter. */
mlx5_hws_age_action_destroy(priv, age_idx, error);
}
- mlx5_flow_hw_aux_set_age_idx(flow, aux, age_idx);
}
}
@@ -4079,34 +4097,35 @@ hw_cmpl_flow_update_or_destroy(struct rte_eth_dev *dev,
struct mlx5_priv *priv = dev->data->dev_private;
struct mlx5_aso_mtr_pool *pool = priv->hws_mpool;
struct rte_flow_template_table *table = flow->table;
- struct rte_flow_hw_aux *aux = mlx5_flow_hw_aux(dev->data->port_id, flow);
/* Release the original resource index in case of update. */
uint32_t res_idx = flow->res_idx;
- if (flow->fate_type == MLX5_FLOW_FATE_JUMP)
- flow_hw_jump_release(dev, flow->jump);
- else if (flow->fate_type == MLX5_FLOW_FATE_QUEUE)
- mlx5_hrxq_obj_release(dev, flow->hrxq);
- if (mlx5_hws_cnt_id_valid(flow->cnt_id))
- flow_hw_age_count_release(priv, queue,
- flow, error);
- if (aux->orig.mtr_id) {
- mlx5_ipool_free(pool->idx_pool, aux->orig.mtr_id);
- aux->orig.mtr_id = 0;
- }
- if (flow->operation_type != MLX5_FLOW_HW_FLOW_OP_TYPE_UPDATE) {
- if (table->resource)
- mlx5_ipool_free(table->resource, res_idx);
- mlx5_ipool_free(table->flow, flow->idx);
- } else {
+ if (flow->flags & MLX5_FLOW_HW_FLOW_FLAGS_ALL) {
struct rte_flow_hw_aux *aux = mlx5_flow_hw_aux(dev->data->port_id, flow);
- struct rte_flow_hw *upd_flow = &aux->upd_flow;
- rte_memcpy(flow, upd_flow, offsetof(struct rte_flow_hw, rule));
- aux->orig = aux->upd;
- flow->operation_type = MLX5_FLOW_HW_FLOW_OP_TYPE_CREATE;
+ if (flow->flags & MLX5_FLOW_HW_FLOW_FLAG_FATE_JUMP)
+ flow_hw_jump_release(dev, flow->jump);
+ else if (flow->flags & MLX5_FLOW_HW_FLOW_FLAG_FATE_HRXQ)
+ mlx5_hrxq_obj_release(dev, flow->hrxq);
+ if (flow->flags & MLX5_FLOW_HW_FLOW_FLAG_CNT_ID)
+ flow_hw_age_count_release(priv, queue, flow, error);
+ if (flow->flags & MLX5_FLOW_HW_FLOW_FLAG_MTR_ID)
+ mlx5_ipool_free(pool->idx_pool, aux->orig.mtr_id);
+ if (flow->flags & MLX5_FLOW_HW_FLOW_FLAG_UPD_FLOW) {
+ struct rte_flow_hw *upd_flow = &aux->upd_flow;
+
+ rte_memcpy(flow, upd_flow, offsetof(struct rte_flow_hw, rule));
+ aux->orig = aux->upd;
+ flow->operation_type = MLX5_FLOW_HW_FLOW_OP_TYPE_CREATE;
+ if (table->resource)
+ mlx5_ipool_free(table->resource, res_idx);
+ }
+ }
+ if (flow->operation_type == MLX5_FLOW_HW_FLOW_OP_TYPE_DESTROY ||
+ flow->operation_type == MLX5_FLOW_HW_FLOW_OP_TYPE_RSZ_TBL_DESTROY) {
if (table->resource)
mlx5_ipool_free(table->resource, res_idx);
+ mlx5_ipool_free(table->flow, flow->idx);
}
}
@@ -4121,6 +4140,7 @@ hw_cmpl_resizable_tbl(struct rte_eth_dev *dev,
uint32_t selector = aux->matcher_selector;
uint32_t other_selector = (selector + 1) & 1;
+ MLX5_ASSERT(flow->flags & MLX5_FLOW_HW_FLOW_FLAG_MATCHER_SELECTOR);
switch (flow->operation_type) {
case MLX5_FLOW_HW_FLOW_OP_TYPE_RSZ_TBL_CREATE:
rte_atomic_fetch_add_explicit
@@ -11411,10 +11431,18 @@ flow_hw_query(struct rte_eth_dev *dev, struct rte_flow *flow,
case RTE_FLOW_ACTION_TYPE_VOID:
break;
case RTE_FLOW_ACTION_TYPE_COUNT:
+ if (!(hw_flow->flags & MLX5_FLOW_HW_FLOW_FLAG_CNT_ID))
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+ "counter not defined in the rule");
ret = flow_hw_query_counter(dev, hw_flow->cnt_id, data,
error);
break;
case RTE_FLOW_ACTION_TYPE_AGE:
+ if (!(hw_flow->flags & MLX5_FLOW_HW_FLOW_FLAG_AGE_IDX))
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+ "age data not available");
aux = mlx5_flow_hw_aux(dev->data->port_id, hw_flow);
ret = flow_hw_query_age(dev, mlx5_flow_hw_aux_get_age_idx(hw_flow, aux),
data, error);
@@ -12707,6 +12735,7 @@ flow_hw_update_resized(struct rte_eth_dev *dev, uint32_t queue,
.burst = attr->postpone,
};
+ MLX5_ASSERT(hw_flow->flags & MLX5_FLOW_HW_FLOW_FLAG_MATCHER_SELECTOR);
/**
* mlx5dr_matcher_resize_rule_move() accepts original table matcher -
* the one that was used BEFORE table resize.
--
2.39.2
next prev parent reply other threads:[~2024-02-29 11:54 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-28 17:00 [PATCH 00/11] net/mlx5: flow insertion performance improvements Dariusz Sosnowski
2024-02-28 17:00 ` [PATCH 01/11] net/mlx5: allocate local DR rule action buffers Dariusz Sosnowski
2024-02-28 17:00 ` [PATCH 02/11] net/mlx5/hws: add check for matcher rule update support Dariusz Sosnowski
2024-02-28 17:00 ` [PATCH 03/11] net/mlx5/hws: add check if matcher contains complex rules Dariusz Sosnowski
2024-02-28 17:00 ` [PATCH 04/11] net/mlx5: skip the unneeded resource index allocation Dariusz Sosnowski
2024-02-28 17:00 ` [PATCH 05/11] net/mlx5: remove action params from job Dariusz Sosnowski
2024-02-28 17:00 ` [PATCH 06/11] net/mlx5: remove flow pattern " Dariusz Sosnowski
2024-02-28 17:00 ` [PATCH 07/11] net/mlx5: remove updated flow " Dariusz Sosnowski
2024-02-28 17:00 ` [PATCH 08/11] net/mlx5: use flow as operation container Dariusz Sosnowski
2024-02-28 17:00 ` [PATCH 09/11] net/mlx5: move rarely used flow fields outside Dariusz Sosnowski
2024-02-28 17:00 ` [PATCH 10/11] net/mlx5: reuse flow fields Dariusz Sosnowski
2024-02-28 17:00 ` [PATCH 11/11] net/mlx5: remove unneeded device status checking Dariusz Sosnowski
2024-02-29 8:52 ` [PATCH 00/11] net/mlx5: flow insertion performance improvements Ori Kam
2024-02-29 11:51 ` [PATCH v2 " Dariusz Sosnowski
2024-02-29 11:51 ` [PATCH v2 01/11] net/mlx5: allocate local DR rule action buffers Dariusz Sosnowski
2024-02-29 11:51 ` [PATCH v2 02/11] net/mlx5/hws: add check for matcher rule update support Dariusz Sosnowski
2024-02-29 11:51 ` [PATCH v2 03/11] net/mlx5/hws: add check if matcher contains complex rules Dariusz Sosnowski
2024-02-29 11:51 ` [PATCH v2 04/11] net/mlx5: skip the unneeded resource index allocation Dariusz Sosnowski
2024-02-29 11:51 ` [PATCH v2 05/11] net/mlx5: remove action params from job Dariusz Sosnowski
2024-02-29 11:51 ` [PATCH v2 06/11] net/mlx5: remove flow pattern " Dariusz Sosnowski
2024-02-29 11:51 ` [PATCH v2 07/11] net/mlx5: remove updated flow " Dariusz Sosnowski
2024-02-29 11:51 ` [PATCH v2 08/11] net/mlx5: use flow as operation container Dariusz Sosnowski
2024-02-29 11:51 ` [PATCH v2 09/11] net/mlx5: move rarely used flow fields outside Dariusz Sosnowski
2024-02-29 11:51 ` Dariusz Sosnowski [this message]
2024-02-29 11:51 ` [PATCH v2 11/11] net/mlx5: remove unneeded device status checking Dariusz Sosnowski
2024-03-03 12:16 ` [PATCH v2 00/11] net/mlx5: flow insertion performance improvements Raslan Darawsheh
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240229115157.201671-11-dsosnowski@nvidia.com \
--to=dsosnowski@nvidia.com \
--cc=bingz@nvidia.com \
--cc=dev@dpdk.org \
--cc=matan@nvidia.com \
--cc=orika@nvidia.com \
--cc=rasland@nvidia.com \
--cc=suanmingm@nvidia.com \
--cc=viacheslavo@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).