]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
dmaengine: idxd: fix RO device state error after been disabled/reset
authorFengqian Gao <fengqian.gao@intel.com>
Fri, 30 Sep 2022 03:28:35 +0000 (11:28 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 16 Nov 2022 09:03:57 +0000 (10:03 +0100)
[ Upstream commit 0b8c97a1d8c1bb6a853b8bb1778e8fef17b86fc9 ]

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().

Fixes: cf4ac3fef338 ("dmaengine: idxd: fix lockdep warning on device driver removal")
Signed-off-by: Fengqian Gao <fengqian.gao@intel.com>
Reviewed-by: Xiaochen Shen <xiaochen.shen@intel.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Fenghua Yu <fenghua.yu@intel.com>
Link: https://lore.kernel.org/r/20220930032835.2290-1-fengqian.gao@intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/dma/idxd/device.c

index cc7aabe4dc840fc31377639d367c15f4b5ed9222..bd6e50f795bebc977ea9ae8be3243b03eedfd52b 100644 (file)
@@ -724,13 +724,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);
 }