Skip to content

Commit c9c9af9

Browse files
jpirkodavem330
authored andcommitted
mlxsw: spectrum_acl: Allow to interrupt/continue rehash work
Currently, migration of vregions with many entries may take long time during which insertions and removals of the rules are blocked due to wait to acquire vregion->lock. To overcome this, allow to interrupt and continue rehash work according to the set credits - number of rules to migrate. Signed-off-by: Jiri Pirko <[email protected]> Signed-off-by: Ido Schimmel <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 8435005 commit c9c9af9

File tree

1 file changed

+62
-20
lines changed

1 file changed

+62
-20
lines changed

drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c

+62-20
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ size_t mlxsw_sp_acl_tcam_priv_size(struct mlxsw_sp *mlxsw_sp)
2727

2828
#define MLXSW_SP_ACL_TCAM_VREGION_REHASH_INTRVL_DFLT 5000 /* ms */
2929
#define MLXSW_SP_ACL_TCAM_VREGION_REHASH_INTRVL_MIN 3000 /* ms */
30+
#define MLXSW_SP_ACL_TCAM_VREGION_REHASH_CREDITS 100 /* number of entries */
3031

3132
int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp,
3233
struct mlxsw_sp_acl_tcam *tcam)
@@ -732,16 +733,26 @@ mlxsw_sp_acl_tcam_vregion_rehash_work_schedule(struct mlxsw_sp_acl_tcam_vregion
732733

733734
static int
734735
mlxsw_sp_acl_tcam_vregion_rehash(struct mlxsw_sp *mlxsw_sp,
735-
struct mlxsw_sp_acl_tcam_vregion *vregion);
736+
struct mlxsw_sp_acl_tcam_vregion *vregion,
737+
int *credits);
736738

737739
static void mlxsw_sp_acl_tcam_vregion_rehash_work(struct work_struct *work)
738740
{
739741
struct mlxsw_sp_acl_tcam_vregion *vregion =
740742
container_of(work, struct mlxsw_sp_acl_tcam_vregion,
741743
rehash.dw.work);
744+
int credits = MLXSW_SP_ACL_TCAM_VREGION_REHASH_CREDITS;
745+
int err;
742746

743-
mlxsw_sp_acl_tcam_vregion_rehash(vregion->mlxsw_sp, vregion);
744-
mlxsw_sp_acl_tcam_vregion_rehash_work_schedule(vregion);
747+
err = mlxsw_sp_acl_tcam_vregion_rehash(vregion->mlxsw_sp,
748+
vregion, &credits);
749+
if (credits < 0)
750+
/* Rehash gone out of credits so it was interrupted.
751+
* Schedule the work as soon as possible to continue.
752+
*/
753+
mlxsw_core_schedule_dw(&vregion->rehash.dw, 0);
754+
else
755+
mlxsw_sp_acl_tcam_vregion_rehash_work_schedule(vregion);
745756
}
746757

747758
static struct mlxsw_sp_acl_tcam_vregion *
@@ -1176,14 +1187,18 @@ mlxsw_sp_acl_tcam_ventry_activity_get(struct mlxsw_sp *mlxsw_sp,
11761187
static int
11771188
mlxsw_sp_acl_tcam_ventry_migrate(struct mlxsw_sp *mlxsw_sp,
11781189
struct mlxsw_sp_acl_tcam_ventry *ventry,
1179-
struct mlxsw_sp_acl_tcam_chunk *chunk)
1190+
struct mlxsw_sp_acl_tcam_chunk *chunk,
1191+
int *credits)
11801192
{
11811193
struct mlxsw_sp_acl_tcam_entry *new_entry;
11821194

11831195
/* First check if the entry is not already where we want it to be. */
11841196
if (ventry->entry->chunk == chunk)
11851197
return 0;
11861198

1199+
if (--(*credits) < 0)
1200+
return 0;
1201+
11871202
new_entry = mlxsw_sp_acl_tcam_entry_create(mlxsw_sp, ventry, chunk);
11881203
if (IS_ERR(new_entry))
11891204
return PTR_ERR(new_entry);
@@ -1223,7 +1238,8 @@ static int
12231238
mlxsw_sp_acl_tcam_vchunk_migrate_one(struct mlxsw_sp *mlxsw_sp,
12241239
struct mlxsw_sp_acl_tcam_vchunk *vchunk,
12251240
struct mlxsw_sp_acl_tcam_region *region,
1226-
struct mlxsw_sp_acl_tcam_rehash_ctx *ctx)
1241+
struct mlxsw_sp_acl_tcam_rehash_ctx *ctx,
1242+
int *credits)
12271243
{
12281244
struct mlxsw_sp_acl_tcam_ventry *ventry;
12291245
int err;
@@ -1240,7 +1256,7 @@ mlxsw_sp_acl_tcam_vchunk_migrate_one(struct mlxsw_sp *mlxsw_sp,
12401256

12411257
list_for_each_entry(ventry, &vchunk->ventry_list, list) {
12421258
err = mlxsw_sp_acl_tcam_ventry_migrate(mlxsw_sp, ventry,
1243-
vchunk->chunk);
1259+
vchunk->chunk, credits);
12441260
if (err) {
12451261
if (ctx->this_is_rollback)
12461262
return err;
@@ -1250,6 +1266,11 @@ mlxsw_sp_acl_tcam_vchunk_migrate_one(struct mlxsw_sp *mlxsw_sp,
12501266
*/
12511267
swap(vchunk->chunk, vchunk->chunk2);
12521268
return err;
1269+
} else if (*credits < 0) {
1270+
/* We are out of credits, the rest of the ventries
1271+
* will be migrated later.
1272+
*/
1273+
return 0;
12531274
}
12541275
}
12551276

@@ -1260,16 +1281,17 @@ mlxsw_sp_acl_tcam_vchunk_migrate_one(struct mlxsw_sp *mlxsw_sp,
12601281
static int
12611282
mlxsw_sp_acl_tcam_vchunk_migrate_all(struct mlxsw_sp *mlxsw_sp,
12621283
struct mlxsw_sp_acl_tcam_vregion *vregion,
1263-
struct mlxsw_sp_acl_tcam_rehash_ctx *ctx)
1284+
struct mlxsw_sp_acl_tcam_rehash_ctx *ctx,
1285+
int *credits)
12641286
{
12651287
struct mlxsw_sp_acl_tcam_vchunk *vchunk;
12661288
int err;
12671289

12681290
list_for_each_entry(vchunk, &vregion->vchunk_list, list) {
12691291
err = mlxsw_sp_acl_tcam_vchunk_migrate_one(mlxsw_sp, vchunk,
12701292
vregion->region,
1271-
ctx);
1272-
if (err)
1293+
ctx, credits);
1294+
if (err || *credits < 0)
12731295
return err;
12741296
}
12751297
return 0;
@@ -1278,21 +1300,24 @@ mlxsw_sp_acl_tcam_vchunk_migrate_all(struct mlxsw_sp *mlxsw_sp,
12781300
static int
12791301
mlxsw_sp_acl_tcam_vregion_migrate(struct mlxsw_sp *mlxsw_sp,
12801302
struct mlxsw_sp_acl_tcam_vregion *vregion,
1281-
struct mlxsw_sp_acl_tcam_rehash_ctx *ctx)
1303+
struct mlxsw_sp_acl_tcam_rehash_ctx *ctx,
1304+
int *credits)
12821305
{
12831306
int err, err2;
12841307

12851308
trace_mlxsw_sp_acl_tcam_vregion_migrate(mlxsw_sp, vregion);
12861309
mutex_lock(&vregion->lock);
1287-
err = mlxsw_sp_acl_tcam_vchunk_migrate_all(mlxsw_sp, vregion, ctx);
1310+
err = mlxsw_sp_acl_tcam_vchunk_migrate_all(mlxsw_sp, vregion,
1311+
ctx, credits);
12881312
if (err) {
12891313
/* In case migration was not successful, we need to swap
12901314
* so the original region pointer is assigned again
12911315
* to vregion->region.
12921316
*/
12931317
swap(vregion->region, vregion->region2);
12941318
ctx->this_is_rollback = true;
1295-
err2 = mlxsw_sp_acl_tcam_vchunk_migrate_all(mlxsw_sp, vregion, ctx);
1319+
err2 = mlxsw_sp_acl_tcam_vchunk_migrate_all(mlxsw_sp, vregion,
1320+
ctx, credits);
12961321
if (err2)
12971322
vregion->failed_rollback = true;
12981323
}
@@ -1301,6 +1326,12 @@ mlxsw_sp_acl_tcam_vregion_migrate(struct mlxsw_sp *mlxsw_sp,
13011326
return err;
13021327
}
13031328

1329+
static bool
1330+
mlxsw_sp_acl_tcam_vregion_rehash_in_progress(const struct mlxsw_sp_acl_tcam_rehash_ctx *ctx)
1331+
{
1332+
return ctx->hints_priv;
1333+
}
1334+
13041335
static int
13051336
mlxsw_sp_acl_tcam_vregion_rehash_start(struct mlxsw_sp *mlxsw_sp,
13061337
struct mlxsw_sp_acl_tcam_vregion *vregion,
@@ -1372,19 +1403,28 @@ mlxsw_sp_acl_tcam_vregion_rehash_end(struct mlxsw_sp *mlxsw_sp,
13721403

13731404
static int
13741405
mlxsw_sp_acl_tcam_vregion_rehash(struct mlxsw_sp *mlxsw_sp,
1375-
struct mlxsw_sp_acl_tcam_vregion *vregion)
1406+
struct mlxsw_sp_acl_tcam_vregion *vregion,
1407+
int *credits)
13761408
{
13771409
struct mlxsw_sp_acl_tcam_rehash_ctx *ctx = &vregion->rehash.ctx;
13781410
int err;
13791411

1380-
err = mlxsw_sp_acl_tcam_vregion_rehash_start(mlxsw_sp, vregion, ctx);
1381-
if (err) {
1382-
if (err != -EAGAIN)
1383-
dev_err(mlxsw_sp->bus_info->dev, "Failed get rehash hints\n");
1384-
return err;
1412+
/* Check if the previous rehash work was interrupted
1413+
* which means we have to continue it now.
1414+
* If not, start a new rehash.
1415+
*/
1416+
if (!mlxsw_sp_acl_tcam_vregion_rehash_in_progress(ctx)) {
1417+
err = mlxsw_sp_acl_tcam_vregion_rehash_start(mlxsw_sp,
1418+
vregion, ctx);
1419+
if (err) {
1420+
if (err != -EAGAIN)
1421+
dev_err(mlxsw_sp->bus_info->dev, "Failed get rehash hints\n");
1422+
return err;
1423+
}
13851424
}
13861425

1387-
err = mlxsw_sp_acl_tcam_vregion_migrate(mlxsw_sp, vregion, ctx);
1426+
err = mlxsw_sp_acl_tcam_vregion_migrate(mlxsw_sp, vregion,
1427+
ctx, credits);
13881428
if (err) {
13891429
dev_err(mlxsw_sp->bus_info->dev, "Failed to migrate vregion\n");
13901430
if (vregion->failed_rollback) {
@@ -1394,7 +1434,9 @@ mlxsw_sp_acl_tcam_vregion_rehash(struct mlxsw_sp *mlxsw_sp,
13941434
}
13951435
}
13961436

1397-
mlxsw_sp_acl_tcam_vregion_rehash_end(mlxsw_sp, vregion, ctx);
1437+
if (*credits >= 0)
1438+
mlxsw_sp_acl_tcam_vregion_rehash_end(mlxsw_sp, vregion, ctx);
1439+
13981440
return err;
13991441
}
14001442

0 commit comments

Comments
 (0)