Skip to content

Commit

Permalink
mlxsw: spectrum_cnt: Expose subpool sizes over devlink resources
Browse files Browse the repository at this point in the history
Implement devlink resources support for counter pools. Move the subpool
sizes calculations into the new resources register function.

Signed-off-by: Jiri Pirko <[email protected]>
Signed-off-by: Ido Schimmel <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
jpirko authored and davem330 committed Mar 18, 2020
1 parent b2d3e33 commit d53cdbb
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 17 deletions.
10 changes: 10 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum.c
Original file line number Diff line number Diff line change
Expand Up @@ -5421,8 +5421,13 @@ static int mlxsw_sp1_resources_register(struct mlxsw_core *mlxsw_core)
if (err)
goto err_resources_span_register;

err = mlxsw_sp_counter_resources_register(mlxsw_core);
if (err)
goto err_resources_counter_register;

return 0;

err_resources_counter_register:
err_resources_span_register:
devlink_resources_unregister(priv_to_devlink(mlxsw_core), NULL);
return err;
Expand All @@ -5440,8 +5445,13 @@ static int mlxsw_sp2_resources_register(struct mlxsw_core *mlxsw_core)
if (err)
goto err_resources_span_register;

err = mlxsw_sp_counter_resources_register(mlxsw_core);
if (err)
goto err_resources_counter_register;

return 0;

err_resources_counter_register:
err_resources_span_register:
devlink_resources_unregister(priv_to_devlink(mlxsw_core), NULL);
return err;
Expand Down
7 changes: 7 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@

#define MLXSW_SP_RESOURCE_NAME_SPAN "span_agents"

#define MLXSW_SP_RESOURCE_NAME_COUNTERS "counters"
#define MLXSW_SP_RESOURCE_NAME_COUNTERS_FLOW "flow"
#define MLXSW_SP_RESOURCE_NAME_COUNTERS_RIF "rif"

