未验证 提交 4aeec9ec 编写于 作者: O openeuler-ci-bot 提交者: Gitee

!64 scsi: mpt3sas: Transition IOC to Ready state during shutdown

Merge Pull Request from: @fengfeixi 
 
Before kernel 5.14, the scsih_shutdown function in the mpt3sas driver directly calls mpt3sas_base_detach to release all resources.
Therefore, when the system shutdown process is slow, the problem of scsih_qcmd accessing the ioc->request resource that has been released (set to NULL) will be triggered probabilistically due to the problem of the ioc firmware itself. Eventually leading to kernel panic.

Part of the call stack is as follows:
```
crash> bt
PID: 6293   TASK: ffff00ff91244d80  CPU: 30  COMMAND: "kworker/30:1H"
 #0 [ffff8000259934d0] machine_kexec at ffff800010031aec
 #1 [ffff800025993520] __crash_kexec at ffff80001015048c
 #2 [ffff8000259936c0] crash_kexec at ffff8000101505a0 
…………
 #12 [ffff800025993a20] memset at ffff8000104fa068
 #13 [ffff800025993a80] scsi_queue_rq at ffff80001073e930
 #14 [ffff800025993ae0] blk_mq_dispatch_rq_list at ffff80001047e3fc
 #15 [ffff800025993bd0] __blk_mq_sched_dispatch_requests at ffff800010484814
 #16 [ffff800025993c30] blk_mq_sched_dispatch_requests at ffff800010484a5c
 #17 [ffff800025993c50] __blk_mq_run_hw_queue at ffff80001047cc98  
 #18 [ffff800025993c70] __blk_mq_delay_run_hw_queue at ffff80001047cf38
 #19 [ffff800025993cc0] blk_mq_run_hw_queue at ffff80001047d064
 #20 [ffff800025993cf0] blk_mq_run_hw_queues at ffff80001047d114
 #21 [ffff800025993d20] blk_mq_requeue_work at ffff80001047eff0
 #22 [ffff800025993d90] process_one_work at ffff8000100a4520
 #23 [ffff800025993de0] worker_thread at ffff8000100a47f8
 #24 [ffff800025993e50] kthread at ffff8000100abecc 
```

Part of the data of the accessed ioc (MPT3SAS_ADAPTER structure), ioc->request request is empty.
```
crash> struct MPT3SAS_ADAPTER 0xffff00ff85806880
struct MPT3SAS_ADAPTER {
  list = {
    next = 0xffff800008eb8038 <mpt3sas_ioc_list>,
    prev = 0xffff800008eb8038 <mpt3sas_ioc_list>
  },
  ...
  name = "mpt3sas_cm0\000\000\000\000\000\000\000\
  ...
  remove_host = 1 '\001',
  ...
  request_sz = 128,
  request = 0x0,
  ...
  sense = 0x0, 
```

The kernel 5.14 upstream patch optimizes the scsih_shutdown process, the ioc memory pool will not be released immediately and ioc->shost_recovery = 1 to ensure that the queuecommand operation will not be performed in the future. 
 
