From 90cc4420a84431073119cf93ab44e5ee0322c542 Mon Sep 17 00:00:00 2001 From: Fengqian Gao Date: Sat, 17 Sep 2022 10:05:14 +0800 Subject: [PATCH] dmaengine: idxd: fix RO device state error after been disabled/reset ANBZ: #2268 cherry-picked from https://lore.kernel.org/all/20220930032835.2290-1-fengqian.gao@intel.com/ When IDXD is not configurable, that means its WQ, engine, and group configurations cannot be changed. But it can be disabled and its state should be set as disabled regardless it's configurable or not. Fix this by setting device state IDXD_DEV_DISABLED for read-only device as well in idxd_device_clear_state(). Intel-SIG: dmaengine: idxd: fix RO device state error after been disabled/reset. Fixes: e6b1e383196b ("dmaengine: idxd: fix lockdep warning on device driver removal") Signed-off-by: Fengqian Gao [ Fengqian Gao: amend commit log ] Reviewed-by: Xiaochen Shen Reviewed-by: Dave Jiang Reviewed-by: Fenghua Yu Link: https://gitee.com/anolis/cloud-kernel/pulls/756 Reviewed-by: Artie Ding --- drivers/dma/idxd/device.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c index ea5e307e4059..79245dbd3357 100644 --- a/drivers/dma/idxd/device.c +++ b/drivers/dma/idxd/device.c @@ -900,13 +900,21 @@ static void idxd_device_wqs_clear_state(struct idxd_device *idxd) void idxd_device_clear_state(struct idxd_device *idxd) { - if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) - return; + /* IDXD is always disabled. Other states are cleared only when IDXD is configurable. */ + if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) { + /* + * Clearing wq state is protected by wq lock. + * So no need to be protected by device lock. + */ + idxd_device_wqs_clear_state(idxd); + + spin_lock(&idxd->dev_lock); + idxd_groups_clear_state(idxd); + idxd_engines_clear_state(idxd); + } else { + spin_lock(&idxd->dev_lock); + } - idxd_device_wqs_clear_state(idxd); - spin_lock(&idxd->dev_lock); - idxd_groups_clear_state(idxd); - idxd_engines_clear_state(idxd); idxd->state = IDXD_DEV_DISABLED; spin_unlock(&idxd->dev_lock); } -- Gitee