crypto: hisilicon/qm - place the interrupt status interface after the PM usage counter

To avoid accessing memory of a suspended device, and since the counter
interface used by PM involves sleep operations, the counter interface
cannot be placed in the interrupt top half. Therefore, the interface for
acquiring the interrupt status in the RAS reset flow that resides in the
interrupt context needs to be moved to the bottom half for processing.

Signed-off-by: Zhushuai Yin <yinzhushuai@huawei.com>
Signed-off-by: Zongyu Wu <wuzongyu1@huawei.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
Zhushuai Yin
2026-05-18 22:29:52 +08:00
committed by Herbert Xu
parent e054cdee67
commit 789fc74a22
2 changed files with 18 additions and 17 deletions

View File

@@ -1195,6 +1195,11 @@ static irqreturn_t qm_aeq_thread(int irq, void *data)
atomic64_inc(&qm->debug.dfx.aeq_irq_cnt);
if (qm_pm_get_sync(qm)) {
dev_err(&qm->pdev->dev, "failed to get runtime PM for aeq handle\n");
return IRQ_HANDLED;
}
while (QM_AEQE_PHASE(dw0) == qm->status.aeqc_phase) {
type = (dw0 >> QM_AEQE_TYPE_SHIFT) & QM_AEQE_TYPE_MASK;
qp_id = dw0 & QM_AEQE_CQN_MASK;
@@ -1230,6 +1235,8 @@ static irqreturn_t qm_aeq_thread(int irq, void *data)
qm_db(qm, 0, QM_DOORBELL_CMD_AEQ, qm->status.aeq_head, 0);
qm_pm_put_sync(qm);
return IRQ_HANDLED;
}
@@ -3043,9 +3050,9 @@ void hisi_qm_wait_task_finish(struct hisi_qm *qm, struct hisi_qm_list *qm_list)
msleep(WAIT_PERIOD);
}
while (test_bit(QM_RST_SCHED, &qm->misc_ctl) ||
test_bit(QM_RESETTING, &qm->misc_ctl))
msleep(WAIT_PERIOD);
/* Cancel possible RAS reset process during the uninstallation procedure. */
if (qm->fun_type == QM_HW_PF)
cancel_work_sync(&qm->rst_work);
if (test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps))
flush_work(&qm->cmd_process);
@@ -4595,8 +4602,6 @@ static int qm_controller_reset_prepare(struct hisi_qm *qm)
if (ret)
pci_err(pdev, "failed to stop by vfs in soft reset!\n");
clear_bit(QM_RST_SCHED, &qm->misc_ctl);
return 0;
}
@@ -4914,7 +4919,6 @@ static int qm_controller_reset(struct hisi_qm *qm)
if (ret) {
hisi_qm_set_hw_reset(qm, QM_RESET_STOP_TX_OFFSET);
hisi_qm_set_hw_reset(qm, QM_RESET_STOP_RX_OFFSET);
clear_bit(QM_RST_SCHED, &qm->misc_ctl);
return ret;
}
@@ -5087,14 +5091,13 @@ static irqreturn_t qm_rsvd_irq(int irq, void *data)
static irqreturn_t qm_abnormal_irq(int irq, void *data)
{
struct hisi_qm *qm = data;
enum acc_err_result ret;
atomic64_inc(&qm->debug.dfx.abnormal_irq_cnt);
ret = qm_process_dev_error(qm);
if (ret == ACC_ERR_NEED_RESET &&
!test_bit(QM_DRIVER_REMOVING, &qm->misc_ctl) &&
!test_and_set_bit(QM_RST_SCHED, &qm->misc_ctl))
if (!test_bit(QM_DRIVER_REMOVING, &qm->misc_ctl))
schedule_work(&qm->rst_work);
else
pci_warn(qm->pdev, "Driver is down, need to reload driver!\n");
return IRQ_HANDLED;
}
@@ -5123,14 +5126,13 @@ static void hisi_qm_controller_reset(struct work_struct *rst_work)
ret = qm_pm_get_sync(qm);
if (ret) {
clear_bit(QM_RST_SCHED, &qm->misc_ctl);
dev_err(&qm->pdev->dev, "failed to get runtime PM for controller\n");
return;
}
/* reset pcie device controller */
ret = qm_controller_reset(qm);
if (ret)
dev_err(&qm->pdev->dev, "controller reset failed (%d)\n", ret);
ret = qm_process_dev_error(qm);
if (ret == ACC_ERR_NEED_RESET)
(void)qm_controller_reset(qm);
qm_pm_put_sync(qm);
}

View File

@@ -158,7 +158,6 @@ enum qm_vf_state {
enum qm_misc_ctl_bits {
QM_DRIVER_REMOVING = 0x0,
QM_RST_SCHED,
QM_RESETTING,
QM_MODULE_PARAM,
};