Commit 0487cfba authored by Nir Dotan's avatar Nir Dotan Committed by David S. Miller
Browse files

mlxsw: spectrum_acl: Introduce Bloom filter



Lay the foundations for Bloom filter handling. Introduce a new file for
Bloom filter actions.

Add struct mlxsw_sp_acl_bf to struct mlxsw_sp_acl_erp_core and initialize
the Bloom filter data structure. Also take care of proper destruction when
terminating.

Signed-off-by: default avatarNir Dotan <nird@mellanox.com>
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 94406858
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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 \
+42 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
/* Copyright (c) 2018 Mellanox Technologies. All rights reserved */

#include <linux/errno.h>
#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/refcount.h>

#include "spectrum.h"
#include "spectrum_acl_tcam.h"

struct mlxsw_sp_acl_bf {
	unsigned int bank_size;
	refcount_t refcnt[0];
};

struct mlxsw_sp_acl_bf *
mlxsw_sp_acl_bf_init(struct mlxsw_sp *mlxsw_sp, unsigned int num_erp_banks)
{
	struct mlxsw_sp_acl_bf *bf;
	unsigned int bf_bank_size;

	if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, ACL_MAX_BF_LOG))
		return ERR_PTR(-EIO);

	/* Bloom filter size per erp_table_bank
	 * is 2^ACL_MAX_BF_LOG
	 */
	bf_bank_size = 1 << MLXSW_CORE_RES_GET(mlxsw_sp->core, ACL_MAX_BF_LOG);
	bf = kzalloc(sizeof(*bf) + bf_bank_size * num_erp_banks *
		     sizeof(*bf->refcnt), GFP_KERNEL);
	if (!bf)
		return ERR_PTR(-ENOMEM);

	bf->bank_size = bf_bank_size;
	return bf;
}

void mlxsw_sp_acl_bf_fini(struct mlxsw_sp_acl_bf *bf)
{
	kfree(bf);
}
+10 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ struct mlxsw_sp_acl_erp_core {
	unsigned int erpt_entries_size[MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX + 1];
	struct gen_pool *erp_tables;
	struct mlxsw_sp *mlxsw_sp;
	struct mlxsw_sp_acl_bf *bf;
	unsigned int num_erp_banks;
};

@@ -1320,6 +1321,12 @@ static int mlxsw_sp_acl_erp_tables_init(struct mlxsw_sp *mlxsw_sp,
	if (err)
		goto err_gen_pool_add;

	erp_core->bf = mlxsw_sp_acl_bf_init(mlxsw_sp, erp_core->num_erp_banks);
	if (IS_ERR(erp_core->bf)) {
		err = PTR_ERR(erp_core->bf);
		goto err_bf_init;
	}

	/* Different regions require masks of different sizes */
	err = mlxsw_sp_acl_erp_tables_sizes_query(mlxsw_sp, erp_core);
	if (err)
@@ -1328,6 +1335,8 @@ static int mlxsw_sp_acl_erp_tables_init(struct mlxsw_sp *mlxsw_sp,
	return 0;

err_erp_tables_sizes_query:
	mlxsw_sp_acl_bf_fini(erp_core->bf);
err_bf_init:
err_gen_pool_add:
	gen_pool_destroy(erp_core->erp_tables);
	return err;
@@ -1336,6 +1345,7 @@ static int mlxsw_sp_acl_erp_tables_init(struct mlxsw_sp *mlxsw_sp,
static void mlxsw_sp_acl_erp_tables_fini(struct mlxsw_sp *mlxsw_sp,
					 struct mlxsw_sp_acl_erp_core *erp_core)
{
	mlxsw_sp_acl_bf_fini(erp_core->bf);
	gen_pool_destroy(erp_core->erp_tables);
}

+6 −0
Original line number Diff line number Diff line
@@ -258,4 +258,10 @@ int mlxsw_sp_acl_erps_init(struct mlxsw_sp *mlxsw_sp,
void mlxsw_sp_acl_erps_fini(struct mlxsw_sp *mlxsw_sp,
			    struct mlxsw_sp_acl_atcam *atcam);

struct mlxsw_sp_acl_bf;

struct mlxsw_sp_acl_bf *
mlxsw_sp_acl_bf_init(struct mlxsw_sp *mlxsw_sp, unsigned int num_erp_banks);
void mlxsw_sp_acl_bf_fini(struct mlxsw_sp_acl_bf *bf);

#endif