Link:https://gitee.com/openeuler/kernel/pulls/64 
Reviewed-by: Zheng Zengkai <zhengzengkai@huawei.com> 
Signed-off-by: Xie XiuQi <xiexiuqi@huawei.com> 
...@@ -2900,13 +2900,13 @@ _base_check_enable_msix(struct MPT3SAS_ADAPTER *ioc) ...@@ -2900,13 +2900,13 @@ _base_check_enable_msix(struct MPT3SAS_ADAPTER *ioc)
} }
/** /**
* _base_free_irq - free irq * mpt3sas_base_free_irq - free irq
* @ioc: per adapter object * @ioc: per adapter object
* *
* Freeing respective reply_queue from the list. * Freeing respective reply_queue from the list.
*/ */
static void void
_base_free_irq(struct MPT3SAS_ADAPTER *ioc) mpt3sas_base_free_irq(struct MPT3SAS_ADAPTER *ioc)
{ {
struct adapter_reply_queue *reply_q, *next; struct adapter_reply_queue *reply_q, *next;
...@@ -3108,12 +3108,12 @@ _base_check_and_enable_high_iops_queues(struct MPT3SAS_ADAPTER *ioc, ...@@ -3108,12 +3108,12 @@ _base_check_and_enable_high_iops_queues(struct MPT3SAS_ADAPTER *ioc,
} }
/** /**
* _base_disable_msix - disables msix * mpt3sas_base_disable_msix - disables msix
* @ioc: per adapter object * @ioc: per adapter object
* *
*/ */
static void void
_base_disable_msix(struct MPT3SAS_ADAPTER *ioc) mpt3sas_base_disable_msix(struct MPT3SAS_ADAPTER *ioc)
{ {
if (!ioc->msix_enable) if (!ioc->msix_enable)
return; return;
...@@ -3221,8 +3221,8 @@ _base_enable_msix(struct MPT3SAS_ADAPTER *ioc) ...@@ -3221,8 +3221,8 @@ _base_enable_msix(struct MPT3SAS_ADAPTER *ioc)
for (i = 0; i < ioc->reply_queue_count; i++) { for (i = 0; i < ioc->reply_queue_count; i++) {
r = _base_request_irq(ioc, i); r = _base_request_irq(ioc, i);
if (r) { if (r) {
_base_free_irq(ioc); mpt3sas_base_free_irq(ioc);
_base_disable_msix(ioc); mpt3sas_base_disable_msix(ioc);
goto try_ioapic; goto try_ioapic;
} }
} }
...@@ -3259,8 +3259,8 @@ mpt3sas_base_unmap_resources(struct MPT3SAS_ADAPTER *ioc) ...@@ -3259,8 +3259,8 @@ mpt3sas_base_unmap_resources(struct MPT3SAS_ADAPTER *ioc)
dexitprintk(ioc, ioc_info(ioc, "%s\n", __func__)); dexitprintk(ioc, ioc_info(ioc, "%s\n", __func__));
_base_free_irq(ioc); mpt3sas_base_free_irq(ioc);
_base_disable_msix(ioc); mpt3sas_base_disable_msix(ioc);
kfree(ioc->replyPostRegisterIndex); kfree(ioc->replyPostRegisterIndex);
ioc->replyPostRegisterIndex = NULL; ioc->replyPostRegisterIndex = NULL;
...@@ -6908,14 +6908,14 @@ _base_diag_reset(struct MPT3SAS_ADAPTER *ioc) ...@@ -6908,14 +6908,14 @@ _base_diag_reset(struct MPT3SAS_ADAPTER *ioc)
} }
/** /**
* _base_make_ioc_ready - put controller in READY state * mpt3sas_base_make_ioc_ready - put controller in READY state
* @ioc: per adapter object * @ioc: per adapter object
* @type: FORCE_BIG_HAMMER or SOFT_RESET * @type: FORCE_BIG_HAMMER or SOFT_RESET
* *
* Return: 0 for success, non-zero for failure. * Return: 0 for success, non-zero for failure.
*/ */
static int int
_base_make_ioc_ready(struct MPT3SAS_ADAPTER *ioc, enum reset_type type) mpt3sas_base_make_ioc_ready(struct MPT3SAS_ADAPTER *ioc, enum reset_type type)
{ {
u32 ioc_state; u32 ioc_state;
int rc; int rc;
...@@ -7189,7 +7189,7 @@ mpt3sas_base_free_resources(struct MPT3SAS_ADAPTER *ioc) ...@@ -7189,7 +7189,7 @@ mpt3sas_base_free_resources(struct MPT3SAS_ADAPTER *ioc)
if (ioc->chip_phys && ioc->chip) { if (ioc->chip_phys && ioc->chip) {
mpt3sas_base_mask_interrupts(ioc); mpt3sas_base_mask_interrupts(ioc);
ioc->shost_recovery = 1; ioc->shost_recovery = 1;
_base_make_ioc_ready(ioc, SOFT_RESET); mpt3sas_base_make_ioc_ready(ioc, SOFT_RESET);
ioc->shost_recovery = 0; ioc->shost_recovery = 0;
} }
...@@ -7308,7 +7308,7 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) ...@@ -7308,7 +7308,7 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
ioc->build_sg_mpi = &_base_build_sg; ioc->build_sg_mpi = &_base_build_sg;
ioc->build_zero_len_sge_mpi = &_base_build_zero_len_sge; ioc->build_zero_len_sge_mpi = &_base_build_zero_len_sge;
r = _base_make_ioc_ready(ioc, SOFT_RESET); r = mpt3sas_base_make_ioc_ready(ioc, SOFT_RESET);
if (r) if (r)
goto out_free_resources; goto out_free_resources;
...@@ -7758,7 +7758,7 @@ mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc, ...@@ -7758,7 +7758,7 @@ mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc,
_base_pre_reset_handler(ioc); _base_pre_reset_handler(ioc);
mpt3sas_wait_for_commands_to_complete(ioc); mpt3sas_wait_for_commands_to_complete(ioc);
mpt3sas_base_mask_interrupts(ioc); mpt3sas_base_mask_interrupts(ioc);
r = _base_make_ioc_ready(ioc, type); r = mpt3sas_base_make_ioc_ready(ioc, type);
if (r) if (r)
goto out; goto out;
_base_clear_outstanding_commands(ioc); _base_clear_outstanding_commands(ioc);
......
...@@ -1599,6 +1599,10 @@ do { ioc_err(ioc, "In func: %s\n", __func__); \ ...@@ -1599,6 +1599,10 @@ do { ioc_err(ioc, "In func: %s\n", __func__); \
status, mpi_request, sz); } while (0) status, mpi_request, sz); } while (0)
int mpt3sas_wait_for_ioc(struct MPT3SAS_ADAPTER *ioc, int wait_count); int mpt3sas_wait_for_ioc(struct MPT3SAS_ADAPTER *ioc, int wait_count);
int
mpt3sas_base_make_ioc_ready(struct MPT3SAS_ADAPTER *ioc, enum reset_type type);
void mpt3sas_base_free_irq(struct MPT3SAS_ADAPTER *ioc);
void mpt3sas_base_disable_msix(struct MPT3SAS_ADAPTER *ioc);
/* scsih shared API */ /* scsih shared API */
struct scsi_cmnd *mpt3sas_scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *mpt3sas_scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER *ioc,
......
...@@ -10275,7 +10275,13 @@ scsih_shutdown(struct pci_dev *pdev) ...@@ -10275,7 +10275,13 @@ scsih_shutdown(struct pci_dev *pdev)
_scsih_ir_shutdown(ioc); _scsih_ir_shutdown(ioc);
_scsih_nvme_shutdown(ioc); _scsih_nvme_shutdown(ioc);
mpt3sas_base_detach(ioc); mpt3sas_base_mask_interrupts(ioc);
mpt3sas_base_stop_watchdog(ioc);
ioc->shost_recovery = 1;
mpt3sas_base_make_ioc_ready(ioc, SOFT_RESET);
ioc->shost_recovery = 0;
mpt3sas_base_free_irq(ioc);
mpt3sas_base_disable_msix(ioc);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册