summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDave Jiang <dave.jiang@intel.com>2023-04-07 22:31:34 +0200
committerVinod Koul <vkoul@kernel.org>2023-04-12 19:48:45 +0200
commitc2f156bf168fb42cd6ecd0a8e2204dbe542b8516 (patch)
tree6235c17693d69f6f9fd45d35a451f20def17d059 /drivers
parentdmaengine: idxd: add per DSA wq workqueue for processing cr faults (diff)
downloadlinux-c2f156bf168fb42cd6ecd0a8e2204dbe542b8516.tar.xz
linux-c2f156bf168fb42cd6ecd0a8e2204dbe542b8516.zip
dmaengine: idxd: create kmem cache for event log fault items
Add a kmem cache per device for allocating event log fault context. The context allows an event log entry to be copied and passed to a software workqueue to be processed. Due to each device can have different sized event log entry depending on device type, it's not possible to have a global kmem cache. Tested-by: Tony Zhu <tony.zhu@intel.com> 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/20230407203143.2189681-8-fenghua.yu@intel.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/dma/idxd/idxd.h10
-rw-r--r--drivers/dma/idxd/init.c9
-rw-r--r--drivers/dma/idxd/sysfs.c1
3 files changed, 20 insertions, 0 deletions
diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h
index 6e56361ae658..c5d99c179902 100644
--- a/drivers/dma/idxd/idxd.h
+++ b/drivers/dma/idxd/idxd.h
@@ -274,6 +274,15 @@ struct idxd_evl {
u16 head;
};
+struct idxd_evl_fault {
+ struct work_struct work;
+ struct idxd_wq *wq;
+ u8 status;
+
+ /* make this last member always */
+ struct __evl_entry entry[];
+};
+
struct idxd_device {
struct idxd_dev idxd_dev;
struct idxd_driver_data *data;
@@ -331,6 +340,7 @@ struct idxd_device {
unsigned long *opcap_bmap;
struct idxd_evl *evl;
+ struct kmem_cache *evl_cache;
struct dentry *dbgfs_dir;
struct dentry *dbgfs_evl_file;
diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
index e21c4b7a1d32..7828ac2d31aa 100644
--- a/drivers/dma/idxd/init.c
+++ b/drivers/dma/idxd/init.c
@@ -345,6 +345,15 @@ static int idxd_init_evl(struct idxd_device *idxd)
spin_lock_init(&evl->lock);
evl->size = IDXD_EVL_SIZE_MIN;
+
+ idxd->evl_cache = kmem_cache_create(dev_name(idxd_confdev(idxd)),
+ sizeof(struct idxd_evl_fault) + evl_ent_size(idxd),
+ 0, 0, NULL);
+ if (!idxd->evl_cache) {
+ kfree(evl);
+ return -ENOMEM;
+ }
+
idxd->evl = evl;
return 0;
}
diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c
index 163fdfaa5022..8b9dfa0d2b99 100644
--- a/drivers/dma/idxd/sysfs.c
+++ b/drivers/dma/idxd/sysfs.c
@@ -1718,6 +1718,7 @@ static void idxd_conf_device_release(struct device *dev)
kfree(idxd->wqs);
kfree(idxd->engines);
kfree(idxd->evl);
+ kmem_cache_destroy(idxd->evl_cache);
ida_free(&idxd_ida, idxd->id);
bitmap_free(idxd->opcap_bmap);
kfree(idxd);