Skip to content

Commit fbd15f4

Browse files
committed
Merge branch 'mlxsw-Add-support-for-non-equal-cost-multi-path'
Jiri Pirko says: ==================== mlxsw: Add support for non-equal-cost multi-path Ido says: In the device, nexthops are stored as adjacency entries in an array called the KVD linear (KVDL). When a multi-path route is hit the packet's headers are hashed and then converted to an index into KVDL based on the adjacency group's size and base index. Up until now the driver ignored the `weight` parameter for multi-path routes and allocated only one adjacency entry for each nexthop with a limit of 32 nexthops in a group. This set makes the driver take the `weight` parameter into account when allocating adjacency entries. First patch teaches dpipe to show the size of the adjacency group, so that users will be able to determine the actual weight of each nexthop. The second patch refactors the KVDL allocator, making it more receptive towards the addition of another partition later in the set. Patches 3-5 introduce small changes towards the actual change in the sixth patch that populates the adjacency entries according to their relative weight. Last two patches finally add another partition to the KVDL, which allows us to allocate more than 32 entries per-group and thus support more nexthops and also provide higher accuracy with regards to the requested weights. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents bc9db41 + 330e2cc commit fbd15f4

File tree

6 files changed

+484
-61
lines changed

6 files changed

+484
-61
lines changed

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3726,10 +3726,16 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
37263726
return err;
37273727
}
37283728

3729+
err = mlxsw_sp_kvdl_init(mlxsw_sp);
3730+
if (err) {
3731+
dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize KVDL\n");
3732+
return err;
3733+
}
3734+
37293735
err = mlxsw_sp_fids_init(mlxsw_sp);
37303736
if (err) {
37313737
dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize FIDs\n");
3732-
return err;
3738+
goto err_fids_init;
37333739
}
37343740

37353741
err = mlxsw_sp_traps_init(mlxsw_sp);
@@ -3834,6 +3840,8 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
38343840
mlxsw_sp_traps_fini(mlxsw_sp);
38353841
err_traps_init:
38363842
mlxsw_sp_fids_fini(mlxsw_sp);
3843+
err_fids_init:
3844+
mlxsw_sp_kvdl_fini(mlxsw_sp);
38373845
return err;
38383846
}
38393847

@@ -3854,6 +3862,7 @@ static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core)
38543862
mlxsw_sp_buffers_fini(mlxsw_sp);
38553863
mlxsw_sp_traps_fini(mlxsw_sp);
38563864
mlxsw_sp_fids_fini(mlxsw_sp);
3865+
mlxsw_sp_kvdl_fini(mlxsw_sp);
38573866
}
38583867

