From afadc26b3aa3e94d1cedf9472889b4c32aecc6ac Mon Sep 17 00:00:00 2001 From: Arkadi Sharshevsky Date: Mon, 15 Jan 2018 08:59:09 +0100 Subject: [PATCH] mlxsw: spectrum: Add support for getting kvdl occupancy Add support for getting the kvdl occupancy through the resource interface. Signed-off-by: Arkadi Sharshevsky Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 9 ++++++++ drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 1 + .../net/ethernet/mellanox/mlxsw/spectrum_kvdl.c | 26 ++++++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index 53b16ddc6acc..87f8a74118d9 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c @@ -4055,12 +4055,21 @@ mlxsw_sp_resource_kvd_hash_double_size_validate(struct devlink *devlink, u64 siz return 0; } +static u64 mlxsw_sp_resource_kvd_linear_occ_get(struct devlink *devlink) +{ + struct mlxsw_core *mlxsw_core = devlink_priv(devlink); + struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); + + return mlxsw_sp_kvdl_occ_get(mlxsw_sp); +} + static struct devlink_resource_ops mlxsw_sp_resource_kvd_ops = { .size_validate = mlxsw_sp_resource_kvd_size_validate, }; static struct devlink_resource_ops mlxsw_sp_resource_kvd_linear_ops = { .size_validate = mlxsw_sp_resource_kvd_linear_size_validate, + .occ_get = mlxsw_sp_resource_kvd_linear_occ_get, }; static struct devlink_resource_ops mlxsw_sp_resource_kvd_hash_single_ops = { diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h index 435e0f2225f6..237cad373dbe 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h @@ -448,6 +448,7 @@ void mlxsw_sp_kvdl_free(struct mlxsw_sp *mlxsw_sp, int entry_index); int mlxsw_sp_kvdl_alloc_size_query(struct mlxsw_sp *mlxsw_sp, unsigned int entry_count, unsigned int *p_alloc_size); +u64 mlxsw_sp_kvdl_occ_get(const struct mlxsw_sp *mlxsw_sp); struct mlxsw_sp_acl_rule_info { unsigned int priority; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_kvdl.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_kvdl.c index 310c38247b5c..cfacc176a1bd 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_kvdl.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_kvdl.c @@ -286,6 +286,32 @@ static void mlxsw_sp_kvdl_parts_fini(struct mlxsw_sp *mlxsw_sp) mlxsw_sp_kvdl_part_fini(mlxsw_sp, i); } +u64 mlxsw_sp_kvdl_part_occ(struct mlxsw_sp_kvdl_part *part) +{ + unsigned int nr_entries; + int bit = -1; + u64 occ = 0; + + nr_entries = (part->info->end_index - + part->info->start_index + 1) / + part->info->alloc_size; + while ((bit = find_next_bit(part->usage, nr_entries, bit + 1)) + < nr_entries) + occ += part->info->alloc_size; + return occ; +} + +u64 mlxsw_sp_kvdl_occ_get(const struct mlxsw_sp *mlxsw_sp) +{ + struct mlxsw_sp_kvdl_part *part; + u64 occ = 0; + + list_for_each_entry(part, &mlxsw_sp->kvdl->parts_list, list) + occ += mlxsw_sp_kvdl_part_occ(part); + + return occ; +} + int mlxsw_sp_kvdl_init(struct mlxsw_sp *mlxsw_sp) { struct mlxsw_sp_kvdl *kvdl; -- 2.11.0