enum mlxsw_sp_resource_id {
MLXSW_SP_RESOURCE_KVD = 1,
MLXSW_SP_RESOURCE_KVD_LINEAR,
Expand All @@ -55,6 +59,9 @@ enum mlxsw_sp_resource_id {
MLXSW_SP_RESOURCE_KVD_LINEAR_CHUNKS,
MLXSW_SP_RESOURCE_KVD_LINEAR_LARGE_CHUNKS,
MLXSW_SP_RESOURCE_SPAN,
MLXSW_SP_RESOURCE_COUNTERS,
MLXSW_SP_RESOURCE_COUNTERS_FLOW,
MLXSW_SP_RESOURCE_COUNTERS_RIF,
};

struct mlxsw_sp_port;
Expand Down
99 changes: 82 additions & 17 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,17 @@
#include "spectrum_cnt.h"

struct mlxsw_sp_counter_sub_pool {
u64 size;
unsigned int base_index;
unsigned int size;
enum mlxsw_res_id entry_size_res_id;
const char *resource_name; /* devlink resource name */
u64 resource_id; /* devlink resource id */
unsigned int entry_size;
unsigned int bank_count;
};

struct mlxsw_sp_counter_pool {
unsigned int pool_size;
u64 pool_size;
unsigned long *usage; /* Usage bitmap */
spinlock_t counter_pool_lock; /* Protects counter pool allocations */
unsigned int sub_pools_count;
Expand All @@ -26,10 +28,14 @@ struct mlxsw_sp_counter_pool {
static const struct mlxsw_sp_counter_sub_pool mlxsw_sp_counter_sub_pools[] = {
[MLXSW_SP_COUNTER_SUB_POOL_FLOW] = {
.entry_size_res_id = MLXSW_RES_ID_COUNTER_SIZE_PACKETS_BYTES,
.resource_name = MLXSW_SP_RESOURCE_NAME_COUNTERS_FLOW,
.resource_id = MLXSW_SP_RESOURCE_COUNTERS_FLOW,
.bank_count = 6,
},
[MLXSW_SP_COUNTER_SUB_POOL_RIF] = {
.entry_size_res_id = MLXSW_RES_ID_COUNTER_SIZE_ROUTER_BASIC,
.resource_name = MLXSW_SP_RESOURCE_NAME_COUNTERS_RIF,
.resource_id = MLXSW_SP_RESOURCE_COUNTERS_RIF,
.bank_count = 2,
}
};
Expand Down Expand Up @@ -74,18 +80,14 @@ static int mlxsw_sp_counter_sub_pools_prepare(struct mlxsw_sp *mlxsw_sp)
int mlxsw_sp_counter_pool_init(struct mlxsw_sp *mlxsw_sp)
{
unsigned int sub_pools_count = ARRAY_SIZE(mlxsw_sp_counter_sub_pools);
struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
struct mlxsw_sp_counter_sub_pool *sub_pool;
struct mlxsw_sp_counter_pool *pool;
unsigned int base_index;
unsigned int bank_size;
unsigned int map_size;
int i;
int err;

if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, COUNTER_POOL_SIZE) ||
!MLXSW_CORE_RES_VALID(mlxsw_sp->core, COUNTER_BANK_SIZE))
return -EIO;

pool = kzalloc(struct_size(pool, sub_pools, sub_pools_count),
GFP_KERNEL);
if (!pool)
Expand All @@ -104,34 +106,39 @@ int mlxsw_sp_counter_pool_init(struct mlxsw_sp *mlxsw_sp)
if (err)
goto err_sub_pools_prepare;

pool->pool_size = MLXSW_CORE_RES_GET(mlxsw_sp->core, COUNTER_POOL_SIZE);
map_size = BITS_TO_LONGS(pool->pool_size) * sizeof(unsigned long);
err = devlink_resource_size_get(devlink, MLXSW_SP_RESOURCE_COUNTERS,
&pool->pool_size);
if (err)
goto err_pool_resource_size_get;

bank_size = MLXSW_CORE_RES_GET(mlxsw_sp->core, COUNTER_BANK_SIZE);
map_size = BITS_TO_LONGS(pool->pool_size) * sizeof(unsigned long);

pool->usage = kzalloc(map_size, GFP_KERNEL);
if (!pool->usage) {
err = -ENOMEM;
goto err_usage_alloc;
}

/* Allocation is based on bank count which should be
* specified for each sub pool statically.
*/
base_index = 0;
for (i = 0; i < pool->sub_pools_count; i++) {
sub_pool = &pool->sub_pools[i];
sub_pool->size = sub_pool->bank_count * bank_size;

err = devlink_resource_size_get(devlink,
sub_pool->resource_id,
&sub_pool->size);
if (err)
goto err_sub_pool_resource_size_get;

sub_pool->base_index = base_index;
base_index += sub_pool->size;
/* The last bank can't be fully used */
if (sub_pool->base_index + sub_pool->size > pool->pool_size)
sub_pool->size = pool->pool_size - sub_pool->base_index;
}

return 0;

err_sub_pool_resource_size_get:
kfree(pool->usage);
err_usage_alloc:
err_pool_resource_size_get:
err_sub_pools_prepare:
err_pool_validate:
kfree(pool);
Expand Down Expand Up @@ -203,3 +210,61 @@ void mlxsw_sp_counter_free(struct mlxsw_sp *mlxsw_sp,
__clear_bit(counter_index + i, pool->usage);
spin_unlock(&pool->counter_pool_lock);
}

int mlxsw_sp_counter_resources_register(struct mlxsw_core *mlxsw_core)
{
static struct devlink_resource_size_params size_params;
struct devlink *devlink = priv_to_devlink(mlxsw_core);
const struct mlxsw_sp_counter_sub_pool *sub_pool;
u64 sub_pool_size;
u64 base_index;
u64 pool_size;
u64 bank_size;
int err;
int i;

if (!MLXSW_CORE_RES_VALID(mlxsw_core, COUNTER_POOL_SIZE) ||
!MLXSW_CORE_RES_VALID(mlxsw_core, COUNTER_BANK_SIZE))
return -EIO;

pool_size = MLXSW_CORE_RES_GET(mlxsw_core, COUNTER_POOL_SIZE);
bank_size = MLXSW_CORE_RES_GET(mlxsw_core, COUNTER_BANK_SIZE);

devlink_resource_size_params_init(&size_params, pool_size,
pool_size, bank_size,
DEVLINK_RESOURCE_UNIT_ENTRY);
err = devlink_resource_register(devlink,
MLXSW_SP_RESOURCE_NAME_COUNTERS,
pool_size,
MLXSW_SP_RESOURCE_COUNTERS,
DEVLINK_RESOURCE_ID_PARENT_TOP,
&size_params);
if (err)
return err;

/* Allocation is based on bank count which should be
* specified for each sub pool statically.
*/
base_index = 0;
for (i = 0; i < ARRAY_SIZE(mlxsw_sp_counter_sub_pools); i++) {
sub_pool = &mlxsw_sp_counter_sub_pools[i];
sub_pool_size = sub_pool->bank_count * bank_size;
/* The last bank can't be fully used */
if (base_index + sub_pool_size > pool_size)
sub_pool_size = pool_size - base_index;
base_index += sub_pool_size;

devlink_resource_size_params_init(&size_params, sub_pool_size,
sub_pool_size, bank_size,
DEVLINK_RESOURCE_UNIT_ENTRY);
err = devlink_resource_register(devlink,
sub_pool->resource_name,
sub_pool_size,
sub_pool->resource_id,
MLXSW_SP_RESOURCE_COUNTERS,
&size_params);
if (err)
return err;
}
return 0;
}
2 changes: 2 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#ifndef _MLXSW_SPECTRUM_CNT_H
#define _MLXSW_SPECTRUM_CNT_H

#include "core.h"
#include "spectrum.h"

enum mlxsw_sp_counter_sub_pool_id {
Expand All @@ -19,5 +20,6 @@ void mlxsw_sp_counter_free(struct mlxsw_sp *mlxsw_sp,
unsigned int counter_index);
int mlxsw_sp_counter_pool_init(struct mlxsw_sp *mlxsw_sp);
void mlxsw_sp_counter_pool_fini(struct mlxsw_sp *mlxsw_sp);
int mlxsw_sp_counter_resources_register(struct mlxsw_core *mlxsw_core);

#endif

0 comments on commit d53cdbb

Please sign in to comment.