38593868
static const struct mlxsw_config_profile mlxsw_sp_config_profile = {
@@ -3876,8 +3885,8 @@ static const struct mlxsw_config_profile mlxsw_sp_config_profile = {
38763885
.max_pkey = 0,
38773886
.used_kvd_split_data = 1,
38783887
.kvd_hash_granularity = MLXSW_SP_KVD_GRANULARITY,
3879-
.kvd_hash_single_parts = 2,
3880-
.kvd_hash_double_parts = 1,
3888+
.kvd_hash_single_parts = 59,
3889+
.kvd_hash_double_parts = 41,
38813890
.kvd_linear_size = MLXSW_SP_KVD_LINEAR_SIZE,
38823891
.swid_config = {
38833892
{

drivers/net/ethernet/mellanox/mlxsw/spectrum.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262

6363
#define MLXSW_SP_PORT_BASE_SPEED 25000 /* Mb/s */
6464

65-
#define MLXSW_SP_KVD_LINEAR_SIZE 65536 /* entries */
65+
#define MLXSW_SP_KVD_LINEAR_SIZE 98304 /* entries */
6666
#define MLXSW_SP_KVD_GRANULARITY 128
6767

6868
struct mlxsw_sp_port;
@@ -143,6 +143,7 @@ struct mlxsw_sp_mr;
143143
struct mlxsw_sp_acl;
144144
struct mlxsw_sp_counter_pool;
145145
struct mlxsw_sp_fid_core;
146+
struct mlxsw_sp_kvdl;
146147

147148
struct mlxsw_sp {
148149
struct mlxsw_sp_port **ports;
@@ -158,9 +159,7 @@ struct mlxsw_sp {
158159
struct mlxsw_afa *afa;
159160
struct mlxsw_sp_acl *acl;
160161
struct mlxsw_sp_fid_core *fid_core;
161-
struct {
162-
DECLARE_BITMAP(usage, MLXSW_SP_KVD_LINEAR_SIZE);
163-
} kvdl;
162+
struct mlxsw_sp_kvdl *kvdl;
164163
struct notifier_block netdevice_nb;
165164

166165
struct mlxsw_sp_counter_pool *counter_pool;
@@ -411,9 +410,14 @@ mlxsw_sp_port_vlan_router_leave(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan);
411410
void mlxsw_sp_rif_destroy(struct mlxsw_sp_rif *rif);
412411

413412
/* spectrum_kvdl.c */
413+
int mlxsw_sp_kvdl_init(struct mlxsw_sp *mlxsw_sp);
414+
void mlxsw_sp_kvdl_fini(struct mlxsw_sp *mlxsw_sp);
414415
int mlxsw_sp_kvdl_alloc(struct mlxsw_sp *mlxsw_sp, unsigned int entry_count,
415416
u32 *p_entry_index);
416417
void mlxsw_sp_kvdl_free(struct mlxsw_sp *mlxsw_sp, int entry_index);
418+
int mlxsw_sp_kvdl_alloc_size_query(struct mlxsw_sp *mlxsw_sp,
419+
unsigned int entry_count,
420+
unsigned int *p_alloc_size);
417421

418422
struct mlxsw_sp_acl_rule_info {
419423
unsigned int priority;

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

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ enum mlxsw_sp_field_metadata_id {
4444
MLXSW_SP_DPIPE_FIELD_METADATA_L3_FORWARD,
4545
MLXSW_SP_DPIPE_FIELD_METADATA_L3_DROP,
4646
MLXSW_SP_DPIPE_FIELD_METADATA_ADJ_INDEX,
47+
MLXSW_SP_DPIPE_FIELD_METADATA_ADJ_SIZE,
4748
MLXSW_SP_DPIPE_FIELD_METADATA_ADJ_HASH_INDEX,
4849
};
4950

@@ -69,6 +70,11 @@ static struct devlink_dpipe_field mlxsw_sp_dpipe_fields_metadata[] = {
6970
.id = MLXSW_SP_DPIPE_FIELD_METADATA_ADJ_INDEX,
7071
.bitwidth = 32,
7172
},
73+
{
74+
.name = "adj_size",
75+
.id = MLXSW_SP_DPIPE_FIELD_METADATA_ADJ_SIZE,
76+
.bitwidth = 32,
77+
},
7278
{
7379
.name = "adj_hash_index",
7480
.id = MLXSW_SP_DPIPE_FIELD_METADATA_ADJ_HASH_INDEX,
@@ -851,6 +857,14 @@ static int mlxsw_sp_dpipe_table_adj_matches_dump(void *priv,
851857
match.header = &mlxsw_sp_dpipe_header_metadata;
852858
match.field_id = MLXSW_SP_DPIPE_FIELD_METADATA_ADJ_INDEX;
853859

860+
err = devlink_dpipe_match_put(skb, &match);
861+
if (err)
862+
return err;
863+
864+
match.type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
865+
match.header = &mlxsw_sp_dpipe_header_metadata;
866+
match.field_id = MLXSW_SP_DPIPE_FIELD_METADATA_ADJ_SIZE;
867+
854868
err = devlink_dpipe_match_put(skb, &match);
855869
if (err)
856870
return err;
@@ -897,6 +911,7 @@ static u64 mlxsw_sp_dpipe_table_adj_size(struct mlxsw_sp *mlxsw_sp)
897911

898912
enum mlxsw_sp_dpipe_table_adj_match {
899913
MLXSW_SP_DPIPE_TABLE_ADJ_MATCH_INDEX,
914+
MLXSW_SP_DPIPE_TABLE_ADJ_MATCH_SIZE,
900915
MLXSW_SP_DPIPE_TABLE_ADJ_MATCH_HASH_INDEX,
901916
MLXSW_SP_DPIPE_TABLE_ADJ_MATCH_COUNT,
902917
};
@@ -919,6 +934,11 @@ mlxsw_sp_dpipe_table_adj_match_action_prepare(struct devlink_dpipe_match *matche
919934
match->header = &mlxsw_sp_dpipe_header_metadata;
920935
match->field_id = MLXSW_SP_DPIPE_FIELD_METADATA_ADJ_INDEX;
921936

937+
match = &matches[MLXSW_SP_DPIPE_TABLE_ADJ_MATCH_SIZE];
938+
match->type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
939+
match->header = &mlxsw_sp_dpipe_header_metadata;
940+
match->field_id = MLXSW_SP_DPIPE_FIELD_METADATA_ADJ_SIZE;
941+
922942
match = &matches[MLXSW_SP_DPIPE_TABLE_ADJ_MATCH_HASH_INDEX];
923943
match->type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
924944
match->header = &mlxsw_sp_dpipe_header_metadata;
@@ -955,6 +975,15 @@ mlxsw_sp_dpipe_table_adj_entry_prepare(struct devlink_dpipe_entry *entry,
955975
match = &matches[MLXSW_SP_DPIPE_TABLE_ADJ_MATCH_INDEX];
956976
match_value = &match_values[MLXSW_SP_DPIPE_TABLE_ADJ_MATCH_INDEX];
957977

978+
match_value->match = match;
979+
match_value->value_size = sizeof(u32);
980+
match_value->value = kmalloc(match_value->value_size, GFP_KERNEL);
981+
if (!match_value->value)
982+
return -ENOMEM;
983+
984+
match = &matches[MLXSW_SP_DPIPE_TABLE_ADJ_MATCH_SIZE];
985+
match_value = &match_values[MLXSW_SP_DPIPE_TABLE_ADJ_MATCH_SIZE];
986+
958987
match_value->match = match;
959988
match_value->value_size = sizeof(u32);
960989
match_value->value = kmalloc(match_value->value_size, GFP_KERNEL);
@@ -993,8 +1022,8 @@ mlxsw_sp_dpipe_table_adj_entry_prepare(struct devlink_dpipe_entry *entry,
9931022

9941023
static void
9951024
__mlxsw_sp_dpipe_table_adj_entry_fill(struct devlink_dpipe_entry *entry,
996-
u32 adj_index, u32 adj_hash_index,
997-
unsigned char *ha,
1025+
u32 adj_index, u32 adj_size,
1026+
u32 adj_hash_index, unsigned char *ha,
9981027
struct mlxsw_sp_rif *rif)
9991028
{
10001029
struct devlink_dpipe_value *value;
@@ -1005,6 +1034,10 @@ __mlxsw_sp_dpipe_table_adj_entry_fill(struct devlink_dpipe_entry *entry,
10051034
p_index = value->value;
10061035
*p_index = adj_index;
10071036

1037+
value = &entry->match_values[MLXSW_SP_DPIPE_TABLE_ADJ_MATCH_SIZE];
1038+
p_index = value->value;
1039+
*p_index = adj_size;
1040+
10081041
value = &entry->match_values[MLXSW_SP_DPIPE_TABLE_ADJ_MATCH_HASH_INDEX];
10091042
p_index = value->value;
10101043
*p_index = adj_hash_index;
@@ -1027,10 +1060,11 @@ static void mlxsw_sp_dpipe_table_adj_entry_fill(struct mlxsw_sp *mlxsw_sp,
10271060
unsigned char *ha = mlxsw_sp_nexthop_ha(nh);
10281061
u32 adj_hash_index = 0;
10291062
u32 adj_index = 0;
1063+
u32 adj_size = 0;
10301064
int err;
10311065

1032-
mlxsw_sp_nexthop_indexes(nh, &adj_index, &adj_hash_index);
1033-
__mlxsw_sp_dpipe_table_adj_entry_fill(entry, adj_index,
1066+
mlxsw_sp_nexthop_indexes(nh, &adj_index, &adj_size, &adj_hash_index);
1067+
__mlxsw_sp_dpipe_table_adj_entry_fill(entry, adj_index, adj_size,
10341068
adj_hash_index, ha, rif);
10351069
err = mlxsw_sp_nexthop_counter_get(mlxsw_sp, nh, &entry->counter);
10361070
if (!err)
@@ -1138,13 +1172,15 @@ static int mlxsw_sp_dpipe_table_adj_counters_update(void *priv, bool enable)
11381172
struct mlxsw_sp_nexthop *nh;
11391173
u32 adj_hash_index = 0;
11401174
u32 adj_index = 0;
1175+
u32 adj_size = 0;
11411176

11421177
mlxsw_sp_nexthop_for_each(nh, mlxsw_sp->router) {
11431178
if (!mlxsw_sp_nexthop_offload(nh) ||
11441179
mlxsw_sp_nexthop_group_has_ipip(nh))
11451180
continue;
11461181

1147-
mlxsw_sp_nexthop_indexes(nh, &adj_index, &adj_hash_index);
1182+
mlxsw_sp_nexthop_indexes(nh, &adj_index, &adj_size,
1183+
&adj_hash_index);
11481184
if (enable)
11491185
mlxsw_sp_nexthop_counter_alloc(mlxsw_sp, nh);
11501186
else

0 commit comments

Comments
 (0)