From 52c2392546528eef79f633119446e17588b2428c Mon Sep 17 00:00:00 2001 From: Luo Jiaxing Date: Thu, 24 Oct 2019 22:08:23 +0800 Subject: [PATCH 036/108] scsi: hisi_sas: Add ability to have multiple debugfs dumps mainline inclusion from mainline-v5.5-rc1 commit 8f6432986e610612688dc77c2683657d7289546f category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8F81L Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8f6432986e610612688dc77c2683657d7289546f ---------------------------------------------------------------------- We use the module parameter debugfs_dump_count to manage the upper limit of the memory block for multiple dumps. Link: https://lore.kernel.org/r/1571926105-74636-17-git-send-email-john.garry@huawei.com Signed-off-by: Luo Jiaxing Signed-off-by: John Garry Signed-off-by: Martin K. Petersen Signed-off-by: YunYi Yang Conflicts: drivers/scsi/hisi_sas/hisi_sas.h drivers/scsi/hisi_sas/hisi_sas_main.c --- drivers/scsi/hisi_sas/hisi_sas.h | 5 +- drivers/scsi/hisi_sas/hisi_sas_main.c | 72 ++++++++++++++++----------- 2 files changed, 46 insertions(+), 31 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 5604e6d7bc25..9eba71ad47fd 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -499,8 +499,8 @@ struct hisi_hba { struct hisi_sas_debugfs_itct_cache debugfs_itct_cache[HISI_SAS_MAX_DEBUGFS_DUMP]; - u64 debugfs_timestamp; - + u64 debugfs_timestamp[HISI_SAS_MAX_DEBUGFS_DUMP]; + int debugfs_dump_index; struct dentry *debugfs_dir; struct dentry *debugfs_dump_dentry; struct dentry *debugfs_bist_dentry; @@ -509,7 +509,6 @@ struct hisi_hba { unsigned int dq_idx[NR_CPUS]; int nvecs; unsigned int dq_num_per_node; - bool debugfs_snapshot; }; /* Generic HW DMA host memory structures */ diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index ab7e07f1ed51..5d890758059b 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -2772,10 +2772,11 @@ struct dentry *hisi_sas_debugfs_dir; static void hisi_sas_debugfs_snapshot_cq_reg(struct hisi_hba *hisi_hba) { int queue_entry_size = hisi_hba->hw->complete_hdr_size; + int dump_index = hisi_hba->debugfs_dump_index; int i; for (i = 0; i < hisi_hba->queue_count; i++) - memcpy(hisi_hba->debugfs_cq[0][i].complete_hdr, + memcpy(hisi_hba->debugfs_cq[dump_index][i].complete_hdr, hisi_hba->complete_hdr[i], HISI_SAS_QUEUE_SLOTS * queue_entry_size); } @@ -2783,16 +2784,18 @@ static void hisi_sas_debugfs_snapshot_cq_reg(struct hisi_hba *hisi_hba) static void hisi_sas_debugfs_snapshot_dq_reg(struct hisi_hba *hisi_hba) { int queue_entry_size = sizeof(struct hisi_sas_cmd_hdr); + int dump_index = hisi_hba->debugfs_dump_index; int i; for (i = 0; i < hisi_hba->queue_count; i++) - memcpy(hisi_hba->debugfs_dq[0][i].hdr, + memcpy(hisi_hba->debugfs_dq[dump_index][i].hdr, hisi_hba->cmd_hdr[i], HISI_SAS_QUEUE_SLOTS * queue_entry_size); } static void hisi_sas_debugfs_snapshot_port_reg(struct hisi_hba *hisi_hba) { + int dump_index = hisi_hba->debugfs_dump_index; const struct hisi_sas_debugfs_reg *port = hisi_hba->hw->debugfs_reg_port; int i, phy_cnt; @@ -2800,7 +2803,7 @@ static void hisi_sas_debugfs_snapshot_port_reg(struct hisi_hba *hisi_hba) u32 *databuf; for (phy_cnt = 0; phy_cnt < hisi_hba->n_phy; phy_cnt++) { - databuf = hisi_hba->debugfs_port_reg[0][phy_cnt].data; + databuf = hisi_hba->debugfs_port_reg[dump_index][phy_cnt].data; for (i = 0; i < port->count; i++, databuf++) { offset = port->base_off + 4 * i; *databuf = port->read_port_reg(hisi_hba, phy_cnt, @@ -2811,7 +2814,8 @@ static void hisi_sas_debugfs_snapshot_port_reg(struct hisi_hba *hisi_hba) static void hisi_sas_debugfs_snapshot_global_reg(struct hisi_hba *hisi_hba) { - u32 *databuf = hisi_hba->debugfs_regs[0][DEBUGFS_GLOBAL].data; + int dump_index = hisi_hba->debugfs_dump_index; + u32 *databuf = hisi_hba->debugfs_regs[dump_index][DEBUGFS_GLOBAL].data; const struct hisi_sas_hw *hw = hisi_hba->hw; const struct hisi_sas_debugfs_reg *global = hw->debugfs_reg_array[DEBUGFS_GLOBAL]; @@ -2823,7 +2827,8 @@ static void hisi_sas_debugfs_snapshot_global_reg(struct hisi_hba *hisi_hba) static void hisi_sas_debugfs_snapshot_axi_reg(struct hisi_hba *hisi_hba) { - u32 *databuf = hisi_hba->debugfs_regs[0][DEBUGFS_AXI].data; + int dump_index = hisi_hba->debugfs_dump_index; + u32 *databuf = hisi_hba->debugfs_regs[dump_index][DEBUGFS_AXI].data; const struct hisi_sas_hw *hw = hisi_hba->hw; const struct hisi_sas_debugfs_reg *axi = hw->debugfs_reg_array[DEBUGFS_AXI]; @@ -2836,7 +2841,8 @@ static void hisi_sas_debugfs_snapshot_axi_reg(struct hisi_hba *hisi_hba) static void hisi_sas_debugfs_snapshot_ras_reg(struct hisi_hba *hisi_hba) { - u32 *databuf = hisi_hba->debugfs_regs[0][DEBUGFS_RAS].data; + int dump_index = hisi_hba->debugfs_dump_index; + u32 *databuf = hisi_hba->debugfs_regs[dump_index][DEBUGFS_RAS].data; const struct hisi_sas_hw *hw = hisi_hba->hw; const struct hisi_sas_debugfs_reg *ras = hw->debugfs_reg_array[DEBUGFS_RAS]; @@ -2849,8 +2855,9 @@ static void hisi_sas_debugfs_snapshot_ras_reg(struct hisi_hba *hisi_hba) static void hisi_sas_debugfs_snapshot_itct_reg(struct hisi_hba *hisi_hba) { - void *cachebuf = hisi_hba->debugfs_itct_cache[0].cache; - void *databuf = hisi_hba->debugfs_itct[0].itct; + int dump_index = hisi_hba->debugfs_dump_index; + void *cachebuf = hisi_hba->debugfs_itct_cache[dump_index].cache; + void *databuf = hisi_hba->debugfs_itct[dump_index].itct; struct hisi_sas_itct *itct; int i; @@ -2867,9 +2874,10 @@ static void hisi_sas_debugfs_snapshot_itct_reg(struct hisi_hba *hisi_hba) static void hisi_sas_debugfs_snapshot_iost_reg(struct hisi_hba *hisi_hba) { + int dump_index = hisi_hba->debugfs_dump_index; int max_command_entries = HISI_SAS_MAX_COMMANDS; - void *cachebuf = hisi_hba->debugfs_iost_cache[0].cache; - void *databuf = hisi_hba->debugfs_iost[0].iost; + void *cachebuf = hisi_hba->debugfs_iost_cache[dump_index].cache; + void *databuf = hisi_hba->debugfs_iost[dump_index].iost; struct hisi_sas_iost *iost; int i; @@ -3648,6 +3656,7 @@ static const struct file_operations hisi_sas_debugfs_itct_cache_fops = { static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) { u64 *debugfs_timestamp; + int dump_index = hisi_hba->debugfs_dump_index; struct dentry *dump_dentry; struct dentry *dentry; char name[256]; @@ -3655,17 +3664,17 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) int c; int d; - debugfs_timestamp = &hisi_hba->debugfs_timestamp; - /* Create dump dir inside device dir */ - dump_dentry = debugfs_create_dir("dump", hisi_hba->debugfs_dir); + snprintf(name, 256, "%d", dump_index); - hisi_hba->debugfs_dump_dentry = dump_dentry; + dump_dentry = debugfs_create_dir(name, hisi_hba->debugfs_dump_dentry); + + debugfs_timestamp = &hisi_hba->debugfs_timestamp[dump_index]; debugfs_create_u64("timestamp", 0400, dump_dentry, debugfs_timestamp); debugfs_create_file("global", 0400, dump_dentry, - &hisi_hba->debugfs_regs[0][DEBUGFS_GLOBAL], + &hisi_hba->debugfs_regs[dump_index][DEBUGFS_GLOBAL], &hisi_sas_debugfs_global_fops); /* Create port dir and files */ @@ -3674,7 +3683,7 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) for (p = 0; p < hisi_hba->n_phy; p++) { snprintf(name, sizeof(name), "%d", p); debugfs_create_file(name, 0400, dentry, - &hisi_hba->debugfs_port_reg[0][p], + &hisi_hba->debugfs_port_reg[dump_index][p], &hisi_sas_debugfs_port_fops); } @@ -3685,7 +3694,7 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) snprintf(name, sizeof(name), "%d", c); debugfs_create_file(name, 0400, dentry, - &hisi_hba->debugfs_cq[0][c], + &hisi_hba->debugfs_cq[dump_index][c], &hisi_sas_debugfs_cq_fops); } @@ -3696,32 +3705,32 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) snprintf(name, sizeof(name), "%d", d); debugfs_create_file(name, 0400, dentry, - &hisi_hba->debugfs_dq[0][d], + &hisi_hba->debugfs_dq[dump_index][d], &hisi_sas_debugfs_dq_fops); } debugfs_create_file("iost", 0400, dump_dentry, - &hisi_hba->debugfs_iost[0], + &hisi_hba->debugfs_iost[dump_index], &hisi_sas_debugfs_iost_fops); debugfs_create_file("iost_cache", 0400, dump_dentry, - &hisi_hba->debugfs_iost_cache[0], + &hisi_hba->debugfs_iost_cache[dump_index], &hisi_sas_debugfs_iost_cache_fops); debugfs_create_file("itct", 0400, dump_dentry, - &hisi_hba->debugfs_itct[0], + &hisi_hba->debugfs_itct[dump_index], &hisi_sas_debugfs_itct_fops); debugfs_create_file("itct_cache", 0400, dump_dentry, - &hisi_hba->debugfs_itct_cache[0], + &hisi_hba->debugfs_itct_cache[dump_index], &hisi_sas_debugfs_itct_cache_fops); debugfs_create_file("axi", 0400, dump_dentry, - &hisi_hba->debugfs_regs[0][DEBUGFS_AXI], + &hisi_hba->debugfs_regs[dump_index][DEBUGFS_AXI], &hisi_sas_debugfs_axi_fops); debugfs_create_file("ras", 0400, dump_dentry, - &hisi_hba->debugfs_regs[0][DEBUGFS_RAS], + &hisi_hba->debugfs_regs[dump_index][DEBUGFS_RAS], &hisi_sas_debugfs_ras_fops); return; @@ -3761,6 +3770,8 @@ static ssize_t hisi_sas_debugfs_trigger_dump_write(struct file *file, * If not 0, will return -EFAULT. * Keep manual dump as one time only */ + if (hisi_hba->debugfs_dump_index >= hisi_sas_debugfs_dump_count) + return -EFAULT; /* Not allow to input more than 8 char */ if (count > sizeof(buf)) @@ -3786,15 +3797,20 @@ void hisi_sas_debugfs_work_handler(struct work_struct *work) { struct hisi_hba *hisi_hba = container_of(work, struct hisi_hba, debugfs_work); + int debugfs_dump_index = hisi_hba->debugfs_dump_index; + struct device *dev = hisi_hba->dev; u64 timestamp = local_clock(); - do_div(timestamp, NSEC_PER_MSEC); - hisi_hba->debugfs_timestamp = timestamp; - if (hisi_hba->debugfs_snapshot) + if (debugfs_dump_index >= hisi_sas_debugfs_dump_count) { + dev_warn(dev, "dump count exceeded!\n"); return; - hisi_hba->debugfs_snapshot = true; + } + + do_div(timestamp, NSEC_PER_MSEC); + hisi_hba->debugfs_timestamp[debugfs_dump_index] = timestamp; hisi_sas_debugfs_snapshot_regs(hisi_hba); + hisi_hba->debugfs_dump_index++; } EXPORT_SYMBOL_GPL(hisi_sas_debugfs_work_handler); -- 2.27.0