227 lines
7.6 KiB
Diff
227 lines
7.6 KiB
Diff
From e8c2bb23379d6dc91892c8fc732e19c9589d3111 Mon Sep 17 00:00:00 2001
|
|
From: Yihang Li <liyihang9@huawei.com>
|
|
Date: Mon, 4 Dec 2023 17:49:04 +0800
|
|
Subject: [PATCH] scsi: hisi_sas: Allocate DFX memory during dump trigger
|
|
|
|
mainline inclusion
|
|
from mainline-v6.7-rc1
|
|
commit 63f0733d07ce60252e885602b39571ade0441015
|
|
category: bugfix
|
|
bugzilla: https://gitee.com/openeuler/kernel/issues/I8IL6H
|
|
CVE: NA
|
|
|
|
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=63f0733d07ce60252e885602b39571ade0441015
|
|
|
|
----------------------------------------------------------------------
|
|
|
|
Currently, if CONFIG_SCSI_HISI_SAS_DEBUGFS_DEFAULT_ENABLE is enabled, the
|
|
memory space used by DFX is allocated during device initialization, which
|
|
occupies a large number of memory resources. The memory usage before and
|
|
after the driver is loaded is as follows:
|
|
|
|
Memory usage before the driver is loaded:
|
|
$ free -m
|
|
total used free shared buff/cache available
|
|
Mem: 867352 2578 864037 11 735 861681
|
|
Swap: 4095 0 4095
|
|
|
|
Memory usage after the driver which include 4 HBAs is loaded:
|
|
$ insmod hisi_sas_v3_hw.ko
|
|
$ free -m
|
|
total used free shared buff/cache available
|
|
Mem: 867352 4760 861848 11 743 859495
|
|
Swap: 4095 0 4095
|
|
|
|
The driver with 4 HBAs connected will allocate about 110 MB of memory
|
|
without enabling debugfs.
|
|
|
|
Therefore, to avoid wasting memory resources, DFX memory is allocated
|
|
during dump triggering. The dump may fail due to memory allocation
|
|
failure. After this change, each dump costs about 10 MB of memory, and each
|
|
dump lasts about 100 ms.
|
|
|
|
Signed-off-by: Yihang Li <liyihang9@huawei.com>
|
|
Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
|
|
Link: https://lore.kernel.org/r/1694571327-78697-4-git-send-email-chenxiang66@hisilicon.com
|
|
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
|
|
Signed-off-by: xiabing <xiabing12@h-partners.com>
|
|
Signed-off-by: chenyi <chenyi211@huawei.com>
|
|
---
|
|
drivers/scsi/hisi_sas/hisi_sas.h | 2 +-
|
|
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 94 +++++++++++++-------------
|
|
2 files changed, 48 insertions(+), 48 deletions(-)
|
|
|
|
diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
|
|
index 003b8c9b86bb..840ceb5366ef 100644
|
|
--- a/drivers/scsi/hisi_sas/hisi_sas.h
|
|
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
|
|
@@ -377,7 +377,7 @@ struct hisi_sas_hw {
|
|
const struct cpumask *(*get_managed_irq_aff)(struct hisi_hba
|
|
*hisi_hba, int queue);
|
|
void (*debugfs_work_handler)(struct work_struct *work);
|
|
- void (*debugfs_snapshot_regs)(struct hisi_hba *hisi_hba);
|
|
+ int (*debugfs_snapshot_regs)(struct hisi_hba *hisi_hba);
|
|
int complete_hdr_size;
|
|
struct scsi_host_template *sht;
|
|
};
|
|
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
|
|
index 69d29dd1b196..292776e47231 100644
|
|
--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
|
|
+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
|
|
@@ -588,7 +588,7 @@ MODULE_PARM_DESC(auto_affine_msi_experimental, "Enable auto-affinity of MSI IRQs
|
|
"default is off");
|
|
|
|
static void debugfs_work_handler_v3_hw(struct work_struct *work);
|
|
-static void debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba);
|
|
+static int debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba);
|
|
|
|
static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off)
|
|
{
|
|
@@ -4147,37 +4147,6 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba)
|
|
&debugfs_ras_v3_hw_fops);
|
|
}
|
|
|
|
-static void debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba)
|
|
-{
|
|
- int debugfs_dump_index = hisi_hba->debugfs_dump_index;
|
|
- struct device *dev = hisi_hba->dev;
|
|
- u64 timestamp = local_clock();
|
|
-
|
|
- if (debugfs_dump_index >= hisi_sas_debugfs_dump_count) {
|
|
- dev_warn(dev, "dump count exceeded!\n");
|
|
- return;
|
|
- }
|
|
-
|
|
- do_div(timestamp, NSEC_PER_MSEC);
|
|
- hisi_hba->debugfs_timestamp[debugfs_dump_index] = timestamp;
|
|
-
|
|
- debugfs_snapshot_prepare_v3_hw(hisi_hba);
|
|
-
|
|
- debugfs_snapshot_global_reg_v3_hw(hisi_hba);
|
|
- debugfs_snapshot_port_reg_v3_hw(hisi_hba);
|
|
- debugfs_snapshot_axi_reg_v3_hw(hisi_hba);
|
|
- debugfs_snapshot_ras_reg_v3_hw(hisi_hba);
|
|
- debugfs_snapshot_cq_reg_v3_hw(hisi_hba);
|
|
- debugfs_snapshot_dq_reg_v3_hw(hisi_hba);
|
|
- debugfs_snapshot_itct_reg_v3_hw(hisi_hba);
|
|
- debugfs_snapshot_iost_reg_v3_hw(hisi_hba);
|
|
-
|
|
- debugfs_create_files_v3_hw(hisi_hba);
|
|
-
|
|
- debugfs_snapshot_restore_v3_hw(hisi_hba);
|
|
- hisi_hba->debugfs_dump_index++;
|
|
-}
|
|
-
|
|
static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file,
|
|
const char __user *user_buf,
|
|
size_t count, loff_t *ppos)
|
|
@@ -4185,9 +4154,6 @@ static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file,
|
|
struct hisi_hba *hisi_hba = file->f_inode->i_private;
|
|
char buf[8];
|
|
|
|
- if (hisi_hba->debugfs_dump_index >= hisi_sas_debugfs_dump_count)
|
|
- return -EFAULT;
|
|
-
|
|
if (count > 8)
|
|
return -EFAULT;
|
|
|
|
@@ -4198,6 +4164,12 @@ static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file,
|
|
return -EFAULT;
|
|
|
|
queue_work(hisi_hba->wq, &hisi_hba->debugfs_work);
|
|
+ down(&hisi_hba->sem);
|
|
+ if (debugfs_snapshot_regs_v3_hw(hisi_hba)) {
|
|
+ up(&hisi_hba->sem);
|
|
+ return -EFAULT;
|
|
+ }
|
|
+ up(&hisi_hba->sem);
|
|
|
|
return count;
|
|
}
|
|
@@ -4985,7 +4957,7 @@ static int debugfs_alloc_v3_hw(struct hisi_hba *hisi_hba, int dump_index)
|
|
{
|
|
const struct hisi_sas_hw *hw = hisi_hba->hw;
|
|
struct device *dev = hisi_hba->dev;
|
|
- int p, c, d, r, i;
|
|
+ int p, c, d, r;
|
|
size_t sz;
|
|
|
|
for (r = 0; r < DEBUGFS_REGS_NUM; r++) {
|
|
@@ -5065,11 +5037,48 @@ static int debugfs_alloc_v3_hw(struct hisi_hba *hisi_hba, int dump_index)
|
|
|
|
return 0;
|
|
fail:
|
|
- for (i = 0; i < hisi_sas_debugfs_dump_count; i++)
|
|
- debugfs_release_v3_hw(hisi_hba, i);
|
|
+ debugfs_release_v3_hw(hisi_hba, dump_index);
|
|
return -ENOMEM;
|
|
}
|
|
|
|
+static int debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba)
|
|
+{
|
|
+ int debugfs_dump_index = hisi_hba->debugfs_dump_index;
|
|
+ struct device *dev = hisi_hba->dev;
|
|
+ u64 timestamp = local_clock();
|
|
+
|
|
+ if (debugfs_dump_index >= hisi_sas_debugfs_dump_count) {
|
|
+ dev_warn(dev, "dump count exceeded!\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ if (debugfs_alloc_v3_hw(hisi_hba, debugfs_dump_index)) {
|
|
+ dev_warn(dev, "failed to alloc memory\n");
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+
|
|
+ do_div(timestamp, NSEC_PER_MSEC);
|
|
+ hisi_hba->debugfs_timestamp[debugfs_dump_index] = timestamp;
|
|
+
|
|
+ debugfs_snapshot_prepare_v3_hw(hisi_hba);
|
|
+
|
|
+ debugfs_snapshot_global_reg_v3_hw(hisi_hba);
|
|
+ debugfs_snapshot_port_reg_v3_hw(hisi_hba);
|
|
+ debugfs_snapshot_axi_reg_v3_hw(hisi_hba);
|
|
+ debugfs_snapshot_ras_reg_v3_hw(hisi_hba);
|
|
+ debugfs_snapshot_cq_reg_v3_hw(hisi_hba);
|
|
+ debugfs_snapshot_dq_reg_v3_hw(hisi_hba);
|
|
+ debugfs_snapshot_itct_reg_v3_hw(hisi_hba);
|
|
+ debugfs_snapshot_iost_reg_v3_hw(hisi_hba);
|
|
+
|
|
+ debugfs_create_files_v3_hw(hisi_hba);
|
|
+
|
|
+ debugfs_snapshot_restore_v3_hw(hisi_hba);
|
|
+ hisi_hba->debugfs_dump_index++;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static void debugfs_phy_down_cnt_init_v3_hw(struct hisi_hba *hisi_hba)
|
|
{
|
|
struct dentry *dir = debugfs_create_dir("phy_down_cnt",
|
|
@@ -5151,7 +5160,6 @@ static void debugfs_bist_init_v3_hw(struct hisi_hba *hisi_hba)
|
|
static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba)
|
|
{
|
|
struct device *dev = hisi_hba->dev;
|
|
- int i;
|
|
|
|
hisi_hba->debugfs_dir = debugfs_create_dir(dev_name(dev),
|
|
hisi_sas_debugfs_dir);
|
|
@@ -5168,14 +5176,6 @@ static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba)
|
|
|
|
debugfs_phy_down_cnt_init_v3_hw(hisi_hba);
|
|
debugfs_fifo_init_v3_hw(hisi_hba);
|
|
-
|
|
- for (i = 0; i < hisi_sas_debugfs_dump_count; i++) {
|
|
- if (debugfs_alloc_v3_hw(hisi_hba, i)) {
|
|
- debugfs_remove_recursive(hisi_hba->debugfs_dir);
|
|
- dev_dbg(dev, "failed to init debugfs!\n");
|
|
- break;
|
|
- }
|
|
- }
|
|
}
|
|
|
|
static void debugfs_exit_v3_hw(struct hisi_hba *hisi_hba)
|
|
--
|
|
2.39.3
|
|
|