dmaengine: idxd: create kmem cache for event log fault items
authorDave Jiang <dave.jiang@intel.com>
Fri, 7 Apr 2023 20:31:34 +0000 (13:31 -0700)
committerVinod Koul <vkoul@kernel.org>
Wed, 12 Apr 2023 17:48:45 +0000 (23:18 +0530)
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>
drivers/dma/idxd/idxd.h
drivers/dma/idxd/init.c
drivers/dma/idxd/sysfs.c

index 6e56361ae658b557348860eec0c789833ee388eb..c5d99c1799022c177f948d5b4c138e5aabd66d03 100644 (file)
@@ -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;
index e21c4b7a1d32f075b8453c53c35504cfd7e31d8e..7828ac2d31aa3e9adbe2c8225a2e322b568fd614 100644 (file)
@@ -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;
 }
index 163fdfaa502236e4d5491969147f114bcc717d01..8b9dfa0d2b99430370697d67426576970fba10bf 100644 (file)
@@ -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);