summaryrefslogtreecommitdiff
path: root/drivers/dma/idxd/init.c
diff options
context:
space:
mode:
authorDave Jiang <dave.jiang@intel.com>2022-09-17 19:12:20 +0300
committerVinod Koul <vkoul@kernel.org>2022-09-29 20:16:08 +0300
commitb0325aefd398d8b536ba46ee2e5d24252c1b2258 (patch)
treec161c2f74c0c3988d775c05dfa9e7c453ddb7432 /drivers/dma/idxd/init.c
parenta8563a33a5e26064061f2fb34215c97f0e2995f4 (diff)
downloadlinux-b0325aefd398d8b536ba46ee2e5d24252c1b2258.tar.xz
dmaengine: idxd: add WQ operation cap restriction support
DSA 2.0 add the capability of configuring DMA ops on a per workqueue basis. This means that certain ops can be disabled by the system administrator for certain wq. By default, all ops are available. A bitmap is used to store the ops due to total op size of 256 bits and it is more convenient to use a range list to specify which bits are enabled. One of the usage to support this is for VM migration between different iteration of devices. The newer ops are disabled in order to allow guest to migrate to a host that only support older ops. Another usage is to restrict the WQ to certain operations for QoS of performance. A sysfs of ops_config attribute is added per wq. It is only usable when the ops_config bit is set under WQ_CAP register. This means that this attribute will return -EOPNOTSUPP on DSA 1.x devices. The expected input is a range list for the bits per operation the WQ supports. Signed-off-by: Dave Jiang <dave.jiang@intel.com> Co-developed-by: Fenghua Yu <fenghua.yu@intel.com> Signed-off-by: Fenghua Yu <fenghua.yu@intel.com> Link: https://lore.kernel.org/r/20220917161222.2835172-4-fenghua.yu@intel.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
Diffstat (limited to 'drivers/dma/idxd/init.c')
-rw-r--r--drivers/dma/idxd/init.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
index f6f0654a79b8..2b18d512cbfc 100644
--- a/drivers/dma/idxd/init.c
+++ b/drivers/dma/idxd/init.c
@@ -191,6 +191,16 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
rc = -ENOMEM;
goto err;
}
+
+ if (idxd->hw.wq_cap.op_config) {
+ wq->opcap_bmap = bitmap_zalloc(IDXD_MAX_OPCAP_BITS, GFP_KERNEL);
+ if (!wq->opcap_bmap) {
+ put_device(conf_dev);
+ rc = -ENOMEM;
+ goto err;
+ }
+ bitmap_copy(wq->opcap_bmap, idxd->opcap_bmap, IDXD_MAX_OPCAP_BITS);
+ }
idxd->wqs[i] = wq;
}