You need to sign in or sign up before continuing.
提交 4efd66fc 编写于 作者: L Luo Jiaxing 提交者: Xie XiuQi

scsi: hisi_sas: Add DFX Feature: Alloc snapshot buffer memory for all registers

This patch allocates snapshot memory for global reg,
port regs, CQ, DQ, IOST, ITCT.

when we fail to allocate memory for one of registers,
we free the momory and set hisi_sas_debugfs_enable
as 0 to stop dfx from running.
Signed-off-by: NLuo Jiaxing <luojiaxing@huawei.com>
Signed-off-by: NJohn Garry <john.garry@huawei.com>
上级 c76876e5
...@@ -223,6 +223,10 @@ struct hisi_sas_slot { ...@@ -223,6 +223,10 @@ struct hisi_sas_slot {
int idx; int idx;
}; };
struct hisi_sas_debugfs_reg {
int count;
};
struct hisi_sas_hw { struct hisi_sas_hw {
int (*hw_init)(struct hisi_hba *hisi_hba); int (*hw_init)(struct hisi_hba *hisi_hba);
void (*setup_itct)(struct hisi_hba *hisi_hba, void (*setup_itct)(struct hisi_hba *hisi_hba,
...@@ -267,6 +271,9 @@ struct hisi_sas_hw { ...@@ -267,6 +271,9 @@ struct hisi_sas_hw {
int max_command_entries; int max_command_entries;
int complete_hdr_size; int complete_hdr_size;
struct scsi_host_template *sht; struct scsi_host_template *sht;
const struct hisi_sas_debugfs_reg *debugfs_reg_global;
const struct hisi_sas_debugfs_reg *debugfs_reg_port;
}; };
struct hisi_hba { struct hisi_hba {
...@@ -335,6 +342,14 @@ struct hisi_hba { ...@@ -335,6 +342,14 @@ struct hisi_hba {
u32 intr_coal_count; /* count of interrupt coalesce */ u32 intr_coal_count; /* count of interrupt coalesce */
int enable_dix_dif; int enable_dix_dif;
/* debugfs memories */
void *global_reg_debugfs;
void *port_reg_debugfs[HISI_SAS_MAX_PHYS];
void *complete_hdr_debugfs[HISI_SAS_MAX_QUEUES];
struct hisi_sas_cmd_hdr *cmd_hdr_debugfs[HISI_SAS_MAX_QUEUES];
struct hisi_sas_iost *iost_debugfs;
struct hisi_sas_itct *itct_debugfs;
struct dentry *debugfs_dir; struct dentry *debugfs_dir;
}; };
......
...@@ -2576,10 +2576,85 @@ struct dentry *hisi_sas_dbg_dir; ...@@ -2576,10 +2576,85 @@ struct dentry *hisi_sas_dbg_dir;
void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba)
{ {
int max_command_entries = hisi_hba->hw->max_command_entries;
struct device *dev = hisi_hba->dev; struct device *dev = hisi_hba->dev;
int p, i, c, d;
size_t sz;
hisi_hba->debugfs_dir = debugfs_create_dir(dev_name(dev), hisi_hba->debugfs_dir = debugfs_create_dir(dev_name(dev),
hisi_sas_dbg_dir); hisi_sas_dbg_dir);
if (!hisi_hba->debugfs_dir)
return;
/* Alloc buffer for global */
sz = hisi_hba->hw->debugfs_reg_global->count * 4;
hisi_hba->global_reg_debugfs =
devm_kmalloc(dev, sz, GFP_KERNEL);
if (!hisi_hba->global_reg_debugfs)
goto fail_global;
/* Alloc buffer for port */
sz = hisi_hba->hw->debugfs_reg_port->count * 4;
for (p = 0; p < hisi_hba->n_phy; p++) {
hisi_hba->port_reg_debugfs[p] =
devm_kmalloc(dev, sz, GFP_KERNEL);
if (!hisi_hba->port_reg_debugfs[p])
goto fail_port;
}
/* Alloc buffer for cq */
sz = hisi_hba->hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS;
for (c = 0; c < hisi_hba->queue_count; c++) {
hisi_hba->complete_hdr_debugfs[c] =
devm_kmalloc(dev, sz, GFP_KERNEL);
if (!hisi_hba->complete_hdr_debugfs[c])
goto fail_cq;
}
/* Alloc buffer for dq */
sz = hisi_hba->hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS;
for (d = 0; d < hisi_hba->queue_count; d++) {
hisi_hba->cmd_hdr_debugfs[d] =
devm_kmalloc(dev, sz, GFP_KERNEL);
if (!hisi_hba->cmd_hdr_debugfs[d])
goto fail_iost_dq;
}
/* Alloc buffer for iost */
sz = max_command_entries * sizeof(struct hisi_sas_iost);
hisi_hba->iost_debugfs = devm_kmalloc(dev, sz, GFP_KERNEL);
if (!hisi_hba->iost_debugfs)
goto fail_iost_dq;
/* Alloc buffer for itct */
/* New memory allocation must be locate before itct */
sz = HISI_SAS_MAX_ITCT_ENTRIES * sizeof(struct hisi_sas_itct);
hisi_hba->itct_debugfs = devm_kmalloc(dev, sz, GFP_KERNEL);
if (!hisi_hba->itct_debugfs)
goto fail_itct;
return;
fail_itct:
devm_kfree(dev, hisi_hba->iost_debugfs);
fail_iost_dq:
for (i = 0; i < d; i++)
devm_kfree(dev, hisi_hba->cmd_hdr_debugfs[i]);
fail_cq:
for (i = 0; i < c; i++)
devm_kfree(dev, hisi_hba->complete_hdr_debugfs[i]);
fail_port:
for (i = 0; i < p; i++)
devm_kfree(dev, hisi_hba->port_reg_debugfs[i]);
devm_kfree(dev, hisi_hba->global_reg_debugfs);
fail_global:
debugfs_remove_recursive(hisi_hba->debugfs_dir);
dev_err(dev, "Dev: %s fail to init Debugfs!", dev_name(dev));
} }
EXPORT_SYMBOL_GPL(hisi_sas_debugfs_init); EXPORT_SYMBOL_GPL(hisi_sas_debugfs_init);
......
...@@ -2400,6 +2400,12 @@ static ssize_t intr_coal_count_store(struct device *dev, ...@@ -2400,6 +2400,12 @@ static ssize_t intr_coal_count_store(struct device *dev,
} }
static DEVICE_ATTR_RW(intr_coal_count); static DEVICE_ATTR_RW(intr_coal_count);
static const struct hisi_sas_debugfs_reg debugfs_port_reg = {
};
static const struct hisi_sas_debugfs_reg debugfs_global_reg = {
};
struct device_attribute *host_attrs_v3_hw[] = { struct device_attribute *host_attrs_v3_hw[] = {
&dev_attr_phy_event_threshold, &dev_attr_phy_event_threshold,
&dev_attr_intr_conv, &dev_attr_intr_conv,
...@@ -2459,6 +2465,8 @@ static const struct hisi_sas_hw hisi_sas_v3_hw = { ...@@ -2459,6 +2465,8 @@ static const struct hisi_sas_hw hisi_sas_v3_hw = {
.get_events = phy_get_events_v3_hw, .get_events = phy_get_events_v3_hw,
.write_gpio = write_gpio_v3_hw, .write_gpio = write_gpio_v3_hw,
.wait_cmds_complete_timeout = wait_cmds_complete_timeout_v3_hw, .wait_cmds_complete_timeout = wait_cmds_complete_timeout_v3_hw,
.debugfs_reg_global = &debugfs_global_reg,
.debugfs_reg_port = &debugfs_port_reg,
}; };
static struct Scsi_Host * static struct Scsi_Host *
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册