diff options
author | Nir Dotan <nird@mellanox.com> | 2018-12-16 08:49:32 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-12-16 15:20:34 -0800 |
commit | 135fd957288ed5f6a4ae490373a7910b3e7f7722 (patch) | |
tree | 4268686d16a4831502e9be3aeedabdd89aa77d19 /drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c | |
parent | 8c81b7438bf6abb035ee3009394a837ac8af64a8 (diff) |
mlxsw: spectrum_acl: Update Bloom filter on eRP transitions
Bloom filter update is required only for rules which reside on an
eRP. When the region has only a single rule pattern then eRP table
is not used, however insertion of another pattern would trigger a
move to an active eRP table so it is imperative to update the Bloom
filter with all previously configured rules.
Add a method that updates Bloom filter entries for all rules
currently configured in the region, on the event of a transition
from master mask to eRP, or vice versa. For that purpose, maintain
a list of all A-TCAM rules within mlxsw_sp_acl_atcam_region.
Signed-off-by: Nir Dotan <nird@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c index aedfece86121..80fb268d51a5 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c @@ -323,6 +323,7 @@ mlxsw_sp_acl_atcam_region_init(struct mlxsw_sp *mlxsw_sp, aregion->region = region; aregion->atcam = atcam; mlxsw_sp_acl_atcam_region_type_init(aregion); + INIT_LIST_HEAD(&aregion->entries_list); err = rhashtable_init(&aregion->entries_ht, &mlxsw_sp_acl_atcam_entries_ht_params); @@ -356,6 +357,7 @@ void mlxsw_sp_acl_atcam_region_fini(struct mlxsw_sp_acl_atcam_region *aregion) mlxsw_sp_acl_erp_region_fini(aregion); aregion->ops->fini(aregion); rhashtable_destroy(&aregion->entries_ht); + WARN_ON(!list_empty(&aregion->entries_list)); } void mlxsw_sp_acl_atcam_chunk_init(struct mlxsw_sp_acl_atcam_region *aregion, @@ -499,6 +501,12 @@ __mlxsw_sp_acl_atcam_entry_add(struct mlxsw_sp *mlxsw_sp, mlxsw_sp_acl_erp_delta_value(delta, aentry->full_enc_key); mlxsw_sp_acl_erp_delta_clear(delta, aentry->ht_key.enc_key); + /* Add rule to the list of A-TCAM rules, assuming this + * rule is intended to A-TCAM. In case this rule does + * not fit into A-TCAM it will be removed from the list. + */ + list_add(&aentry->list, &aregion->entries_list); + /* We can't insert identical rules into the A-TCAM, so fail and * let the rule spill into C-TCAM */ @@ -528,6 +536,7 @@ err_bf_insert: rhashtable_remove_fast(&aregion->entries_ht, &aentry->ht_node, mlxsw_sp_acl_atcam_entries_ht_params); err_rhashtable_insert: + list_del(&aentry->list); mlxsw_sp_acl_erp_mask_put(aregion, erp_mask); return err; } @@ -541,6 +550,7 @@ __mlxsw_sp_acl_atcam_entry_del(struct mlxsw_sp *mlxsw_sp, mlxsw_sp_acl_erp_bf_remove(mlxsw_sp, aregion, aentry->erp_mask, aentry); rhashtable_remove_fast(&aregion->entries_ht, &aentry->ht_node, mlxsw_sp_acl_atcam_entries_ht_params); + list_del(&aentry->list); mlxsw_sp_acl_erp_mask_put(aregion, aentry->erp_mask); } |