net/mlx5e: Add support to rx reporter diagnose
Add rx reporter, which supports diagnose call-back. Diagnostics output include: information common to all RQs: RQ type, RQ size, RQ stride size, CQ size and CQ stride size. In addition advertise information per RQ and its related icosq and attached CQ. $ devlink health diagnose pci/0000:00:0b.0 reporter rx Common config: RQ: type: 2 stride size: 2048 size: 8 CQ: stride size: 64 size: 1024 RQs: channel ix: 0 rqn: 4308 HW state: 1 SW state: 3 posted WQEs: 7 cc: 7 ICOSQ HW state: 1 CQ: cqn: 1032 HW status: 0 channel ix: 1 rqn: 4313 HW state: 1 SW state: 3 posted WQEs: 7 cc: 7 ICOSQ HW state: 1 CQ: cqn: 1036 HW status: 0 channel ix: 2 rqn: 4318 HW state: 1 SW state: 3 posted WQEs: 7 cc: 7 ICOSQ HW state: 1 CQ: cqn: 1040 HW status: 0 channel ix: 3 rqn: 4323 HW state: 1 SW state: 3 posted WQEs: 7 cc: 7 ICOSQ HW state: 1 CQ: cqn: 1044 HW status: 0 $ devlink health diagnose pci/0000:00:0b.0 reporter rx -jp { "Common config": { "RQ": { "type": 2, "stride size": 2048, "size": 8 }, "CQ": { "stride size": 64, "size": 1024 } }, "RQs": [ { "channel ix": 0, "rqn": 4308, "HW state": 1, "SW state": 3, "posted WQEs": 7, "cc": 7, "ICOSQ HW state": 1, "CQ": { "cqn": 1032, "HW status": 0 } },{ "channel ix": 1, "rqn": 4313, "HW state": 1, "SW state": 3, "posted WQEs": 7, "cc": 7, "ICOSQ HW state": 1, "CQ": { "cqn": 1036, "HW status": 0 } },{ "channel ix": 2, "rqn": 4318, "HW state": 1, "SW state": 3, "posted WQEs": 7, "cc": 7, "ICOSQ HW state": 1, "CQ": { "cqn": 1040, "HW status": 0 } },{ "channel ix": 3, "rqn": 4323, "HW state": 1, "SW state": 3, "posted WQEs": 7, "cc": 7, "ICOSQ HW state": 1, "CQ": { "cqn": 1044, "HW status": 0 } } ] } Signed-off-by: Aya Levin <ayal@mellanox.com> Reviewed-by: Tariq Toukan <tariqt@mellanox.com> Acked-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
This commit is contained in:
Родитель
11af6a6d09
Коммит
9032e7192e
|
@ -24,8 +24,8 @@ mlx5_core-y := main.o cmd.o debugfs.o fw.o eq.o uar.o pagealloc.o \
|
|||
mlx5_core-$(CONFIG_MLX5_CORE_EN) += en_main.o en_common.o en_fs.o en_ethtool.o \
|
||||
en_tx.o en_rx.o en_dim.o en_txrx.o en/xdp.o en_stats.o \
|
||||
en_selftest.o en/port.o en/monitor_stats.o en/health.o \
|
||||
en/reporter_tx.o en/params.o en/xsk/umem.o en/xsk/setup.o \
|
||||
en/xsk/rx.o en/xsk/tx.o
|
||||
en/reporter_tx.o en/reporter_rx.o en/params.o en/xsk/umem.o \
|
||||
en/xsk/setup.o en/xsk/rx.o en/xsk/tx.o
|
||||
|
||||
#
|
||||
# Netdev extra
|
||||
|
|
|
@ -846,6 +846,7 @@ struct mlx5e_priv {
|
|||
struct mlx5e_tls *tls;
|
||||
#endif
|
||||
struct devlink_health_reporter *tx_reporter;
|
||||
struct devlink_health_reporter *rx_reporter;
|
||||
struct mlx5e_xsk xsk;
|
||||
};
|
||||
|
||||
|
@ -887,6 +888,26 @@ bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget);
|
|||
int mlx5e_poll_rx_cq(struct mlx5e_cq *cq, int budget);
|
||||
void mlx5e_free_txqsq_descs(struct mlx5e_txqsq *sq);
|
||||
|
||||
static inline u32 mlx5e_rqwq_get_size(struct mlx5e_rq *rq)
|
||||
{
|
||||
switch (rq->wq_type) {
|
||||
case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
|
||||
return mlx5_wq_ll_get_size(&rq->mpwqe.wq);
|
||||
default:
|
||||
return mlx5_wq_cyc_get_size(&rq->wqe.wq);
|
||||
}
|
||||
}
|
||||
|
||||
static inline u32 mlx5e_rqwq_get_cur_sz(struct mlx5e_rq *rq)
|
||||
{
|
||||
switch (rq->wq_type) {
|
||||
case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
|
||||
return rq->mpwqe.wq.cur_sz;
|
||||
default:
|
||||
return rq->wqe.wq.cur_sz;
|
||||
}
|
||||
}
|
||||
|
||||
bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev);
|
||||
bool mlx5e_striding_rq_possible(struct mlx5_core_dev *mdev,
|
||||
struct mlx5e_params *params);
|
||||
|
|
|
@ -98,11 +98,22 @@ int mlx5e_reporter_cq_common_diagnose(struct mlx5e_cq *cq, struct devlink_fmsg *
|
|||
|
||||
int mlx5e_health_create_reporters(struct mlx5e_priv *priv)
|
||||
{
|
||||
return mlx5e_reporter_tx_create(priv);
|
||||
int err;
|
||||
|
||||
err = mlx5e_reporter_tx_create(priv);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mlx5e_reporter_rx_create(priv);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mlx5e_health_destroy_reporters(struct mlx5e_priv *priv)
|
||||
{
|
||||
mlx5e_reporter_rx_destroy(priv);
|
||||
mlx5e_reporter_tx_destroy(priv);
|
||||
}
|
||||
|
||||
|
@ -111,6 +122,9 @@ void mlx5e_health_channels_update(struct mlx5e_priv *priv)
|
|||
if (priv->tx_reporter)
|
||||
devlink_health_reporter_state_update(priv->tx_reporter,
|
||||
DEVLINK_HEALTH_REPORTER_STATE_HEALTHY);
|
||||
if (priv->rx_reporter)
|
||||
devlink_health_reporter_state_update(priv->rx_reporter,
|
||||
DEVLINK_HEALTH_REPORTER_STATE_HEALTHY);
|
||||
}
|
||||
|
||||
int mlx5e_health_sq_to_ready(struct mlx5e_channel *channel, u32 sqn)
|
||||
|
|
|
@ -16,6 +16,9 @@ int mlx5e_reporter_cq_common_diagnose(struct mlx5e_cq *cq, struct devlink_fmsg *
|
|||
int mlx5e_reporter_named_obj_nest_start(struct devlink_fmsg *fmsg, char *name);
|
||||
int mlx5e_reporter_named_obj_nest_end(struct devlink_fmsg *fmsg);
|
||||
|
||||
int mlx5e_reporter_rx_create(struct mlx5e_priv *priv);
|
||||
void mlx5e_reporter_rx_destroy(struct mlx5e_priv *priv);
|
||||
|
||||
#define MLX5E_REPORTER_PER_Q_MAX_LEN 256
|
||||
|
||||
struct mlx5e_err_ctx {
|
||||
|
|
|
@ -0,0 +1,196 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (c) 2019 Mellanox Technologies.
|
||||
|
||||
#include "health.h"
|
||||
#include "params.h"
|
||||
|
||||
static int mlx5e_query_rq_state(struct mlx5_core_dev *dev, u32 rqn, u8 *state)
|
||||
{
|
||||
int outlen = MLX5_ST_SZ_BYTES(query_rq_out);
|
||||
void *out;
|
||||
void *rqc;
|
||||
int err;
|
||||
|
||||
out = kvzalloc(outlen, GFP_KERNEL);
|
||||
if (!out)
|
||||
return -ENOMEM;
|
||||
|
||||
err = mlx5_core_query_rq(dev, rqn, out);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
rqc = MLX5_ADDR_OF(query_rq_out, out, rq_context);
|
||||
*state = MLX5_GET(rqc, rqc, state);
|
||||
|
||||
out:
|
||||
kvfree(out);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mlx5e_rx_reporter_build_diagnose_output(struct mlx5e_rq *rq,
|
||||
struct devlink_fmsg *fmsg)
|
||||
{
|
||||
struct mlx5e_priv *priv = rq->channel->priv;
|
||||
struct mlx5e_params *params;
|
||||
struct mlx5e_icosq *icosq;
|
||||
u8 icosq_hw_state;
|
||||
int wqes_sz;
|
||||
u8 hw_state;
|
||||
u16 wq_head;
|
||||
int err;
|
||||
|
||||
params = &priv->channels.params;
|
||||
icosq = &rq->channel->icosq;
|
||||
err = mlx5e_query_rq_state(priv->mdev, rq->rqn, &hw_state);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mlx5_core_query_sq_state(priv->mdev, icosq->sqn, &icosq_hw_state);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
wqes_sz = mlx5e_rqwq_get_cur_sz(rq);
|
||||
wq_head = params->rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ ?
|
||||
rq->mpwqe.wq.head : mlx5_wq_cyc_get_head(&rq->wqe.wq);
|
||||
|
||||
err = devlink_fmsg_obj_nest_start(fmsg);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = devlink_fmsg_u32_pair_put(fmsg, "channel ix", rq->channel->ix);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = devlink_fmsg_u32_pair_put(fmsg, "rqn", rq->rqn);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = devlink_fmsg_u8_pair_put(fmsg, "HW state", hw_state);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = devlink_fmsg_u8_pair_put(fmsg, "SW state", rq->state);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = devlink_fmsg_u32_pair_put(fmsg, "posted WQEs", wqes_sz);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = devlink_fmsg_u32_pair_put(fmsg, "cc", wq_head);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = devlink_fmsg_u8_pair_put(fmsg, "ICOSQ HW state", icosq_hw_state);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mlx5e_reporter_cq_diagnose(&rq->cq, fmsg);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = devlink_fmsg_obj_nest_end(fmsg);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mlx5e_rx_reporter_diagnose(struct devlink_health_reporter *reporter,
|
||||
struct devlink_fmsg *fmsg)
|
||||
{
|
||||
struct mlx5e_priv *priv = devlink_health_reporter_priv(reporter);
|
||||
struct mlx5e_params *params = &priv->channels.params;
|
||||
struct mlx5e_rq *generic_rq;
|
||||
u32 rq_stride, rq_sz;
|
||||
int i, err = 0;
|
||||
|
||||
mutex_lock(&priv->state_lock);
|
||||
|
||||
if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
|
||||
goto unlock;
|
||||
|
||||
generic_rq = &priv->channels.c[0]->rq;
|
||||
rq_sz = mlx5e_rqwq_get_size(generic_rq);
|
||||
rq_stride = BIT(mlx5e_mpwqe_get_log_stride_size(priv->mdev, params, NULL));
|
||||
|
||||
err = mlx5e_reporter_named_obj_nest_start(fmsg, "Common config");
|
||||
if (err)
|
||||
goto unlock;
|
||||
|
||||
err = mlx5e_reporter_named_obj_nest_start(fmsg, "RQ");
|
||||
if (err)
|
||||
goto unlock;
|
||||
|
||||
err = devlink_fmsg_u8_pair_put(fmsg, "type", params->rq_wq_type);
|
||||
if (err)
|
||||
goto unlock;
|
||||
|
||||
err = devlink_fmsg_u64_pair_put(fmsg, "stride size", rq_stride);
|
||||
if (err)
|
||||
goto unlock;
|
||||
|
||||
err = devlink_fmsg_u32_pair_put(fmsg, "size", rq_sz);
|
||||
if (err)
|
||||
goto unlock;
|
||||
|
||||
err = mlx5e_reporter_named_obj_nest_end(fmsg);
|
||||
if (err)
|
||||
goto unlock;
|
||||
|
||||
err = mlx5e_reporter_cq_common_diagnose(&generic_rq->cq, fmsg);
|
||||
if (err)
|
||||
goto unlock;
|
||||
|
||||
err = mlx5e_reporter_named_obj_nest_end(fmsg);
|
||||
if (err)
|
||||
goto unlock;
|
||||
|
||||
err = devlink_fmsg_arr_pair_nest_start(fmsg, "RQs");
|
||||
if (err)
|
||||
goto unlock;
|
||||
|
||||
for (i = 0; i < priv->channels.num; i++) {
|
||||
struct mlx5e_rq *rq = &priv->channels.c[i]->rq;
|
||||
|
||||
err = mlx5e_rx_reporter_build_diagnose_output(rq, fmsg);
|
||||
if (err)
|
||||
goto unlock;
|
||||
}
|
||||
err = devlink_fmsg_arr_pair_nest_end(fmsg);
|
||||
if (err)
|
||||
goto unlock;
|
||||
unlock:
|
||||
mutex_unlock(&priv->state_lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct devlink_health_reporter_ops mlx5_rx_reporter_ops = {
|
||||
.name = "rx",
|
||||
.diagnose = mlx5e_rx_reporter_diagnose,
|
||||
};
|
||||
|
||||
int mlx5e_reporter_rx_create(struct mlx5e_priv *priv)
|
||||
{
|
||||
struct devlink *devlink = priv_to_devlink(priv->mdev);
|
||||
struct devlink_health_reporter *reporter;
|
||||
|
||||
reporter = devlink_health_reporter_create(devlink,
|
||||
&mlx5_rx_reporter_ops,
|
||||
0, false, priv);
|
||||
if (IS_ERR(reporter)) {
|
||||
netdev_warn(priv->netdev, "Failed to create rx reporter, err = %ld\n",
|
||||
PTR_ERR(reporter));
|
||||
return PTR_ERR(reporter);
|
||||
}
|
||||
priv->rx_reporter = reporter;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mlx5e_reporter_rx_destroy(struct mlx5e_priv *priv)
|
||||
{
|
||||
if (!priv->rx_reporter)
|
||||
return;
|
||||
|
||||
devlink_health_reporter_destroy(priv->rx_reporter);
|
||||
}
|
|
@ -247,26 +247,6 @@ static inline void mlx5e_build_umr_wqe(struct mlx5e_rq *rq,
|
|||
ucseg->mkey_mask = cpu_to_be64(MLX5_MKEY_MASK_FREE);
|
||||
}
|
||||
|
||||
static u32 mlx5e_rqwq_get_size(struct mlx5e_rq *rq)
|
||||
{
|
||||
switch (rq->wq_type) {
|
||||
case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
|
||||
return mlx5_wq_ll_get_size(&rq->mpwqe.wq);
|
||||
default:
|
||||
return mlx5_wq_cyc_get_size(&rq->wqe.wq);
|
||||
}
|
||||
}
|
||||
|
||||
static u32 mlx5e_rqwq_get_cur_sz(struct mlx5e_rq *rq)
|
||||
{
|
||||
switch (rq->wq_type) {
|
||||
case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
|
||||
return rq->mpwqe.wq.cur_sz;
|
||||
default:
|
||||
return rq->wqe.wq.cur_sz;
|
||||
}
|
||||
}
|
||||
|
||||
static int mlx5e_rq_alloc_mpwqe_info(struct mlx5e_rq *rq,
|
||||
struct mlx5e_channel *c)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче