From 628e72d7c9c53772497599545cf9a78fe2559511 Mon Sep 17 00:00:00 2001 From: chenyi Date: Mon, 10 Jun 2024 21:38:49 -0400 Subject: [PATCH] backport a bugfix for hisi_sas --- kernel.spec | 5 +- ...locate-DFX-memory-during-dump-trigge.patch | 226 ++++++++++++++++++ series.conf | 3 +- 3 files changed, 232 insertions(+), 2 deletions(-) create mode 100644 patches/0759-scsi-hisi_sas-Allocate-DFX-memory-during-dump-trigge.patch diff --git a/kernel.spec b/kernel.spec index f487e24..03c3c56 100644 --- a/kernel.spec +++ b/kernel.spec @@ -32,7 +32,7 @@ Name: kernel Version: 4.19.90 -Release: %{hulkrelease}.0279 +Release: %{hulkrelease}.0280 Summary: Linux Kernel License: GPLv2 URL: http://www.kernel.org/ @@ -850,6 +850,9 @@ fi %changelog +* Tue Jun 11 2024 chenyi - 4.19.90-2406.1.0.0280 +- scsi: hisi_sas: Allocate DFX memory during dump trigger + * Wed Jun 05 2024 chenyi - 4.19.90-2406.1.0.0279 - !8437 comedi: dt9812: fix DMA buffers on stack - !8515 v2 *** CVE-2021-47356 *** diff --git a/patches/0759-scsi-hisi_sas-Allocate-DFX-memory-during-dump-trigge.patch b/patches/0759-scsi-hisi_sas-Allocate-DFX-memory-during-dump-trigge.patch new file mode 100644 index 0000000..1c167a5 --- /dev/null +++ b/patches/0759-scsi-hisi_sas-Allocate-DFX-memory-during-dump-trigge.patch @@ -0,0 +1,226 @@ +From e8c2bb23379d6dc91892c8fc732e19c9589d3111 Mon Sep 17 00:00:00 2001 +From: Yihang Li +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 +Signed-off-by: Xiang Chen +Link: https://lore.kernel.org/r/1694571327-78697-4-git-send-email-chenxiang66@hisilicon.com +Signed-off-by: Martin K. Petersen +Signed-off-by: xiabing +Signed-off-by: chenyi +--- + 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 + diff --git a/series.conf b/series.conf index 854655c..5dddf12 100644 --- a/series.conf +++ b/series.conf @@ -758,4 +758,5 @@ patches/0754-scsi-hisi_sas_v3_hw-Remove-extra-function-calls-for-.patch patches/0755-config-arm64-Enable-dubugfs-config-of-hisi-sas.patch patches/0756-crypto-hisilicon-Add-value-profile-support-for-kerne.patch patches/0757-Revert-genirq-Increase-the-number-of-IRQ-descriptors.patch -patches/0758-spi-hisi-sfc-v3xx-Return-IRQ_NONE-if-no-interrupts-w.patch \ No newline at end of file +patches/0758-spi-hisi-sfc-v3xx-Return-IRQ_NONE-if-no-interrupts-w.patch +patches/0759-scsi-hisi_sas-Allocate-DFX-memory-during-dump-trigge.patch