hinic: add support to query rq info

add debugfs node for querying rq info, for example:
cat /sys/kernel/debug/hinic/0000:15:00.0/RQs/0x0/rq_hw_pi

Signed-off-by: Luo bin <luobin9@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Luo bin 2020-08-28 11:37:47 +08:00 committed by David S. Miller
parent 253ac3a979
commit 626f060311
6 changed files with 101 additions and 2 deletions

View File

@ -40,6 +40,36 @@ static u64 hinic_dbg_get_sq_info(struct hinic_dev *nic_dev, struct hinic_sq *sq,
return 0;
}
enum rq_dbg_info {
GLB_RQ_ID,
RQ_HW_PI,
RQ_SW_CI,
RQ_SW_PI,
RQ_MSIX_ENTRY,
};
static char *rq_fields[] = {"glb_rq_id", "rq_hw_pi", "rq_sw_ci", "rq_sw_pi", "rq_msix_entry"};
static u64 hinic_dbg_get_rq_info(struct hinic_dev *nic_dev, struct hinic_rq *rq, int idx)
{
struct hinic_wq *wq = rq->wq;
switch (idx) {
case GLB_RQ_ID:
return nic_dev->hwdev->func_to_io.global_qpn + rq->qid;
case RQ_HW_PI:
return be16_to_cpu(*(__be16 *)(rq->pi_virt_addr)) & wq->mask;
case RQ_SW_CI:
return atomic_read(&wq->cons_idx) & wq->mask;
case RQ_SW_PI:
return atomic_read(&wq->prod_idx) & wq->mask;
case RQ_MSIX_ENTRY:
return rq->msix_entry;
}
return 0;
}
static ssize_t hinic_dbg_cmd_read(struct file *filp, char __user *buffer, size_t count,
loff_t *ppos)
{
@ -57,6 +87,10 @@ static ssize_t hinic_dbg_cmd_read(struct file *filp, char __user *buffer, size_t
out = hinic_dbg_get_sq_info(dbg->dev, dbg->object, *desc);
break;
case HINIC_DBG_RQ_INFO:
out = hinic_dbg_get_rq_info(dbg->dev, dbg->object, *desc);
break;
default:
netif_warn(dbg->dev, drv, dbg->dev->netdev, "Invalid hinic debug cmd: %d\n",
dbg->type);
@ -128,6 +162,28 @@ void hinic_sq_debug_rem(struct hinic_sq *sq)
rem_dbg_files(sq->dbg);
}
int hinic_rq_debug_add(struct hinic_dev *dev, u16 rq_id)
{
struct hinic_rq *rq;
struct dentry *root;
char sub_dir[16];
rq = dev->rxqs[rq_id].rq;
sprintf(sub_dir, "0x%x", rq_id);
root = debugfs_create_dir(sub_dir, dev->rq_dbgfs);
return create_dbg_files(dev, HINIC_DBG_RQ_INFO, rq, root, &rq->dbg, rq_fields,
ARRAY_SIZE(rq_fields));
}
void hinic_rq_debug_rem(struct hinic_rq *rq)
{
if (rq->dbg)
rem_dbg_files(rq->dbg);
}
void hinic_sq_dbgfs_init(struct hinic_dev *nic_dev)
{
nic_dev->sq_dbgfs = debugfs_create_dir("SQs", nic_dev->dbgfs_root);
@ -138,6 +194,16 @@ void hinic_sq_dbgfs_uninit(struct hinic_dev *nic_dev)
debugfs_remove_recursive(nic_dev->sq_dbgfs);
}
void hinic_rq_dbgfs_init(struct hinic_dev *nic_dev)
{
nic_dev->rq_dbgfs = debugfs_create_dir("RQs", nic_dev->dbgfs_root);
}
void hinic_rq_dbgfs_uninit(struct hinic_dev *nic_dev)
{
debugfs_remove_recursive(nic_dev->rq_dbgfs);
}
void hinic_dbg_init(struct hinic_dev *nic_dev)
{
nic_dev->dbgfs_root = debugfs_create_dir(pci_name(nic_dev->hwdev->hwif->pdev),

View File

@ -12,10 +12,18 @@ int hinic_sq_debug_add(struct hinic_dev *dev, u16 sq_id);
void hinic_sq_debug_rem(struct hinic_sq *sq);
int hinic_rq_debug_add(struct hinic_dev *dev, u16 rq_id);
void hinic_rq_debug_rem(struct hinic_rq *rq);
void hinic_sq_dbgfs_init(struct hinic_dev *nic_dev);
void hinic_sq_dbgfs_uninit(struct hinic_dev *nic_dev);
void hinic_rq_dbgfs_init(struct hinic_dev *nic_dev);
void hinic_rq_dbgfs_uninit(struct hinic_dev *nic_dev);
void hinic_dbg_init(struct hinic_dev *nic_dev);
void hinic_dbg_uninit(struct hinic_dev *nic_dev);

View File

@ -60,6 +60,7 @@ struct hinic_intr_coal_info {
enum hinic_dbg_type {
HINIC_DBG_SQ_INFO,
HINIC_DBG_RQ_INFO,
};
struct hinic_debug_priv {
@ -112,6 +113,7 @@ struct hinic_dev {
struct dentry *dbgfs_root;
struct dentry *sq_dbgfs;
struct dentry *rq_dbgfs;
struct devlink *devlink;
bool cable_unplugged;
bool module_unrecognized;

View File

@ -315,6 +315,7 @@ static int init_qp(struct hinic_func_to_io *func_to_io,
goto err_sq_init;
}
qp->rq.qid = q_id;
err = hinic_init_rq(&qp->rq, hwif, &func_to_io->rq_wq[q_id],
rq_msix_entry);
if (err) {

View File

@ -100,6 +100,8 @@ struct hinic_rq {
struct hinic_wq *wq;
u16 qid;
struct cpumask affinity_mask;
u32 irq;
u16 msix_entry;
@ -113,6 +115,7 @@ struct hinic_rq {
u16 *pi_virt_addr;
dma_addr_t pi_dma_addr;
struct hinic_debug_priv *dbg;
};
struct hinic_qp {

View File

@ -234,6 +234,8 @@ static int create_rxqs(struct hinic_dev *nic_dev)
if (!nic_dev->rxqs)
return -ENOMEM;
hinic_rq_dbgfs_init(nic_dev);
for (i = 0; i < num_rxqs; i++) {
struct hinic_rq *rq = hinic_hwdev_get_rq(nic_dev->hwdev, i);
@ -243,13 +245,26 @@ static int create_rxqs(struct hinic_dev *nic_dev)
"Failed to init rxq\n");
goto err_init_rxq;
}
err = hinic_rq_debug_add(nic_dev, i);
if (err) {
netif_err(nic_dev, drv, netdev,
"Failed to add RQ%d debug\n", i);
goto err_add_rq_dbg;
}
}
return 0;
err_add_rq_dbg:
hinic_clean_rxq(&nic_dev->rxqs[i]);
err_init_rxq:
for (j = 0; j < i; j++)
for (j = 0; j < i; j++) {
hinic_rq_debug_rem(nic_dev->rxqs[j].rq);
hinic_clean_rxq(&nic_dev->rxqs[j]);
}
hinic_rq_dbgfs_uninit(nic_dev);
devm_kfree(&netdev->dev, nic_dev->rxqs);
return err;
@ -267,8 +282,12 @@ static void free_rxqs(struct hinic_dev *nic_dev)
if (!nic_dev->rxqs)
return;
for (i = 0; i < num_rxqs; i++)
for (i = 0; i < num_rxqs; i++) {
hinic_rq_debug_rem(nic_dev->rxqs[i].rq);
hinic_clean_rxq(&nic_dev->rxqs[i]);
}
hinic_rq_dbgfs_uninit(nic_dev);
devm_kfree(&netdev->dev, nic_dev->rxqs);
nic_dev->rxqs = NULL;