Skip to content

Commit 9069a38

Browse files
jpirkodavem330
authored andcommitted
lib: objagg: implement optimization hints assembly and use hints for object creation
Implement simple greedy algo to find more optimized root-delta tree for a given objagg instance. This "hints" can be used by a driver to: 1) check if the hints are better (driver's choice) than the original objagg tree. Driver does comparison of objagg stats and hints stats. 2) use the hints to create a new objagg instance which will construct the root-delta tree according to the passed hints. Currently, only a simple greedy algorithm is implemented. Basically it finds the roots according to the maximal possible user count including deltas. Signed-off-by: Jiri Pirko <[email protected]> Signed-off-by: Ido Schimmel <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent bb72e68 commit 9069a38

File tree

4 files changed

+802
-22
lines changed

4 files changed

+802
-22
lines changed

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

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,6 +1200,32 @@ mlxsw_sp_acl_erp_delta_fill(const struct mlxsw_sp_acl_erp_key *parent_key,
12001200
return 0;
12011201
}
12021202

1203+
static bool mlxsw_sp_acl_erp_delta_check(void *priv, const void *parent_obj,
1204+
const void *obj)
1205+
{
1206+
const struct mlxsw_sp_acl_erp_key *parent_key = parent_obj;
1207+
const struct mlxsw_sp_acl_erp_key *key = obj;
1208+
u16 delta_start;
1209+
u8 delta_mask;
1210+
int err;
1211+
1212+
err = mlxsw_sp_acl_erp_delta_fill(parent_key, key,
1213+
&delta_start, &delta_mask);
1214+
return err ? false : true;
1215+
}
1216+
1217+
static int mlxsw_sp_acl_erp_hints_obj_cmp(const void *obj1, const void *obj2)
1218+
{
1219+
const struct mlxsw_sp_acl_erp_key *key1 = obj1;
1220+
const struct mlxsw_sp_acl_erp_key *key2 = obj2;
1221+
1222+
/* For hints purposes, two objects are considered equal
1223+
* in case the masks are the same. Does not matter what
1224+
* the "ctcam" value is.
1225+
*/
1226+
return memcmp(key1->mask, key2->mask, sizeof(key1->mask));
1227+
}
1228+
12031229
static void *mlxsw_sp_acl_erp_delta_create(void *priv, void *parent_obj,
12041230
void *obj)
12051231
{
@@ -1254,12 +1280,17 @@ static void mlxsw_sp_acl_erp_delta_destroy(void *priv, void *delta_priv)
12541280
kfree(delta);
12551281
}
12561282

1257-
static void *mlxsw_sp_acl_erp_root_create(void *priv, void *obj)
1283+
static void *mlxsw_sp_acl_erp_root_create(void *priv, void *obj,
1284+
unsigned int root_id)
12581285
{
12591286
struct mlxsw_sp_acl_atcam_region *aregion = priv;
12601287
struct mlxsw_sp_acl_erp_table *erp_table = aregion->erp_table;
12611288
struct mlxsw_sp_acl_erp_key *key = obj;
12621289

1290+
if (!key->ctcam &&
1291+
root_id != OBJAGG_OBJ_ROOT_ID_INVALID &&
1292+
root_id >= MLXSW_SP_ACL_ERP_MAX_PER_REGION)
1293+
return ERR_PTR(-ENOBUFS);
12631294
return erp_table->ops->erp_create(erp_table, key);
12641295
}
12651296

@@ -1273,6 +1304,8 @@ static void mlxsw_sp_acl_erp_root_destroy(void *priv, void *root_priv)
12731304

12741305
static const struct objagg_ops mlxsw_sp_acl_erp_objagg_ops = {
12751306
.obj_size = sizeof(struct mlxsw_sp_acl_erp_key),
1307+
.delta_check = mlxsw_sp_acl_erp_delta_check,
1308+
.hints_obj_cmp = mlxsw_sp_acl_erp_hints_obj_cmp,
12761309
.delta_create = mlxsw_sp_acl_erp_delta_create,
12771310
.delta_destroy = mlxsw_sp_acl_erp_delta_destroy,
12781311
.root_create = mlxsw_sp_acl_erp_root_create,
@@ -1290,7 +1323,7 @@ mlxsw_sp_acl_erp_table_create(struct mlxsw_sp_acl_atcam_region *aregion)
12901323
return ERR_PTR(-ENOMEM);
12911324

12921325
erp_table->objagg = objagg_create(&mlxsw_sp_acl_erp_objagg_ops,
1293-
aregion);
1326+
NULL, aregion);
12941327
if (IS_ERR(erp_table->objagg)) {
12951328
err = PTR_ERR(erp_table->objagg);
12961329
goto err_objagg_create;

include/linux/objagg.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,28 @@
66

77
struct objagg_ops {
88
size_t obj_size;
9+
bool (*delta_check)(void *priv, const void *parent_obj,
10+
const void *obj);
11+
int (*hints_obj_cmp)(const void *obj1, const void *obj2);
912
void * (*delta_create)(void *priv, void *parent_obj, void *obj);
1013
void (*delta_destroy)(void *priv, void *delta_priv);
11-
void * (*root_create)(void *priv, void *obj);
14+
void * (*root_create)(void *priv, void *obj, unsigned int root_id);
15+
#define OBJAGG_OBJ_ROOT_ID_INVALID UINT_MAX
1216
void (*root_destroy)(void *priv, void *root_priv);
1317
};
1418

1519
struct objagg;
1620
struct objagg_obj;
21+
struct objagg_hints;
1722

1823
const void *objagg_obj_root_priv(const struct objagg_obj *objagg_obj);
1924
const void *objagg_obj_delta_priv(const struct objagg_obj *objagg_obj);
2025
const void *objagg_obj_raw(const struct objagg_obj *objagg_obj);
2126

2227
struct objagg_obj *objagg_obj_get(struct objagg *objagg, void *obj);
2328
void objagg_obj_put(struct objagg *objagg, struct objagg_obj *objagg_obj);
24-
struct objagg *objagg_create(const struct objagg_ops *ops, void *priv);
29+
struct objagg *objagg_create(const struct objagg_ops *ops,
30+
struct objagg_hints *hints, void *priv);
2531
void objagg_destroy(struct objagg *objagg);
2632

2733
struct objagg_obj_stats {
@@ -43,4 +49,14 @@ struct objagg_stats {
4349
const struct objagg_stats *objagg_stats_get(struct objagg *objagg);
4450
void objagg_stats_put(const struct objagg_stats *objagg_stats);
4551

52+
enum objagg_opt_algo_type {
53+
OBJAGG_OPT_ALGO_SIMPLE_GREEDY,
54+
};
55+
56+
struct objagg_hints *objagg_hints_get(struct objagg *objagg,
57+
enum objagg_opt_algo_type opt_algo_type);
58+
void objagg_hints_put(struct objagg_hints *objagg_hints);
59+
const struct objagg_stats *
60+
objagg_hints_stats_get(struct objagg_hints *objagg_hints);
61+
4662
#endif

0 commit comments

Comments
 (0)