Add context numbers for HW elements in mlx5en(4).

To access the data, set sysctl dev.mce.N.conf.debug_stats to 1.
This enables the sysctl node dev.mce.N.hw_ctx_debug.  Its content is
the mapping of each channel' number to used receive queue and associated
completion queue, set of the transmit queues numbers and corresponding
completion queues.

Trimmed example output:
channel 30 rq 188 cq 1085
channel 30 tc 0 sq 187 cq 1084
channel 31 rq 191 cq 1087
channel 31 tc 0 sq 190 cq 1086

MFC after:		1 week
Sponsored by:		Mellanox Technologies
This commit is contained in:
Hans Petter Selasky 2018-07-17 11:18:01 +00:00
parent a880c1ff6a
commit f2b4782c81
3 changed files with 63 additions and 9 deletions

View File

@ -774,6 +774,7 @@ struct mlx5e_priv {
struct sysctl_oid *sysctl_hw;
int sysctl_debug;
struct mlx5e_stats stats;
struct sysctl_ctx_list sysctl_ctx_channel_debug;
int counter_set_id;
struct workqueue_struct *wq;

View File

@ -915,28 +915,76 @@ static const char *mlx5e_port_stats_debug_desc[] = {
MLX5E_PORT_STATS_DEBUG(MLX5E_STATS_DESC)
};
static int
mlx5e_ethtool_debug_channel_info(SYSCTL_HANDLER_ARGS)
{
struct mlx5e_priv *priv;
struct sbuf sb;
struct mlx5e_channel *c;
struct mlx5e_sq *sq;
struct mlx5e_rq *rq;
int error, i, tc;
priv = arg1;
error = sysctl_wire_old_buffer(req, 0);
if (error != 0)
return (error);
if (sbuf_new_for_sysctl(&sb, NULL, 128, req) == NULL)
return (ENOMEM);
sbuf_clear_flags(&sb, SBUF_INCLUDENUL);
PRIV_LOCK(priv);
if (test_bit(MLX5E_STATE_OPENED, &priv->state) == 0)
goto out;
for (i = 0; i < priv->params.num_channels; i++) {
c = priv->channel[i];
rq = &c->rq;
sbuf_printf(&sb, "channel %d rq %d cq %d\n",
c->ix, rq->rqn, rq->cq.mcq.cqn);
for (tc = 0; tc < c->num_tc; tc++) {
sq = &c->sq[tc];
sbuf_printf(&sb, "channel %d tc %d sq %d cq %d\n",
c->ix, tc, sq->sqn, sq->cq.mcq.cqn);
}
}
out:
PRIV_UNLOCK(priv);
error = sbuf_finish(&sb);
sbuf_delete(&sb);
return (error);
}
static int
mlx5e_ethtool_debug_stats(SYSCTL_HANDLER_ARGS)
{
struct mlx5e_priv *priv = arg1;
int error;
int sys_debug;
int error, sys_debug;
sys_debug = priv->sysctl_debug;
error = sysctl_handle_int(oidp, &priv->sysctl_debug, 0, req);
if (error || !req->newptr)
if (error != 0 || !req->newptr)
return (error);
priv->sysctl_debug = !!priv->sysctl_debug;
priv->sysctl_debug = priv->sysctl_debug != 0;
if (sys_debug == priv->sysctl_debug)
return (error);
if (priv->sysctl_debug)
return (0);
PRIV_LOCK(priv);
if (priv->sysctl_debug) {
mlx5e_create_stats(&priv->stats.port_stats_debug.ctx,
SYSCTL_CHILDREN(priv->sysctl_ifnet), "debug_stats",
mlx5e_port_stats_debug_desc, MLX5E_PORT_STATS_DEBUG_NUM,
priv->stats.port_stats_debug.arg);
else
SYSCTL_ADD_PROC(&priv->sysctl_ctx_channel_debug,
SYSCTL_CHILDREN(priv->sysctl_ifnet), OID_AUTO,
"hw_ctx_debug",
CTLFLAG_RD | CTLFLAG_MPSAFE | CTLTYPE_STRING, priv, 0,
mlx5e_ethtool_debug_channel_info, "S", "");
} else {
sysctl_ctx_free(&priv->stats.port_stats_debug.ctx);
return (error);
sysctl_ctx_free(&priv->sysctl_ctx_channel_debug);
}
PRIV_UNLOCK(priv);
return (0);
}
static void

View File

@ -3529,6 +3529,8 @@ mlx5e_create_ifp(struct mlx5_core_dev *mdev)
if (ifp->if_capenable & IFCAP_TXCSUM_IPV6)
ifp->if_hwassist |= (CSUM_UDP_IPV6 | CSUM_TCP_IPV6);
sysctl_ctx_init(&priv->sysctl_ctx_channel_debug);
/* ifnet sysctl tree */
sysctl_ctx_init(&priv->sysctl_ctx);
priv->sysctl_ifnet = SYSCTL_ADD_NODE(&priv->sysctl_ctx, SYSCTL_STATIC_CHILDREN(_dev),
@ -3706,6 +3708,7 @@ err_free_wq:
err_free_sysctl:
sysctl_ctx_free(&priv->sysctl_ctx);
sysctl_ctx_free(&priv->sysctl_ctx_channel_debug);
if_free(ifp);
@ -3770,8 +3773,10 @@ mlx5e_destroy_ifp(struct mlx5_core_dev *mdev, void *vpriv)
mlx5e_rl_cleanup(priv);
#endif
/* destroy all remaining sysctl nodes */
if (priv->sysctl_debug)
if (priv->sysctl_debug) {
sysctl_ctx_free(&priv->sysctl_ctx_channel_debug);
sysctl_ctx_free(&priv->stats.port_stats_debug.ctx);
}
sysctl_ctx_free(&priv->stats.vport.ctx);
sysctl_ctx_free(&priv->stats.pport.ctx);
sysctl_ctx_free(&priv->sysctl_ctx);