Skip to content

Commit

Permalink
Merge branch 'mlxsw-spectrum_acl-Add-Bloom-filter-support'
Browse files Browse the repository at this point in the history
Ido Schimmel says:

====================
mlxsw: spectrum_acl: Add Bloom filter support

Nir says:

Spectrum-2 uses Bloom filter to reduce the number of lookups in the
algorithmic TCAM (A-TCAM). HW performs multiple exact match lookups in a
given region using a key composed of { packet & mask, mask ID, region ID }.
The masks which are used in a region are called rule patterns or RP.
When such multiple masks are used, the A-TCAM region uses an eRP
(extended RP) table that describes which rule patterns are in use and
defines the order of the lookup. When eRP table is used in a region, one
way to reduce the number of the lookups is to consult a Bloom filter
before doing the lookup.

A Bloom filter is a space-efficient probabilistic data structure, on
which a query returns either "possibly in set" or "definitely not in
set". HW can skip a lookup if a query on the Bloom filter results a
"definitely not set" response. The mlxsw driver implements a "counting
filter" and when either a new entry is marked or the last entry is
removed it will update the HW. Update of this counting filter occurs
when rule is configured or deleted from a region.

Patch #1 adds PEABFE register which is used for setting Bloom filter
entries.

Patch #2 adds Bloom filter resources.

Patch #3 and patch #4 provide Bloom filter handling within mlxsw, by
adding initialization and logic for updating the Bloom bit vector in HW.

Patch #5 and patch #6 add required calls for Bloom filter update as part
of rule configuration flow.

Patch #7 handles transitions to and from eRP table. It uses a list to
keep A-TCAM rules in order to update rules in Bloom filter, in cases of
transitions from master mask based A-TCAM region to an eRP table based
region and vice versa.

Patch #8 removes a trick done on master RP index to a remaining RP,
since Bloom filter is updated on eRP transitions.

Finally, patch #9 activates Bloom filter mechanism in HW, by cancelling
the bypass that was configured before and the remaining three patches
are selftests that exercise the new code.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Dec 16, 2018
2 parents 0634d69 + 5d06a76 commit ae6750e
Show file tree
Hide file tree
Showing 8 changed files with 661 additions and 9 deletions.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/mellanox/mlxsw/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ mlxsw_spectrum-objs := spectrum.o spectrum_buffers.o \
spectrum_acl_tcam.o spectrum_acl_ctcam.o \
spectrum_acl_atcam.o spectrum_acl_erp.o \
spectrum1_acl_tcam.o spectrum2_acl_tcam.o \
spectrum_acl.o \
spectrum_acl_bloom_filter.o spectrum_acl.o \
spectrum_flower.o spectrum_cnt.o \
spectrum_fid.o spectrum_ipip.o \
spectrum_acl_flex_actions.o \
Expand Down
71 changes: 69 additions & 2 deletions drivers/net/ethernet/mellanox/mlxsw/reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -2743,7 +2743,7 @@ mlxsw_reg_perpt_pack(char *payload, u8 erpt_bank, u8 erpt_index,
mlxsw_reg_perpt_erpt_bank_set(payload, erpt_bank);
mlxsw_reg_perpt_erpt_index_set(payload, erpt_index);
mlxsw_reg_perpt_key_size_set(payload, key_size);
mlxsw_reg_perpt_bf_bypass_set(payload, true);
mlxsw_reg_perpt_bf_bypass_set(payload, false);
mlxsw_reg_perpt_erp_id_set(payload, erp_id);
mlxsw_reg_perpt_erpt_base_bank_set(payload, erpt_base_bank);
mlxsw_reg_perpt_erpt_base_index_set(payload, erpt_base_index);
Expand Down Expand Up @@ -3006,7 +3006,7 @@ static inline void mlxsw_reg_percr_pack(char *payload, u16 region_id)
mlxsw_reg_percr_region_id_set(payload, region_id);
mlxsw_reg_percr_atcam_ignore_prune_set(payload, false);
mlxsw_reg_percr_ctcam_ignore_prune_set(payload, false);
mlxsw_reg_percr_bf_bypass_set(payload, true);
mlxsw_reg_percr_bf_bypass_set(payload, false);
}

/* PERERP - Policy-Engine Region eRP Register
Expand Down Expand Up @@ -3095,6 +3095,72 @@ static inline void mlxsw_reg_pererp_pack(char *payload, u16 region_id,
mlxsw_reg_pererp_master_rp_id_set(payload, master_rp_id);
}

/* PEABFE - Policy-Engine Algorithmic Bloom Filter Entries Register
* ----------------------------------------------------------------
* This register configures the Bloom filter entries.
*/
#define MLXSW_REG_PEABFE_ID 0x3022
#define MLXSW_REG_PEABFE_BASE_LEN 0x10
#define MLXSW_REG_PEABFE_BF_REC_LEN 0x4
#define MLXSW_REG_PEABFE_BF_REC_MAX_COUNT 256
#define MLXSW_REG_PEABFE_LEN (MLXSW_REG_PEABFE_BASE_LEN + \
MLXSW_REG_PEABFE_BF_REC_LEN * \
MLXSW_REG_PEABFE_BF_REC_MAX_COUNT)

