Skip to content

Commit a4cba7e

Browse files
committed
Merge branch 'net-mlx5-hws-refactor-action-ste-handling'
Tariq Toukan says: ==================== net/mlx5: HWS, Refactor action STE handling This patch series by Vlad refactors how action STEs are handled for hardware steering. Definitions ---------- * STE (Steering Table Entry): a building block for steering rules. Simple rules consist of a single STE that specifies both the match value and what actions to do. For more complex rules we have one or more match STEs that point to one or more action STEs. It is these action STEs which this patch series is primarily concerned with. * RTC (Rule Table Context): a table that contains STEs. A matcher currently consists of a match RTC and, if necessary, an action RTC. This patch series decouples action RTCs from matchers and moves action RTCs to a central pool. * Matcher: a logical container for steering rules. While the items above describe hardware concepts, a matcher is purely a software construct. Current situation ----------------- As mentioned above, a matcher currently consists of a match RTC (or more, in case of complex matchers) and zero or one action STCs. An action STC is only allocated if the matcher contains sufficiently complicated action templates, or many actions. When adding a rule, we decide based on its action template whether it requires action STEs. If yes, we allocate the required number of action STEs from the matcher's action STE. When updating a rule, we need to prevent the rule ever being in an invalid state. So we need to allocate and write new action STEs first, then update the match STE to point to them, and finally release the old action STEs. So there is a state when a rule needs double the action STEs it normally uses. Thus, for a given matcher of log_sz=N, log_action_ste_sz=A, the action STC log_size is (N + A + 1). We need enough space to hold all the rules' action STEs, and effectively double that space to account for the not very common case of rules being updated. We could manage with much fewer extra action STEs, but RTCs are allocated in powers of two. This results in effective utilization of action RTCs of 50%, outside rule update cases. This is further complicated when resizing matchers. To avoid updating all the rules to point to new match STEs, we keep existing action RTCs around as resize_data, and only free them when the matcher is freed. Action STE pool --------------- This patch series decouples action RTCs from matchers by creating a per-queue pool. When a rule needs to allocate action STEs it does so from the pool, creating a new RTC if needed. During update two sets of action STEs are in use, possibly from different RTCs. The pool is sharded per-queue to avoid lock contention. Each per-queue pool consists of 3 elements, corresponding to rx-only, tx-only and rx-and-tx use cases. The series takes this approach because rules that are bidirectional require that their action STEs have the same index in the rx- and tx-RTCs, and using a single RTC would result in unidirectional rules wasting the STEs for the unused direction. Pool elements, in turn, consist of a list of RTCs. The driver progressively allocates larger RTCs as they are needed to amortize the cost of allocation. Allocation of elements (STEs) inside RTCs is modelled by an existing mechanism, somewhat confusingly also known as a pool. The first few patches in the series refactor this abstraction to simplify it and adapt it to the new schema. Finally, this series implements periodic cleanup of unused action RTCs as a new feature. Previously, once a matcher allocated an action RTC, it would only be freed when the matcher is freed. This resulted in a lot of wasted memory for matchers that had previously grown, but were now mostly unused. Conversely, action STE pools have a timestamp of when they were last used. A cleanup routine periodically checks all pools. If a pool's last usage was too far in the past, it is destroyed. Benchmarks ---------- The test module creates a batch of (1 << 18) rules per queue and then deletes them, in a loop. The rules are complex enough to require two action STEs per rule. Each queue is manipulated from a separate kernel workqueue, so there is a 1:1 correspondence between threads and queues. There are sleep statements between insert and delete batches so that memory usage can be evaluated using `free -m`. The numbers below are the diff between base memory usage (without the mlx5 module inserted) and peak usage while running a test. The values are rounded to the nearest hundred megabytes. The `queues` column lists how many queues the test used. queues mem_before mem_after 1 1300M 800M 4 4000M 2300M 8 7300M 3300M Across all of the tests, insertion and deletion rates are the same before and after these patches. Summary of the patches ---------------------- * Patch 1: Fix matcher action template attach to avoid overrunning the buffer and correctly report errors. * Patches 2-7: Cleanup the existing pool abstraction. Clarify semantics, and use cases, simplify API and callers. * Patch 8: Implement the new action STE pool structure. * Patch 9: Use the action STE pool when manipulating rules. * Patch 10: Remove action RTC from matcher. * Patch 11: Add logic to periodically check and free unused action RTCs. * Patch 12: Export action STE tables in debugfs for our dump tool. ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 4129a75 + 3db55f8 commit a4cba7e

