@@ -129,22 +129,18 @@ static void hws_rule_gen_comp(struct mlx5hws_send_engine *queue,
129
129
130
130
static void
131
131
hws_rule_save_resize_info (struct mlx5hws_rule * rule ,
132
- struct mlx5hws_send_ste_attr * ste_attr ,
133
- bool is_update )
132
+ struct mlx5hws_send_ste_attr * ste_attr )
134
133
{
135
134
if (!mlx5hws_matcher_is_resizable (rule -> matcher ))
136
135
return ;
137
136
138
- if (likely (!is_update )) {
137
+ /* resize_info might already exist (if we're in update flow) */
138
+ if (likely (!rule -> resize_info )) {
139
139
rule -> resize_info = kzalloc (sizeof (* rule -> resize_info ), GFP_KERNEL );
140
140
if (unlikely (!rule -> resize_info )) {
141
141
pr_warn ("HWS: resize info isn't allocated for rule\n" );
142
142
return ;
143
143
}
144
-
145
- rule -> resize_info -> max_stes = rule -> matcher -> action_ste .max_stes ;
146
- rule -> resize_info -> action_ste_pool = rule -> matcher -> action_ste .max_stes ?
147
- rule -> matcher -> action_ste .pool : NULL ;
148
144
}
149
145
150
146
memcpy (rule -> resize_info -> ctrl_seg , ste_attr -> wqe_ctrl ,
@@ -199,8 +195,7 @@ hws_rule_load_delete_info(struct mlx5hws_rule *rule,
199
195
}
200
196
}
201
197
202
- static int hws_rule_alloc_action_ste (struct mlx5hws_rule * rule ,
203
- struct mlx5hws_rule_attr * attr )
198
+ static int hws_rule_alloc_action_ste (struct mlx5hws_rule * rule )
204
199
{
205
200
struct mlx5hws_matcher * matcher = rule -> matcher ;
206
201
struct mlx5hws_matcher_action_ste * action_ste ;
@@ -215,32 +210,29 @@ static int hws_rule_alloc_action_ste(struct mlx5hws_rule *rule,
215
210
"Failed to allocate STE for rule actions" );
216
211
return ret ;
217
212
}
218
- rule -> action_ste_idx = ste .offset ;
213
+
214
+ rule -> action_ste .pool = matcher -> action_ste .pool ;
215
+ rule -> action_ste .num_stes = matcher -> action_ste .max_stes ;
216
+ rule -> action_ste .index = ste .offset ;
219
217
220
218
return 0 ;
221
219
}
222
220
223
- void mlx5hws_rule_free_action_ste (struct mlx5hws_rule * rule )
221
+ void mlx5hws_rule_free_action_ste (struct mlx5hws_rule_action_ste_info * action_ste )
224
222
{
225
- struct mlx5hws_matcher * matcher = rule -> matcher ;
226
223
struct mlx5hws_pool_chunk ste = {0 };
227
- struct mlx5hws_pool * pool ;
228
- u8 max_stes ;
229
224
230
- if (mlx5hws_matcher_is_resizable (matcher )) {
231
- /* Free the original action pool if rule was resized */
232
- max_stes = rule -> resize_info -> max_stes ;
233
- pool = rule -> resize_info -> action_ste_pool ;
234
- } else {
235
- max_stes = matcher -> action_ste .max_stes ;
236
- pool = matcher -> action_ste .pool ;
237
- }
225
+ if (!action_ste -> num_stes )
226
+ return ;
238
227
239
- /* This release is safe only when the rule match part was deleted */
240
- ste .order = ilog2 (roundup_pow_of_two (max_stes ));
241
- ste .offset = rule -> action_ste_idx ;
228
+ ste .order = ilog2 (roundup_pow_of_two (action_ste -> num_stes ));
229
+ ste .offset = action_ste -> index ;
242
230
243
- mlx5hws_pool_chunk_free (pool , & ste );
231
+ /* This release is safe only when the rule match STE was deleted
232
+ * (when the rule is being deleted) or replaced with the new STE that
233
+ * isn't pointing to old action STEs (when the rule is being updated).
234
+ */
235
+ mlx5hws_pool_chunk_free (action_ste -> pool , & ste );
244
236
}
245
237
246
238
static void hws_rule_create_init (struct mlx5hws_rule * rule ,
@@ -257,11 +249,24 @@ static void hws_rule_create_init(struct mlx5hws_rule *rule,
257
249
/* In update we use these rtc's */
258
250
rule -> rtc_0 = 0 ;
259
251
rule -> rtc_1 = 0 ;
252
+
253
+ rule -> action_ste .pool = NULL ;
254
+ rule -> action_ste .num_stes = 0 ;
255
+ rule -> action_ste .index = -1 ;
256
+
257
+ rule -> status = MLX5HWS_RULE_STATUS_CREATING ;
258
+ } else {
259
+ rule -> status = MLX5HWS_RULE_STATUS_UPDATING ;
260
260
}
261
261
262
+ /* Initialize the old action STE info - shallow-copy action_ste.
263
+ * In create flow this will set old_action_ste fields to initial values.
264
+ * In update flow this will save the existing action STE info,
265
+ * so that we will later use it to free old STEs.
266
+ */
267
+ rule -> old_action_ste = rule -> action_ste ;
268
+
262
269
rule -> pending_wqes = 0 ;
263
- rule -> action_ste_idx = -1 ;
264
- rule -> status = MLX5HWS_RULE_STATUS_CREATING ;
265
270
266
271
/* Init default send STE attributes */
267
272
ste_attr -> gta_opcode = MLX5HWS_WQE_GTA_OP_ACTIVATE ;
@@ -288,7 +293,6 @@ static void hws_rule_move_init(struct mlx5hws_rule *rule,
288
293
rule -> rtc_1 = 0 ;
289
294
290
295
rule -> pending_wqes = 0 ;
291
- rule -> action_ste_idx = -1 ;
292
296
rule -> status = MLX5HWS_RULE_STATUS_CREATING ;
293
297
rule -> resize_info -> state = MLX5HWS_RULE_RESIZE_STATE_WRITING ;
294
298
}
@@ -349,19 +353,17 @@ static int hws_rule_create_hws(struct mlx5hws_rule *rule,
349
353
350
354
if (action_stes ) {
351
355
/* Allocate action STEs for rules that need more than match STE */
352
- if (!is_update ) {
353
- ret = hws_rule_alloc_action_ste (rule , attr );
354
- if (ret ) {
355
- mlx5hws_err (ctx , "Failed to allocate action memory %d" , ret );
356
- mlx5hws_send_abort_new_dep_wqe (queue );
357
- return ret ;
358
- }
356
+ ret = hws_rule_alloc_action_ste (rule );
357
+ if (ret ) {
358
+ mlx5hws_err (ctx , "Failed to allocate action memory %d" , ret );
359
+ mlx5hws_send_abort_new_dep_wqe (queue );
360
+ return ret ;
359
361
}
360
362
/* Skip RX/TX based on the dep_wqe init */
361
363
ste_attr .rtc_0 = dep_wqe -> rtc_0 ? matcher -> action_ste .rtc_0_id : 0 ;
362
364
ste_attr .rtc_1 = dep_wqe -> rtc_1 ? matcher -> action_ste .rtc_1_id : 0 ;
363
365
/* Action STEs are written to a specific index last to first */
364
- ste_attr .direct_index = rule -> action_ste_idx + action_stes ;
366
+ ste_attr .direct_index = rule -> action_ste . index + action_stes ;
365
367
apply .next_direct_idx = ste_attr .direct_index ;
366
368
} else {
367
369
apply .next_direct_idx = 0 ;
@@ -412,7 +414,7 @@ static int hws_rule_create_hws(struct mlx5hws_rule *rule,
412
414
if (!is_update )
413
415
hws_rule_save_delete_info (rule , & ste_attr );
414
416
415
- hws_rule_save_resize_info (rule , & ste_attr , is_update );
417
+ hws_rule_save_resize_info (rule , & ste_attr );
416
418
mlx5hws_send_engine_inc_rule (queue );
417
419
418
420
if (!attr -> burst )
@@ -433,7 +435,10 @@ static void hws_rule_destroy_failed_hws(struct mlx5hws_rule *rule,
433
435
attr -> user_data , MLX5HWS_RULE_STATUS_DELETED );
434
436
435
437
/* Rule failed now we can safely release action STEs */
436
- mlx5hws_rule_free_action_ste (rule );
438
+ mlx5hws_rule_free_action_ste (& rule -> action_ste );
439
+
440
+ /* Perhaps the rule failed updating - release old action STEs as well */
441
+ mlx5hws_rule_free_action_ste (& rule -> old_action_ste );
437
442
438
443
/* Clear complex tag */
439
444
hws_rule_clear_delete_info (rule );
@@ -470,7 +475,8 @@ static int hws_rule_destroy_hws(struct mlx5hws_rule *rule,
470
475
}
471
476
472
477
/* Rule is not completed yet */
473
- if (rule -> status == MLX5HWS_RULE_STATUS_CREATING )
478
+ if (rule -> status == MLX5HWS_RULE_STATUS_CREATING ||
479
+ rule -> status == MLX5HWS_RULE_STATUS_UPDATING )
474
480
return - EBUSY ;
475
481
476
482
/* Rule failed and doesn't require cleanup */
@@ -487,7 +493,7 @@ static int hws_rule_destroy_hws(struct mlx5hws_rule *rule,
487
493
hws_rule_gen_comp (queue , rule , false,
488
494
attr -> user_data , MLX5HWS_RULE_STATUS_DELETED );
489
495
490
- mlx5hws_rule_free_action_ste (rule );
496
+ mlx5hws_rule_free_action_ste (& rule -> action_ste );
491
497
mlx5hws_rule_clear_resize_info (rule );
492
498
return 0 ;
493
499
}
0 commit comments