MLXSW_REG_DEFINE(peabfe, MLXSW_REG_PEABFE_ID, MLXSW_REG_PEABFE_LEN);

/* reg_peabfe_size
* Number of BF entries to be updated.
* Range 1..256
* Access: Op
*/
MLXSW_ITEM32(reg, peabfe, size, 0x00, 0, 9);

/* reg_peabfe_bf_entry_state
* Bloom filter state
* 0 - Clear
* 1 - Set
* Access: RW
*/
MLXSW_ITEM32_INDEXED(reg, peabfe, bf_entry_state,
MLXSW_REG_PEABFE_BASE_LEN, 31, 1,
MLXSW_REG_PEABFE_BF_REC_LEN, 0x00, false);

/* reg_peabfe_bf_entry_bank
* Bloom filter bank ID
* Range 0..cap_max_erp_table_banks-1
* Access: Index
*/
MLXSW_ITEM32_INDEXED(reg, peabfe, bf_entry_bank,
MLXSW_REG_PEABFE_BASE_LEN, 24, 4,
MLXSW_REG_PEABFE_BF_REC_LEN, 0x00, false);

/* reg_peabfe_bf_entry_index
* Bloom filter entry index
* Range 0..2^cap_max_bf_log-1
* Access: Index
*/
MLXSW_ITEM32_INDEXED(reg, peabfe, bf_entry_index,
MLXSW_REG_PEABFE_BASE_LEN, 0, 24,
MLXSW_REG_PEABFE_BF_REC_LEN, 0x00, false);

static inline void mlxsw_reg_peabfe_pack(char *payload)
{
MLXSW_REG_ZERO(peabfe, payload);
}

static inline void mlxsw_reg_peabfe_rec_pack(char *payload, int rec_index,
u8 state, u8 bank, u32 bf_index)
{
u8 num_rec = mlxsw_reg_peabfe_size_get(payload);

if (rec_index >= num_rec)
mlxsw_reg_peabfe_size_set(payload, rec_index + 1);
mlxsw_reg_peabfe_bf_entry_state_set(payload, rec_index, state);
mlxsw_reg_peabfe_bf_entry_bank_set(payload, rec_index, bank);
mlxsw_reg_peabfe_bf_entry_index_set(payload, rec_index, bf_index);
}

/* IEDR - Infrastructure Entry Delete Register
* ----------------------------------------------------
* This register is used for deleting entries from the entry tables.
Expand Down Expand Up @@ -9608,6 +9674,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
MLXSW_REG(pemrbt),
MLXSW_REG(ptce2),
MLXSW_REG(perpt),
MLXSW_REG(peabfe),
MLXSW_REG(perar),
MLXSW_REG(ptce3),
MLXSW_REG(percr),
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/resources.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ enum mlxsw_res_id {
MLXSW_RES_ID_ACL_ERPT_ENTRIES_4KB,
MLXSW_RES_ID_ACL_ERPT_ENTRIES_8KB,
MLXSW_RES_ID_ACL_ERPT_ENTRIES_12KB,
MLXSW_RES_ID_ACL_MAX_BF_LOG,
MLXSW_RES_ID_MAX_CPU_POLICERS,
MLXSW_RES_ID_MAX_VRS,
MLXSW_RES_ID_MAX_RIFS,
Expand Down Expand Up @@ -93,6 +94,7 @@ static u16 mlxsw_res_ids[] = {
[MLXSW_RES_ID_ACL_ERPT_ENTRIES_4KB] = 0x2951,
[MLXSW_RES_ID_ACL_ERPT_ENTRIES_8KB] = 0x2952,
[MLXSW_RES_ID_ACL_ERPT_ENTRIES_12KB] = 0x2953,
[MLXSW_RES_ID_ACL_MAX_BF_LOG] = 0x2960,
[MLXSW_RES_ID_MAX_CPU_POLICERS] = 0x2A13,
[MLXSW_RES_ID_MAX_VRS] = 0x2C01,
[MLXSW_RES_ID_MAX_RIFS] = 0x2C02,
Expand Down
20 changes: 20 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
*/
Expand All @@ -508,6 +516,13 @@ __mlxsw_sp_acl_atcam_entry_add(struct mlxsw_sp *mlxsw_sp,
if (err)
goto err_rhashtable_insert;

/* Bloom filter must be updated here, before inserting the rule into
* the A-TCAM.
*/
err = mlxsw_sp_acl_erp_bf_insert(mlxsw_sp, aregion, erp_mask, aentry);
if (err)
goto err_bf_insert;

err = mlxsw_sp_acl_atcam_region_entry_insert(mlxsw_sp, aregion, aentry,
rulei);
if (err)
Expand All @@ -516,9 +531,12 @@ __mlxsw_sp_acl_atcam_entry_add(struct mlxsw_sp *mlxsw_sp,
return 0;

err_rule_insert:
mlxsw_sp_acl_erp_bf_remove(mlxsw_sp, aregion, erp_mask, aentry);
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;
}
Expand All @@ -529,8 +547,10 @@ __mlxsw_sp_acl_atcam_entry_del(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_atcam_entry *aentry)
{
mlxsw_sp_acl_atcam_region_entry_remove(mlxsw_sp, aregion, aentry);
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);
}

Expand Down
Loading

0 comments on commit ae6750e

Please sign in to comment.