File tree

20 files changed

+972
-969
lines changed

20 files changed

+972
-969
lines changed

drivers/net/ethernet/mellanox/mlx5/core/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,8 @@ mlx5_core-$(CONFIG_MLX5_HW_STEERING) += steering/hws/cmd.o \
154154
steering/hws/vport.o \
155155
steering/hws/bwc_complex.o \
156156
steering/hws/fs_hws_pools.o \
157-
steering/hws/fs_hws.o
157+
steering/hws/fs_hws.o \
158+
steering/hws/action_ste_pool.o
158159

159160
#
160161
# SF device

drivers/net/ethernet/mellanox/mlx5/core/steering/hws/action.c

Lines changed: 23 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ hws_action_fixup_stc_attr(struct mlx5hws_context *ctx,
238238
enum mlx5hws_table_type table_type,
239239
bool is_mirror)
240240
{
241+
struct mlx5hws_pool *pool;
241242
bool use_fixup = false;
242243
u32 fw_tbl_type;
243244
u32 base_id;
@@ -253,13 +254,11 @@ hws_action_fixup_stc_attr(struct mlx5hws_context *ctx,
253254
use_fixup = true;
254255
break;
255256
}
257+
pool = stc_attr->ste_table.ste_pool;
256258
if (!is_mirror)
257-
base_id = mlx5hws_pool_chunk_get_base_id(stc_attr->ste_table.ste_pool,
258-
&stc_attr->ste_table.ste);
259+
base_id = mlx5hws_pool_get_base_id(pool);
259260
else
260-
base_id =
261-
mlx5hws_pool_chunk_get_base_mirror_id(stc_attr->ste_table.ste_pool,
262-
&stc_attr->ste_table.ste);
261+
base_id = mlx5hws_pool_get_base_mirror_id(pool);
263262

264263
*fixup_stc_attr = *stc_attr;
265264
fixup_stc_attr->ste_table.ste_obj_id = base_id;
@@ -337,7 +336,7 @@ __must_hold(&ctx->ctrl_lock)
337336
if (!mlx5hws_context_cap_dynamic_reparse(ctx))
338337
stc_attr->reparse_mode = MLX5_IFC_STC_REPARSE_IGNORE;
339338

340-
obj_0_id = mlx5hws_pool_chunk_get_base_id(stc_pool, stc);
339+
obj_0_id = mlx5hws_pool_get_base_id(stc_pool);
341340

342341
/* According to table/action limitation change the stc_attr */
343342
use_fixup = hws_action_fixup_stc_attr(ctx, stc_attr, &fixup_stc_attr, table_type, false);
@@ -353,7 +352,7 @@ __must_hold(&ctx->ctrl_lock)
353352
if (table_type == MLX5HWS_TABLE_TYPE_FDB) {
354353
u32 obj_1_id;
355354

356-
obj_1_id = mlx5hws_pool_chunk_get_base_mirror_id(stc_pool, stc);
355+
obj_1_id = mlx5hws_pool_get_base_mirror_id(stc_pool);
357356

358357
use_fixup = hws_action_fixup_stc_attr(ctx, stc_attr,
359358
&fixup_stc_attr,
@@ -393,11 +392,11 @@ __must_hold(&ctx->ctrl_lock)
393392
stc_attr.action_type = MLX5_IFC_STC_ACTION_TYPE_DROP;
394393
stc_attr.action_offset = MLX5HWS_ACTION_OFFSET_HIT;
395394
stc_attr.stc_offset = stc->offset;
396-
obj_id = mlx5hws_pool_chunk_get_base_id(stc_pool, stc);
395+
obj_id = mlx5hws_pool_get_base_id(stc_pool);
397396
mlx5hws_cmd_stc_modify(ctx->mdev, obj_id, &stc_attr);
398397

399398
if (table_type == MLX5HWS_TABLE_TYPE_FDB) {
400-
obj_id = mlx5hws_pool_chunk_get_base_mirror_id(stc_pool, stc);
399+
obj_id = mlx5hws_pool_get_base_mirror_id(stc_pool);
401400
mlx5hws_cmd_stc_modify(ctx->mdev, obj_id, &stc_attr);
402401
}
403402

@@ -1575,17 +1574,15 @@ hws_action_create_dest_match_range_definer(struct mlx5hws_context *ctx)
15751574
return definer;
15761575
}
15771576

1578-
static struct mlx5hws_matcher_action_ste *
1577+
static struct mlx5hws_range_action_table *
15791578
hws_action_create_dest_match_range_table(struct mlx5hws_context *ctx,
15801579
struct mlx5hws_definer *definer,
15811580
u32 miss_ft_id)
15821581
{
15831582
struct mlx5hws_cmd_rtc_create_attr rtc_attr = {0};
1584-
struct mlx5hws_action_default_stc *default_stc;
1585-
struct mlx5hws_matcher_action_ste *table_ste;
1583+
struct mlx5hws_range_action_table *table_ste;
15861584
struct mlx5hws_pool_attr pool_attr = {0};
15871585
struct mlx5hws_pool *ste_pool, *stc_pool;
1588-
struct mlx5hws_pool_chunk *ste;
15891586
u32 *rtc_0_id, *rtc_1_id;
15901587
u32 obj_id;
15911588
int ret;
@@ -1604,7 +1601,6 @@ hws_action_create_dest_match_range_table(struct mlx5hws_context *ctx,
16041601

16051602
pool_attr.table_type = MLX5HWS_TABLE_TYPE_FDB;
16061603
pool_attr.pool_type = MLX5HWS_POOL_TYPE_STE;
1607-
pool_attr.flags = MLX5HWS_POOL_FLAGS_FOR_STE_ACTION_POOL;
16081604
pool_attr.alloc_log_sz = 1;
16091605
table_ste->pool = mlx5hws_pool_create(ctx, &pool_attr);
16101606
if (!table_ste->pool) {
@@ -1616,8 +1612,6 @@ hws_action_create_dest_match_range_table(struct mlx5hws_context *ctx,
16161612
rtc_0_id = &table_ste->rtc_0_id;
16171613
rtc_1_id = &table_ste->rtc_1_id;
16181614
ste_pool = table_ste->pool;
1619-
ste = &table_ste->ste;
1620-
ste->order = 1;
16211615

16221616
rtc_attr.log_size = 0;
16231617
rtc_attr.log_depth = 0;
@@ -1629,18 +1623,16 @@ hws_action_create_dest_match_range_table(struct mlx5hws_context *ctx,
16291623
rtc_attr.fw_gen_wqe = true;
16301624
rtc_attr.is_scnd_range = true;
16311625

1632-
obj_id = mlx5hws_pool_chunk_get_base_id(ste_pool, ste);
1626+
obj_id = mlx5hws_pool_get_base_id(ste_pool);
16331627

16341628
rtc_attr.pd = ctx->pd_num;
16351629
rtc_attr.ste_base = obj_id;
1636-
rtc_attr.ste_offset = ste->offset;
16371630
rtc_attr.reparse_mode = mlx5hws_context_get_reparse_mode(ctx);
16381631
rtc_attr.table_type = mlx5hws_table_get_res_fw_ft_type(MLX5HWS_TABLE_TYPE_FDB, false);
16391632

16401633
/* STC is a single resource (obj_id), use any STC for the ID */
16411634
stc_pool = ctx->stc_pool;
1642-
default_stc = ctx->common_res.default_stc;
1643-
obj_id = mlx5hws_pool_chunk_get_base_id(stc_pool, &default_stc->default_hit);
1635+
obj_id = mlx5hws_pool_get_base_id(stc_pool);
16441636
rtc_attr.stc_base = obj_id;
16451637

16461638
ret = mlx5hws_cmd_rtc_create(ctx->mdev, &rtc_attr, rtc_0_id);
@@ -1650,11 +1642,11 @@ hws_action_create_dest_match_range_table(struct mlx5hws_context *ctx,
16501642
}
16511643

16521644
/* Create mirror RTC */
1653-
obj_id = mlx5hws_pool_chunk_get_base_mirror_id(ste_pool, ste);
1645+
obj_id = mlx5hws_pool_get_base_mirror_id(ste_pool);
16541646
rtc_attr.ste_base = obj_id;
16551647
rtc_attr.table_type = mlx5hws_table_get_res_fw_ft_type(MLX5HWS_TABLE_TYPE_FDB, true);
16561648

1657-
obj_id = mlx5hws_pool_chunk_get_base_mirror_id(stc_pool, &default_stc->default_hit);
1649+
obj_id = mlx5hws_pool_get_base_mirror_id(stc_pool);
16581650
rtc_attr.stc_base = obj_id;
16591651

16601652
ret = mlx5hws_cmd_rtc_create(ctx->mdev, &rtc_attr, rtc_1_id);
@@ -1677,9 +1669,9 @@ hws_action_create_dest_match_range_table(struct mlx5hws_context *ctx,
16771669
return NULL;
16781670
}
16791671

1680-
static void
1681-
hws_action_destroy_dest_match_range_table(struct mlx5hws_context *ctx,
1682-
struct mlx5hws_matcher_action_ste *table_ste)
1672+
static void hws_action_destroy_dest_match_range_table(
1673+
struct mlx5hws_context *ctx,
1674+
struct mlx5hws_range_action_table *table_ste)
16831675
{
16841676
mutex_lock(&ctx->ctrl_lock);
16851677

@@ -1691,12 +1683,11 @@ hws_action_destroy_dest_match_range_table(struct mlx5hws_context *ctx,
16911683
mutex_unlock(&ctx->ctrl_lock);
16921684
}
16931685

1694-
static int
1695-
hws_action_create_dest_match_range_fill_table(struct mlx5hws_context *ctx,
1696-
struct mlx5hws_matcher_action_ste *table_ste,
1697-
struct mlx5hws_action *hit_ft_action,
1698-
struct mlx5hws_definer *range_definer,
1699-
u32 min, u32 max)
1686+
static int hws_action_create_dest_match_range_fill_table(
1687+
struct mlx5hws_context *ctx,
1688+
struct mlx5hws_range_action_table *table_ste,
1689+
struct mlx5hws_action *hit_ft_action,
1690+
struct mlx5hws_definer *range_definer, u32 min, u32 max)
17001691
{
17011692
struct mlx5hws_wqe_gta_data_seg_ste match_wqe_data = {0};
17021693
struct mlx5hws_wqe_gta_data_seg_ste range_wqe_data = {0};
@@ -1792,7 +1783,7 @@ mlx5hws_action_create_dest_match_range(struct mlx5hws_context *ctx,
17921783
u32 min, u32 max, u32 flags)
17931784
{
17941785
struct mlx5hws_cmd_stc_modify_attr stc_attr = {0};
1795-
struct mlx5hws_matcher_action_ste *table_ste;
1786+
struct mlx5hws_range_action_table *table_ste;
17961787
struct mlx5hws_action *hit_ft_action;
17971788
struct mlx5hws_definer *definer;
17981789
struct mlx5hws_action *action;
@@ -1837,7 +1828,6 @@ mlx5hws_action_create_dest_match_range(struct mlx5hws_context *ctx,
18371828
stc_attr.action_offset = MLX5HWS_ACTION_OFFSET_HIT;
18381829
stc_attr.action_type = MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_STE_TABLE;
18391830
stc_attr.reparse_mode = MLX5_IFC_STC_REPARSE_IGNORE;
1840-
stc_attr.ste_table.ste = table_ste->ste;
18411831
stc_attr.ste_table.ste_pool = table_ste->pool;
18421832
stc_attr.ste_table.match_definer_id = ctx->caps->trivial_match_definer;
18431833

drivers/net/ethernet/mellanox/mlx5/core/steering/hws/action.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,12 @@ struct mlx5hws_action_template {
118118
u8 only_term;
119119
};
120120

121+
struct mlx5hws_range_action_table {
122+
struct mlx5hws_pool *pool;
123+
u32 rtc_0_id;
124+
u32 rtc_1_id;
125+
};
126+
121127
struct mlx5hws_action {
122128
u8 type;
123129
u8 flags;
@@ -186,7 +192,7 @@ struct mlx5hws_action {
186192
size_t size;
187193
} remove_header;
188194
struct {
189-
struct mlx5hws_matcher_action_ste *table_ste;
195+
struct mlx5hws_range_action_table *table_ste;
190196
struct mlx5hws_action *hit_ft_action;
191197
struct mlx5hws_definer *definer;
192198
} range;

0 commit comments

Comments
 (0)