* [PATCH net-next 0/2] mlxsw: spectrum_buffers: Add the ability to query the CPU port's shared buffer
@ 2019-09-12 13:07 Ido Schimmel
2019-09-12 13:07 ` [PATCH net-next 1/2] mlxsw: spectrum: Register CPU port with devlink Ido Schimmel
2019-09-12 13:07 ` [PATCH net-next 2/2] mlxsw: spectrum_buffers: Add the ability to query the CPU port's shared buffer Ido Schimmel
0 siblings, 2 replies; 6+ messages in thread
From: Ido Schimmel @ 2019-09-12 13:07 UTC (permalink / raw)
To: netdev; +Cc: davem, jiri, shalomt, mlxsw, Ido Schimmel
From: Ido Schimmel <idosch@mellanox.com>
Shalom says:
While debugging packet loss towards the CPU, it is useful to be able to
query the CPU port's shared buffer quotas and occupancy.
Patch #1 registers the CPU port with devlink.
Patch #2 adds the ability to query the CPU port's shared buffer quotas and
occupancy.
Shalom Toledo (2):
mlxsw: spectrum: Register CPU port with devlink
mlxsw: spectrum_buffers: Add the ability to query the CPU port's
shared buffer
drivers/net/ethernet/mellanox/mlxsw/core.c | 33 ++++++++++++
drivers/net/ethernet/mellanox/mlxsw/core.h | 5 ++
.../net/ethernet/mellanox/mlxsw/spectrum.c | 47 +++++++++++++++++
.../mellanox/mlxsw/spectrum_buffers.c | 51 ++++++++++++++++---
4 files changed, 128 insertions(+), 8 deletions(-)
--
2.21.0
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH net-next 1/2] mlxsw: spectrum: Register CPU port with devlink 2019-09-12 13:07 [PATCH net-next 0/2] mlxsw: spectrum_buffers: Add the ability to query the CPU port's shared buffer Ido Schimmel @ 2019-09-12 13:07 ` Ido Schimmel 2019-09-13 8:02 ` Jiri Pirko 2019-09-12 13:07 ` [PATCH net-next 2/2] mlxsw: spectrum_buffers: Add the ability to query the CPU port's shared buffer Ido Schimmel 1 sibling, 1 reply; 6+ messages in thread From: Ido Schimmel @ 2019-09-12 13:07 UTC (permalink / raw) To: netdev; +Cc: davem, jiri, shalomt, mlxsw, Ido Schimmel From: Shalom Toledo <shalomt@mellanox.com> Register CPU port with devlink. Signed-off-by: Shalom Toledo <shalomt@mellanox.com> Signed-off-by: Ido Schimmel <idosch@mellanox.com> --- drivers/net/ethernet/mellanox/mlxsw/core.c | 33 +++++++++++++ drivers/net/ethernet/mellanox/mlxsw/core.h | 5 ++ .../net/ethernet/mellanox/mlxsw/spectrum.c | 47 +++++++++++++++++++ 3 files changed, 85 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c index 963a2b4b61b1..94f83d2be17e 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core.c @@ -1892,6 +1892,39 @@ void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port) } EXPORT_SYMBOL(mlxsw_core_port_fini); +int mlxsw_core_cpu_port_init(struct mlxsw_core *mlxsw_core, + void *port_driver_priv, + const unsigned char *switch_id, + unsigned char switch_id_len) +{ + struct devlink *devlink = priv_to_devlink(mlxsw_core); + struct mlxsw_core_port *mlxsw_core_port = + &mlxsw_core->ports[MLXSW_PORT_CPU_PORT]; + struct devlink_port *devlink_port = &mlxsw_core_port->devlink_port; + int err; + + mlxsw_core_port->local_port = MLXSW_PORT_CPU_PORT; + mlxsw_core_port->port_driver_priv = port_driver_priv; + devlink_port_attrs_set(devlink_port, DEVLINK_PORT_FLAVOUR_CPU, + 0, false, 0, switch_id, switch_id_len); + err = devlink_port_register(devlink, devlink_port, MLXSW_PORT_CPU_PORT); + if (err) + memset(mlxsw_core_port, 0, sizeof(*mlxsw_core_port)); + return err; +} +EXPORT_SYMBOL(mlxsw_core_cpu_port_init); + +void mlxsw_core_cpu_port_fini(struct mlxsw_core *mlxsw_core) +{ + struct mlxsw_core_port *mlxsw_core_port = + &mlxsw_core->ports[MLXSW_PORT_CPU_PORT]; + struct devlink_port *devlink_port = &mlxsw_core_port->devlink_port; + + devlink_port_unregister(devlink_port); + memset(mlxsw_core_port, 0, sizeof(*mlxsw_core_port)); +} +EXPORT_SYMBOL(mlxsw_core_cpu_port_fini); + void mlxsw_core_port_eth_set(struct mlxsw_core *mlxsw_core, u8 local_port, void *port_driver_priv, struct net_device *dev) { diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h index b65a17d49e43..5d7d2ab6d155 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core.h +++ b/drivers/net/ethernet/mellanox/mlxsw/core.h @@ -177,6 +177,11 @@ int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port, const unsigned char *switch_id, unsigned char switch_id_len); void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port); +int mlxsw_core_cpu_port_init(struct mlxsw_core *mlxsw_core, + void *port_driver_priv, + const unsigned char *switch_id, + unsigned char switch_id_len); +void mlxsw_core_cpu_port_fini(struct mlxsw_core *mlxsw_core); void mlxsw_core_port_eth_set(struct mlxsw_core *mlxsw_core, u8 local_port, void *port_driver_priv, struct net_device *dev); void mlxsw_core_port_ib_set(struct mlxsw_core *mlxsw_core, u8 local_port, diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index 91e4792bb7e7..1fc73a9ad84d 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c @@ -3872,6 +3872,46 @@ static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port) mlxsw_core_port_fini(mlxsw_sp->core, local_port); } +static int mlxsw_sp_cpu_port_create(struct mlxsw_sp *mlxsw_sp) +{ + struct mlxsw_sp_port *mlxsw_sp_port; + int err; + + mlxsw_sp_port = kzalloc(sizeof(*mlxsw_sp_port), GFP_KERNEL); + if (!mlxsw_sp_port) + return -ENOMEM; + + mlxsw_sp_port->mlxsw_sp = mlxsw_sp; + mlxsw_sp_port->local_port = MLXSW_PORT_CPU_PORT; + + mlxsw_sp->ports[MLXSW_PORT_CPU_PORT] = mlxsw_sp_port; + + err = mlxsw_core_cpu_port_init(mlxsw_sp->core, + mlxsw_sp_port, + mlxsw_sp->base_mac, + sizeof(mlxsw_sp->base_mac)); + if (err) { + dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize core CPU port\n"); + goto err_core_cpu_port_init; + } + + return err; + +err_core_cpu_port_init: + mlxsw_sp->ports[MLXSW_PORT_CPU_PORT] = NULL; + kfree(mlxsw_sp_port); + return err; +} + +static void mlxsw_sp_cpu_port_remove(struct mlxsw_sp *mlxsw_sp) +{ + struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp->ports[0]; + + mlxsw_core_cpu_port_fini(mlxsw_sp->core); + mlxsw_sp->ports[MLXSW_PORT_CPU_PORT] = NULL; + kfree(mlxsw_sp_port); +} + static bool mlxsw_sp_port_created(struct mlxsw_sp *mlxsw_sp, u8 local_port) { return mlxsw_sp->ports[local_port] != NULL; @@ -3884,6 +3924,7 @@ static void mlxsw_sp_ports_remove(struct mlxsw_sp *mlxsw_sp) for (i = 1; i < mlxsw_core_max_ports(mlxsw_sp->core); i++) if (mlxsw_sp_port_created(mlxsw_sp, i)) mlxsw_sp_port_remove(mlxsw_sp, i); + mlxsw_sp_cpu_port_remove(mlxsw_sp); kfree(mlxsw_sp->port_to_module); kfree(mlxsw_sp->ports); } @@ -3908,6 +3949,10 @@ static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp) goto err_port_to_module_alloc; } + err = mlxsw_sp_cpu_port_create(mlxsw_sp); + if (err) + goto err_cpu_port_create; + for (i = 1; i < max_ports; i++) { /* Mark as invalid */ mlxsw_sp->port_to_module[i] = -1; @@ -3931,6 +3976,8 @@ static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp) for (i--; i >= 1; i--) if (mlxsw_sp_port_created(mlxsw_sp, i)) mlxsw_sp_port_remove(mlxsw_sp, i); + mlxsw_sp_cpu_port_remove(mlxsw_sp); +err_cpu_port_create: kfree(mlxsw_sp->port_to_module); err_port_to_module_alloc: kfree(mlxsw_sp->ports); -- 2.21.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH net-next 1/2] mlxsw: spectrum: Register CPU port with devlink 2019-09-12 13:07 ` [PATCH net-next 1/2] mlxsw: spectrum: Register CPU port with devlink Ido Schimmel @ 2019-09-13 8:02 ` Jiri Pirko 2019-09-13 9:06 ` Shalom Toledo 0 siblings, 1 reply; 6+ messages in thread From: Jiri Pirko @ 2019-09-13 8:02 UTC (permalink / raw) To: Ido Schimmel; +Cc: netdev, davem, jiri, shalomt, mlxsw, Ido Schimmel Thu, Sep 12, 2019 at 03:07:39PM CEST, idosch@idosch.org wrote: >From: Shalom Toledo <shalomt@mellanox.com> > >Register CPU port with devlink. > >Signed-off-by: Shalom Toledo <shalomt@mellanox.com> >Signed-off-by: Ido Schimmel <idosch@mellanox.com> >--- > drivers/net/ethernet/mellanox/mlxsw/core.c | 33 +++++++++++++ > drivers/net/ethernet/mellanox/mlxsw/core.h | 5 ++ > .../net/ethernet/mellanox/mlxsw/spectrum.c | 47 +++++++++++++++++++ > 3 files changed, 85 insertions(+) > >diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c >index 963a2b4b61b1..94f83d2be17e 100644 >--- a/drivers/net/ethernet/mellanox/mlxsw/core.c >+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c >@@ -1892,6 +1892,39 @@ void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port) > } > EXPORT_SYMBOL(mlxsw_core_port_fini); > >+int mlxsw_core_cpu_port_init(struct mlxsw_core *mlxsw_core, >+ void *port_driver_priv, >+ const unsigned char *switch_id, >+ unsigned char switch_id_len) >+{ >+ struct devlink *devlink = priv_to_devlink(mlxsw_core); >+ struct mlxsw_core_port *mlxsw_core_port = >+ &mlxsw_core->ports[MLXSW_PORT_CPU_PORT]; >+ struct devlink_port *devlink_port = &mlxsw_core_port->devlink_port; >+ int err; >+ >+ mlxsw_core_port->local_port = MLXSW_PORT_CPU_PORT; >+ mlxsw_core_port->port_driver_priv = port_driver_priv; >+ devlink_port_attrs_set(devlink_port, DEVLINK_PORT_FLAVOUR_CPU, >+ 0, false, 0, switch_id, switch_id_len); >+ err = devlink_port_register(devlink, devlink_port, MLXSW_PORT_CPU_PORT); >+ if (err) >+ memset(mlxsw_core_port, 0, sizeof(*mlxsw_core_port)); >+ return err; This duplicates almost 100% of code of mlxsw_core_port_init. Please do a common function what can be used by both. >+} >+EXPORT_SYMBOL(mlxsw_core_cpu_port_init); >+ >+void mlxsw_core_cpu_port_fini(struct mlxsw_core *mlxsw_core) >+{ >+ struct mlxsw_core_port *mlxsw_core_port = >+ &mlxsw_core->ports[MLXSW_PORT_CPU_PORT]; >+ struct devlink_port *devlink_port = &mlxsw_core_port->devlink_port; >+ >+ devlink_port_unregister(devlink_port); >+ memset(mlxsw_core_port, 0, sizeof(*mlxsw_core_port)); >+} >+EXPORT_SYMBOL(mlxsw_core_cpu_port_fini); >+ > void mlxsw_core_port_eth_set(struct mlxsw_core *mlxsw_core, u8 local_port, > void *port_driver_priv, struct net_device *dev) > { >diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h >index b65a17d49e43..5d7d2ab6d155 100644 >--- a/drivers/net/ethernet/mellanox/mlxsw/core.h >+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h >@@ -177,6 +177,11 @@ int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port, > const unsigned char *switch_id, > unsigned char switch_id_len); > void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port); >+int mlxsw_core_cpu_port_init(struct mlxsw_core *mlxsw_core, >+ void *port_driver_priv, >+ const unsigned char *switch_id, >+ unsigned char switch_id_len); >+void mlxsw_core_cpu_port_fini(struct mlxsw_core *mlxsw_core); > void mlxsw_core_port_eth_set(struct mlxsw_core *mlxsw_core, u8 local_port, > void *port_driver_priv, struct net_device *dev); > void mlxsw_core_port_ib_set(struct mlxsw_core *mlxsw_core, u8 local_port, >diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c >index 91e4792bb7e7..1fc73a9ad84d 100644 >--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c >+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c >@@ -3872,6 +3872,46 @@ static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port) > mlxsw_core_port_fini(mlxsw_sp->core, local_port); > } > >+static int mlxsw_sp_cpu_port_create(struct mlxsw_sp *mlxsw_sp) >+{ >+ struct mlxsw_sp_port *mlxsw_sp_port; >+ int err; >+ >+ mlxsw_sp_port = kzalloc(sizeof(*mlxsw_sp_port), GFP_KERNEL); >+ if (!mlxsw_sp_port) >+ return -ENOMEM; >+ >+ mlxsw_sp_port->mlxsw_sp = mlxsw_sp; >+ mlxsw_sp_port->local_port = MLXSW_PORT_CPU_PORT; >+ >+ mlxsw_sp->ports[MLXSW_PORT_CPU_PORT] = mlxsw_sp_port; Assign this at the end of the function and avoid NULL assignment on error path. >+ >+ err = mlxsw_core_cpu_port_init(mlxsw_sp->core, >+ mlxsw_sp_port, >+ mlxsw_sp->base_mac, >+ sizeof(mlxsw_sp->base_mac)); >+ if (err) { >+ dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize core CPU port\n"); >+ goto err_core_cpu_port_init; >+ } >+ >+ return err; >+ >+err_core_cpu_port_init: >+ mlxsw_sp->ports[MLXSW_PORT_CPU_PORT] = NULL; >+ kfree(mlxsw_sp_port); >+ return err; >+} >+ >+static void mlxsw_sp_cpu_port_remove(struct mlxsw_sp *mlxsw_sp) >+{ >+ struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp->ports[0]; s/0/MLXSW_PORT_CPU_PORT/ >+ >+ mlxsw_core_cpu_port_fini(mlxsw_sp->core); >+ mlxsw_sp->ports[MLXSW_PORT_CPU_PORT] = NULL; >+ kfree(mlxsw_sp_port); >+} >+ > static bool mlxsw_sp_port_created(struct mlxsw_sp *mlxsw_sp, u8 local_port) > { > return mlxsw_sp->ports[local_port] != NULL; >@@ -3884,6 +3924,7 @@ static void mlxsw_sp_ports_remove(struct mlxsw_sp *mlxsw_sp) > for (i = 1; i < mlxsw_core_max_ports(mlxsw_sp->core); i++) > if (mlxsw_sp_port_created(mlxsw_sp, i)) > mlxsw_sp_port_remove(mlxsw_sp, i); >+ mlxsw_sp_cpu_port_remove(mlxsw_sp); > kfree(mlxsw_sp->port_to_module); > kfree(mlxsw_sp->ports); > } >@@ -3908,6 +3949,10 @@ static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp) > goto err_port_to_module_alloc; > } > >+ err = mlxsw_sp_cpu_port_create(mlxsw_sp); >+ if (err) >+ goto err_cpu_port_create; >+ > for (i = 1; i < max_ports; i++) { > /* Mark as invalid */ > mlxsw_sp->port_to_module[i] = -1; >@@ -3931,6 +3976,8 @@ static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp) > for (i--; i >= 1; i--) > if (mlxsw_sp_port_created(mlxsw_sp, i)) > mlxsw_sp_port_remove(mlxsw_sp, i); >+ mlxsw_sp_cpu_port_remove(mlxsw_sp); >+err_cpu_port_create: > kfree(mlxsw_sp->port_to_module); > err_port_to_module_alloc: > kfree(mlxsw_sp->ports); >-- >2.21.0 > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH net-next 1/2] mlxsw: spectrum: Register CPU port with devlink 2019-09-13 8:02 ` Jiri Pirko @ 2019-09-13 9:06 ` Shalom Toledo 0 siblings, 0 replies; 6+ messages in thread From: Shalom Toledo @ 2019-09-13 9:06 UTC (permalink / raw) To: Jiri Pirko Cc: Ido Schimmel, netdev@vger.kernel.org, davem@davemloft.net, Jiri Pirko, mlxsw, Ido Schimmel On Fri, Sep 13, 2019 at 10:02:23AM +0200, Jiri Pirko wrote: > Thu, Sep 12, 2019 at 03:07:39PM CEST, idosch@idosch.org wrote: > >From: Shalom Toledo <shalomt@mellanox.com> > > > >Register CPU port with devlink. > > > >Signed-off-by: Shalom Toledo <shalomt@mellanox.com> > >Signed-off-by: Ido Schimmel <idosch@mellanox.com> > >--- > > drivers/net/ethernet/mellanox/mlxsw/core.c | 33 +++++++++++++ > > drivers/net/ethernet/mellanox/mlxsw/core.h | 5 ++ > > .../net/ethernet/mellanox/mlxsw/spectrum.c | 47 +++++++++++++++++++ > > 3 files changed, 85 insertions(+) > > > >diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c > >index 963a2b4b61b1..94f83d2be17e 100644 > >--- a/drivers/net/ethernet/mellanox/mlxsw/core.c > >+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c > >@@ -1892,6 +1892,39 @@ void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port) > > } > > EXPORT_SYMBOL(mlxsw_core_port_fini); > > > >+int mlxsw_core_cpu_port_init(struct mlxsw_core *mlxsw_core, > >+ void *port_driver_priv, > >+ const unsigned char *switch_id, > >+ unsigned char switch_id_len) > >+{ > >+ struct devlink *devlink = priv_to_devlink(mlxsw_core); > >+ struct mlxsw_core_port *mlxsw_core_port = > >+ &mlxsw_core->ports[MLXSW_PORT_CPU_PORT]; > >+ struct devlink_port *devlink_port = &mlxsw_core_port->devlink_port; > >+ int err; > >+ > >+ mlxsw_core_port->local_port = MLXSW_PORT_CPU_PORT; > >+ mlxsw_core_port->port_driver_priv = port_driver_priv; > >+ devlink_port_attrs_set(devlink_port, DEVLINK_PORT_FLAVOUR_CPU, > >+ 0, false, 0, switch_id, switch_id_len); > >+ err = devlink_port_register(devlink, devlink_port, MLXSW_PORT_CPU_PORT); > >+ if (err) > >+ memset(mlxsw_core_port, 0, sizeof(*mlxsw_core_port)); > >+ return err; > > This duplicates almost 100% of code of mlxsw_core_port_init. Please do a > common function what can be used by both. Ok, I will send another version on Sunday. > > > >+} > >+EXPORT_SYMBOL(mlxsw_core_cpu_port_init); > >+ > >+void mlxsw_core_cpu_port_fini(struct mlxsw_core *mlxsw_core) > >+{ > >+ struct mlxsw_core_port *mlxsw_core_port = > >+ &mlxsw_core->ports[MLXSW_PORT_CPU_PORT]; > >+ struct devlink_port *devlink_port = &mlxsw_core_port->devlink_port; > >+ > >+ devlink_port_unregister(devlink_port); > >+ memset(mlxsw_core_port, 0, sizeof(*mlxsw_core_port)); > >+} > >+EXPORT_SYMBOL(mlxsw_core_cpu_port_fini); > >+ > > void mlxsw_core_port_eth_set(struct mlxsw_core *mlxsw_core, u8 local_port, > > void *port_driver_priv, struct net_device *dev) > > { > >diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h > >index b65a17d49e43..5d7d2ab6d155 100644 > >--- a/drivers/net/ethernet/mellanox/mlxsw/core.h > >+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h > >@@ -177,6 +177,11 @@ int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port, > > const unsigned char *switch_id, > > unsigned char switch_id_len); > > void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port); > >+int mlxsw_core_cpu_port_init(struct mlxsw_core *mlxsw_core, > >+ void *port_driver_priv, > >+ const unsigned char *switch_id, > >+ unsigned char switch_id_len); > >+void mlxsw_core_cpu_port_fini(struct mlxsw_core *mlxsw_core); > > void mlxsw_core_port_eth_set(struct mlxsw_core *mlxsw_core, u8 local_port, > > void *port_driver_priv, struct net_device *dev); > > void mlxsw_core_port_ib_set(struct mlxsw_core *mlxsw_core, u8 local_port, > >diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c > >index 91e4792bb7e7..1fc73a9ad84d 100644 > >--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c > >+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c > >@@ -3872,6 +3872,46 @@ static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port) > > mlxsw_core_port_fini(mlxsw_sp->core, local_port); > > } > > > >+static int mlxsw_sp_cpu_port_create(struct mlxsw_sp *mlxsw_sp) > >+{ > >+ struct mlxsw_sp_port *mlxsw_sp_port; > >+ int err; > >+ > >+ mlxsw_sp_port = kzalloc(sizeof(*mlxsw_sp_port), GFP_KERNEL); > >+ if (!mlxsw_sp_port) > >+ return -ENOMEM; > >+ > >+ mlxsw_sp_port->mlxsw_sp = mlxsw_sp; > >+ mlxsw_sp_port->local_port = MLXSW_PORT_CPU_PORT; > >+ > >+ mlxsw_sp->ports[MLXSW_PORT_CPU_PORT] = mlxsw_sp_port; > > Assign this at the end of the function and avoid NULL assignment on > error path. > > > >+ > >+ err = mlxsw_core_cpu_port_init(mlxsw_sp->core, > >+ mlxsw_sp_port, > >+ mlxsw_sp->base_mac, > >+ sizeof(mlxsw_sp->base_mac)); > >+ if (err) { > >+ dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize core CPU port\n"); > >+ goto err_core_cpu_port_init; > >+ } > >+ > >+ return err; > >+ > >+err_core_cpu_port_init: > >+ mlxsw_sp->ports[MLXSW_PORT_CPU_PORT] = NULL; > >+ kfree(mlxsw_sp_port); > >+ return err; > >+} > >+ > >+static void mlxsw_sp_cpu_port_remove(struct mlxsw_sp *mlxsw_sp) > >+{ > >+ struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp->ports[0]; > > s/0/MLXSW_PORT_CPU_PORT/ > > > >+ > >+ mlxsw_core_cpu_port_fini(mlxsw_sp->core); > >+ mlxsw_sp->ports[MLXSW_PORT_CPU_PORT] = NULL; > >+ kfree(mlxsw_sp_port); > >+} > >+ > > static bool mlxsw_sp_port_created(struct mlxsw_sp *mlxsw_sp, u8 local_port) > > { > > return mlxsw_sp->ports[local_port] != NULL; > >@@ -3884,6 +3924,7 @@ static void mlxsw_sp_ports_remove(struct mlxsw_sp *mlxsw_sp) > > for (i = 1; i < mlxsw_core_max_ports(mlxsw_sp->core); i++) > > if (mlxsw_sp_port_created(mlxsw_sp, i)) > > mlxsw_sp_port_remove(mlxsw_sp, i); > >+ mlxsw_sp_cpu_port_remove(mlxsw_sp); > > kfree(mlxsw_sp->port_to_module); > > kfree(mlxsw_sp->ports); > > } > >@@ -3908,6 +3949,10 @@ static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp) > > goto err_port_to_module_alloc; > > } > > > >+ err = mlxsw_sp_cpu_port_create(mlxsw_sp); > >+ if (err) > >+ goto err_cpu_port_create; > >+ > > for (i = 1; i < max_ports; i++) { > > /* Mark as invalid */ > > mlxsw_sp->port_to_module[i] = -1; > >@@ -3931,6 +3976,8 @@ static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp) > > for (i--; i >= 1; i--) > > if (mlxsw_sp_port_created(mlxsw_sp, i)) > > mlxsw_sp_port_remove(mlxsw_sp, i); > >+ mlxsw_sp_cpu_port_remove(mlxsw_sp); > >+err_cpu_port_create: > > kfree(mlxsw_sp->port_to_module); > > err_port_to_module_alloc: > > kfree(mlxsw_sp->ports); > >-- > >2.21.0 > > ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH net-next 2/2] mlxsw: spectrum_buffers: Add the ability to query the CPU port's shared buffer 2019-09-12 13:07 [PATCH net-next 0/2] mlxsw: spectrum_buffers: Add the ability to query the CPU port's shared buffer Ido Schimmel 2019-09-12 13:07 ` [PATCH net-next 1/2] mlxsw: spectrum: Register CPU port with devlink Ido Schimmel @ 2019-09-12 13:07 ` Ido Schimmel 2019-09-13 8:17 ` Jiri Pirko 1 sibling, 1 reply; 6+ messages in thread From: Ido Schimmel @ 2019-09-12 13:07 UTC (permalink / raw) To: netdev; +Cc: davem, jiri, shalomt, mlxsw, Ido Schimmel From: Shalom Toledo <shalomt@mellanox.com> While debugging packet loss towards the CPU, it is useful to be able to query the CPU port's shared buffer quotas and occupancy. Since the CPU port has no ingress buffers, all the shared buffers ingress information will be cleared. Signed-off-by: Shalom Toledo <shalomt@mellanox.com> Signed-off-by: Ido Schimmel <idosch@mellanox.com> --- .../mellanox/mlxsw/spectrum_buffers.c | 51 ++++++++++++++++--- 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c index 888ba4300bcc..b9eeae37a4dc 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c @@ -250,6 +250,10 @@ static int mlxsw_sp_sb_pm_occ_clear(struct mlxsw_sp *mlxsw_sp, u8 local_port, &mlxsw_sp->sb_vals->pool_dess[pool_index]; char sbpm_pl[MLXSW_REG_SBPM_LEN]; + if (local_port == MLXSW_PORT_CPU_PORT && + des->dir == MLXSW_REG_SBXX_DIR_INGRESS) + return 0; + mlxsw_reg_sbpm_pack(sbpm_pl, local_port, des->pool, des->dir, true, 0, 0); return mlxsw_reg_trans_query(mlxsw_sp->core, MLXSW_REG(sbpm), sbpm_pl, @@ -273,6 +277,10 @@ static int mlxsw_sp_sb_pm_occ_query(struct mlxsw_sp *mlxsw_sp, u8 local_port, char sbpm_pl[MLXSW_REG_SBPM_LEN]; struct mlxsw_sp_sb_pm *pm; + if (local_port == MLXSW_PORT_CPU_PORT && + des->dir == MLXSW_REG_SBXX_DIR_INGRESS) + return 0; + pm = mlxsw_sp_sb_pm_get(mlxsw_sp, local_port, pool_index); mlxsw_reg_sbpm_pack(sbpm_pl, local_port, des->pool, des->dir, false, 0, 0); @@ -1085,6 +1093,11 @@ int mlxsw_sp_sb_port_pool_set(struct mlxsw_core_port *mlxsw_core_port, u32 max_buff; int err; + if (local_port == MLXSW_PORT_CPU_PORT) { + NL_SET_ERR_MSG_MOD(extack, "Changing CPU port's threshold is forbidden"); + return -EINVAL; + } + err = mlxsw_sp_sb_threshold_in(mlxsw_sp, pool_index, threshold, &max_buff, extack); if (err) @@ -1130,6 +1143,11 @@ int mlxsw_sp_sb_tc_pool_bind_set(struct mlxsw_core_port *mlxsw_core_port, u32 max_buff; int err; + if (local_port == MLXSW_PORT_CPU_PORT) { + NL_SET_ERR_MSG_MOD(extack, "Changing CPU port's binding is forbidden"); + return -EINVAL; + } + if (dir != mlxsw_sp->sb_vals->pool_dess[pool_index].dir) { NL_SET_ERR_MSG_MOD(extack, "Binding egress TC to ingress pool and vice versa is forbidden"); return -EINVAL; @@ -1187,6 +1205,11 @@ static void mlxsw_sp_sb_sr_occ_query_cb(struct mlxsw_core *mlxsw_core, local_port < mlxsw_core_max_ports(mlxsw_core); local_port++) { if (!mlxsw_sp->ports[local_port]) continue; + if (local_port == MLXSW_PORT_CPU_PORT) { + /* Ingress quotas are not supported for the CPU port */ + masked_count++; + continue; + } for (i = 0; i < MLXSW_SP_SB_ING_TC_COUNT; i++) { cm = mlxsw_sp_sb_cm_get(mlxsw_sp, local_port, i, MLXSW_REG_SBXX_DIR_INGRESS); @@ -1222,7 +1245,7 @@ int mlxsw_sp_sb_occ_snapshot(struct mlxsw_core *mlxsw_core, char *sbsr_pl; u8 masked_count; u8 local_port_1; - u8 local_port = 0; + u8 local_port; int i; int err; int err2; @@ -1231,8 +1254,8 @@ int mlxsw_sp_sb_occ_snapshot(struct mlxsw_core *mlxsw_core, if (!sbsr_pl) return -ENOMEM; + local_port = MLXSW_PORT_CPU_PORT; next_batch: - local_port++; local_port_1 = local_port; masked_count = 0; mlxsw_reg_sbsr_pack(sbsr_pl, false); @@ -1243,7 +1266,11 @@ int mlxsw_sp_sb_occ_snapshot(struct mlxsw_core *mlxsw_core, for (; local_port < mlxsw_core_max_ports(mlxsw_core); local_port++) { if (!mlxsw_sp->ports[local_port]) continue; - mlxsw_reg_sbsr_ingress_port_mask_set(sbsr_pl, local_port, 1); + if (local_port != MLXSW_PORT_CPU_PORT) { + /* Ingress quotas are not supported for the CPU port */ + mlxsw_reg_sbsr_ingress_port_mask_set(sbsr_pl, + local_port, 1); + } mlxsw_reg_sbsr_egress_port_mask_set(sbsr_pl, local_port, 1); for (i = 0; i < mlxsw_sp->sb_vals->pool_count; i++) { err = mlxsw_sp_sb_pm_occ_query(mlxsw_sp, local_port, i, @@ -1264,8 +1291,10 @@ int mlxsw_sp_sb_occ_snapshot(struct mlxsw_core *mlxsw_core, cb_priv); if (err) goto out; - if (local_port < mlxsw_core_max_ports(mlxsw_core)) + if (local_port < mlxsw_core_max_ports(mlxsw_core)) { + local_port++; goto next_batch; + } out: err2 = mlxsw_reg_trans_bulk_wait(&bulk_list); @@ -1282,7 +1311,7 @@ int mlxsw_sp_sb_occ_max_clear(struct mlxsw_core *mlxsw_core, LIST_HEAD(bulk_list); char *sbsr_pl; unsigned int masked_count; - u8 local_port = 0; + u8 local_port; int i; int err; int err2; @@ -1291,8 +1320,8 @@ int mlxsw_sp_sb_occ_max_clear(struct mlxsw_core *mlxsw_core, if (!sbsr_pl) return -ENOMEM; + local_port = MLXSW_PORT_CPU_PORT; next_batch: - local_port++; masked_count = 0; mlxsw_reg_sbsr_pack(sbsr_pl, true); for (i = 0; i < MLXSW_SP_SB_ING_TC_COUNT; i++) @@ -1302,7 +1331,11 @@ int mlxsw_sp_sb_occ_max_clear(struct mlxsw_core *mlxsw_core, for (; local_port < mlxsw_core_max_ports(mlxsw_core); local_port++) { if (!mlxsw_sp->ports[local_port]) continue; - mlxsw_reg_sbsr_ingress_port_mask_set(sbsr_pl, local_port, 1); + if (local_port != MLXSW_PORT_CPU_PORT) { + /* Ingress quotas are not supported for the CPU port */ + mlxsw_reg_sbsr_ingress_port_mask_set(sbsr_pl, + local_port, 1); + } mlxsw_reg_sbsr_egress_port_mask_set(sbsr_pl, local_port, 1); for (i = 0; i < mlxsw_sp->sb_vals->pool_count; i++) { err = mlxsw_sp_sb_pm_occ_clear(mlxsw_sp, local_port, i, @@ -1319,8 +1352,10 @@ int mlxsw_sp_sb_occ_max_clear(struct mlxsw_core *mlxsw_core, &bulk_list, NULL, 0); if (err) goto out; - if (local_port < mlxsw_core_max_ports(mlxsw_core)) + if (local_port < mlxsw_core_max_ports(mlxsw_core)) { + local_port++; goto next_batch; + } out: err2 = mlxsw_reg_trans_bulk_wait(&bulk_list); -- 2.21.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH net-next 2/2] mlxsw: spectrum_buffers: Add the ability to query the CPU port's shared buffer 2019-09-12 13:07 ` [PATCH net-next 2/2] mlxsw: spectrum_buffers: Add the ability to query the CPU port's shared buffer Ido Schimmel @ 2019-09-13 8:17 ` Jiri Pirko 0 siblings, 0 replies; 6+ messages in thread From: Jiri Pirko @ 2019-09-13 8:17 UTC (permalink / raw) To: Ido Schimmel; +Cc: netdev, davem, jiri, shalomt, mlxsw, Ido Schimmel Thu, Sep 12, 2019 at 03:07:40PM CEST, idosch@idosch.org wrote: >From: Shalom Toledo <shalomt@mellanox.com> > >While debugging packet loss towards the CPU, it is useful to be able to >query the CPU port's shared buffer quotas and occupancy. > >Since the CPU port has no ingress buffers, all the shared buffers ingress >information will be cleared. > >Signed-off-by: Shalom Toledo <shalomt@mellanox.com> >Signed-off-by: Ido Schimmel <idosch@mellanox.com> >--- > .../mellanox/mlxsw/spectrum_buffers.c | 51 ++++++++++++++++--- > 1 file changed, 43 insertions(+), 8 deletions(-) > >diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c >index 888ba4300bcc..b9eeae37a4dc 100644 >--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c >+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c >@@ -250,6 +250,10 @@ static int mlxsw_sp_sb_pm_occ_clear(struct mlxsw_sp *mlxsw_sp, u8 local_port, > &mlxsw_sp->sb_vals->pool_dess[pool_index]; > char sbpm_pl[MLXSW_REG_SBPM_LEN]; > >+ if (local_port == MLXSW_PORT_CPU_PORT && >+ des->dir == MLXSW_REG_SBXX_DIR_INGRESS) >+ return 0; >+ > mlxsw_reg_sbpm_pack(sbpm_pl, local_port, des->pool, des->dir, > true, 0, 0); > return mlxsw_reg_trans_query(mlxsw_sp->core, MLXSW_REG(sbpm), sbpm_pl, >@@ -273,6 +277,10 @@ static int mlxsw_sp_sb_pm_occ_query(struct mlxsw_sp *mlxsw_sp, u8 local_port, > char sbpm_pl[MLXSW_REG_SBPM_LEN]; > struct mlxsw_sp_sb_pm *pm; > >+ if (local_port == MLXSW_PORT_CPU_PORT && >+ des->dir == MLXSW_REG_SBXX_DIR_INGRESS) >+ return 0; >+ > pm = mlxsw_sp_sb_pm_get(mlxsw_sp, local_port, pool_index); > mlxsw_reg_sbpm_pack(sbpm_pl, local_port, des->pool, des->dir, > false, 0, 0); >@@ -1085,6 +1093,11 @@ int mlxsw_sp_sb_port_pool_set(struct mlxsw_core_port *mlxsw_core_port, > u32 max_buff; > int err; > >+ if (local_port == MLXSW_PORT_CPU_PORT) { >+ NL_SET_ERR_MSG_MOD(extack, "Changing CPU port's threshold is forbidden"); >+ return -EINVAL; >+ } >+ > err = mlxsw_sp_sb_threshold_in(mlxsw_sp, pool_index, > threshold, &max_buff, extack); > if (err) >@@ -1130,6 +1143,11 @@ int mlxsw_sp_sb_tc_pool_bind_set(struct mlxsw_core_port *mlxsw_core_port, > u32 max_buff; > int err; > >+ if (local_port == MLXSW_PORT_CPU_PORT) { >+ NL_SET_ERR_MSG_MOD(extack, "Changing CPU port's binding is forbidden"); I believe you need to add this check before the previous patch that introduces the cpu port. >+ return -EINVAL; >+ } >+ > if (dir != mlxsw_sp->sb_vals->pool_dess[pool_index].dir) { > NL_SET_ERR_MSG_MOD(extack, "Binding egress TC to ingress pool and vice versa is forbidden"); > return -EINVAL; >@@ -1187,6 +1205,11 @@ static void mlxsw_sp_sb_sr_occ_query_cb(struct mlxsw_core *mlxsw_core, > local_port < mlxsw_core_max_ports(mlxsw_core); local_port++) { > if (!mlxsw_sp->ports[local_port]) > continue; >+ if (local_port == MLXSW_PORT_CPU_PORT) { >+ /* Ingress quotas are not supported for the CPU port */ >+ masked_count++; >+ continue; >+ } > for (i = 0; i < MLXSW_SP_SB_ING_TC_COUNT; i++) { > cm = mlxsw_sp_sb_cm_get(mlxsw_sp, local_port, i, > MLXSW_REG_SBXX_DIR_INGRESS); >@@ -1222,7 +1245,7 @@ int mlxsw_sp_sb_occ_snapshot(struct mlxsw_core *mlxsw_core, > char *sbsr_pl; > u8 masked_count; > u8 local_port_1; >- u8 local_port = 0; >+ u8 local_port; > int i; > int err; > int err2; >@@ -1231,8 +1254,8 @@ int mlxsw_sp_sb_occ_snapshot(struct mlxsw_core *mlxsw_core, > if (!sbsr_pl) > return -ENOMEM; > >+ local_port = MLXSW_PORT_CPU_PORT; > next_batch: >- local_port++; > local_port_1 = local_port; > masked_count = 0; > mlxsw_reg_sbsr_pack(sbsr_pl, false); >@@ -1243,7 +1266,11 @@ int mlxsw_sp_sb_occ_snapshot(struct mlxsw_core *mlxsw_core, > for (; local_port < mlxsw_core_max_ports(mlxsw_core); local_port++) { > if (!mlxsw_sp->ports[local_port]) > continue; >- mlxsw_reg_sbsr_ingress_port_mask_set(sbsr_pl, local_port, 1); >+ if (local_port != MLXSW_PORT_CPU_PORT) { >+ /* Ingress quotas are not supported for the CPU port */ >+ mlxsw_reg_sbsr_ingress_port_mask_set(sbsr_pl, >+ local_port, 1); >+ } > mlxsw_reg_sbsr_egress_port_mask_set(sbsr_pl, local_port, 1); > for (i = 0; i < mlxsw_sp->sb_vals->pool_count; i++) { > err = mlxsw_sp_sb_pm_occ_query(mlxsw_sp, local_port, i, >@@ -1264,8 +1291,10 @@ int mlxsw_sp_sb_occ_snapshot(struct mlxsw_core *mlxsw_core, > cb_priv); > if (err) > goto out; >- if (local_port < mlxsw_core_max_ports(mlxsw_core)) >+ if (local_port < mlxsw_core_max_ports(mlxsw_core)) { >+ local_port++; > goto next_batch; >+ } > > out: > err2 = mlxsw_reg_trans_bulk_wait(&bulk_list); >@@ -1282,7 +1311,7 @@ int mlxsw_sp_sb_occ_max_clear(struct mlxsw_core *mlxsw_core, > LIST_HEAD(bulk_list); > char *sbsr_pl; > unsigned int masked_count; >- u8 local_port = 0; >+ u8 local_port; > int i; > int err; > int err2; >@@ -1291,8 +1320,8 @@ int mlxsw_sp_sb_occ_max_clear(struct mlxsw_core *mlxsw_core, > if (!sbsr_pl) > return -ENOMEM; > >+ local_port = MLXSW_PORT_CPU_PORT; > next_batch: >- local_port++; > masked_count = 0; > mlxsw_reg_sbsr_pack(sbsr_pl, true); > for (i = 0; i < MLXSW_SP_SB_ING_TC_COUNT; i++) >@@ -1302,7 +1331,11 @@ int mlxsw_sp_sb_occ_max_clear(struct mlxsw_core *mlxsw_core, > for (; local_port < mlxsw_core_max_ports(mlxsw_core); local_port++) { > if (!mlxsw_sp->ports[local_port]) > continue; >- mlxsw_reg_sbsr_ingress_port_mask_set(sbsr_pl, local_port, 1); >+ if (local_port != MLXSW_PORT_CPU_PORT) { >+ /* Ingress quotas are not supported for the CPU port */ >+ mlxsw_reg_sbsr_ingress_port_mask_set(sbsr_pl, >+ local_port, 1); >+ } > mlxsw_reg_sbsr_egress_port_mask_set(sbsr_pl, local_port, 1); > for (i = 0; i < mlxsw_sp->sb_vals->pool_count; i++) { > err = mlxsw_sp_sb_pm_occ_clear(mlxsw_sp, local_port, i, >@@ -1319,8 +1352,10 @@ int mlxsw_sp_sb_occ_max_clear(struct mlxsw_core *mlxsw_core, > &bulk_list, NULL, 0); > if (err) > goto out; >- if (local_port < mlxsw_core_max_ports(mlxsw_core)) >+ if (local_port < mlxsw_core_max_ports(mlxsw_core)) { >+ local_port++; > goto next_batch; >+ } > > out: > err2 = mlxsw_reg_trans_bulk_wait(&bulk_list); >-- >2.21.0 > ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2019-09-13 9:06 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2019-09-12 13:07 [PATCH net-next 0/2] mlxsw: spectrum_buffers: Add the ability to query the CPU port's shared buffer Ido Schimmel 2019-09-12 13:07 ` [PATCH net-next 1/2] mlxsw: spectrum: Register CPU port with devlink Ido Schimmel 2019-09-13 8:02 ` Jiri Pirko 2019-09-13 9:06 ` Shalom Toledo 2019-09-12 13:07 ` [PATCH net-next 2/2] mlxsw: spectrum_buffers: Add the ability to query the CPU port's shared buffer Ido Schimmel 2019-09-13 8:17 ` Jiri Pirko
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).