From: Fenghua Yu <fenghua.yu@intel.com>
To: "Vinod Koul" <vkoul@kernel.org>, "Dave Jiang" <dave.jiang@intel.com>
Cc: dmaengine@vger.kernel.org,
"linux-kernel" <linux-kernel@vger.kernel.org>,
Tony Zhu <tony.zhu@intel.com>, Fenghua Yu <fenghua.yu@intel.com>
Subject: [PATCH v4 13/16] dmaengine: idxd: add a device to represent the file opened
Date: Fri, 7 Apr 2023 13:31:40 -0700 [thread overview]
Message-ID: <20230407203143.2189681-14-fenghua.yu@intel.com> (raw)
In-Reply-To: <20230407203143.2189681-1-fenghua.yu@intel.com>
From: Dave Jiang <dave.jiang@intel.com>
Embed a struct device for the user file context in order to export sysfs
attributes related with the opened file. Tie the lifetime of the file
context to the device. The sysfs entry will be added under the char device.
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>
---
drivers/dma/idxd/cdev.c | 119 ++++++++++++++++++++++++++++++++--------
drivers/dma/idxd/idxd.h | 2 +
2 files changed, 97 insertions(+), 24 deletions(-)
diff --git a/drivers/dma/idxd/cdev.c b/drivers/dma/idxd/cdev.c
index 5c8e964e671b..e07411053e21 100644
--- a/drivers/dma/idxd/cdev.c
+++ b/drivers/dma/idxd/cdev.c
@@ -23,6 +23,13 @@ struct idxd_cdev_context {
struct ida minor_ida;
};
+/*
+ * Since user file names are global in DSA devices, define their ida's as
+ * global to avoid conflict file names.
+ */
+static DEFINE_IDA(file_ida);
+static DEFINE_MUTEX(ida_lock);
+
/*
* ictx is an array based off of accelerator types. enum idxd_type
* is used as index
@@ -39,7 +46,60 @@ struct idxd_user_context {
struct mm_struct *mm;
unsigned int flags;
struct iommu_sva *sva;
+ struct idxd_dev idxd_dev;
u64 counters[COUNTER_MAX];
+ int id;
+};
+
+static void idxd_cdev_evl_drain_pasid(struct idxd_wq *wq, u32 pasid);
+static void idxd_xa_pasid_remove(struct idxd_user_context *ctx);
+
+static inline struct idxd_user_context *dev_to_uctx(struct device *dev)
+{
+ struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev);
+
+ return container_of(idxd_dev, struct idxd_user_context, idxd_dev);
+}
+
+static void idxd_file_dev_release(struct device *dev)
+{
+ struct idxd_user_context *ctx = dev_to_uctx(dev);
+ struct idxd_wq *wq = ctx->wq;
+ struct idxd_device *idxd = wq->idxd;
+ int rc;
+
+ mutex_lock(&ida_lock);
+ ida_free(&file_ida, ctx->id);
+ mutex_unlock(&ida_lock);
+
+ /* Wait for in-flight operations to complete. */
+ if (wq_shared(wq)) {
+ idxd_device_drain_pasid(idxd, ctx->pasid);
+ } else {
+ if (device_user_pasid_enabled(idxd)) {
+ /* The wq disable in the disable pasid function will drain the wq */
+ rc = idxd_wq_disable_pasid(wq);
+ if (rc < 0)
+ dev_err(dev, "wq disable pasid failed.\n");
+ } else {
+ idxd_wq_drain(wq);
+ }
+ }
+
+ if (ctx->sva) {
+ idxd_cdev_evl_drain_pasid(wq, ctx->pasid);
+ iommu_sva_unbind_device(ctx->sva);
+ idxd_xa_pasid_remove(ctx);
+ }
+ kfree(ctx);
+ mutex_lock(&wq->wq_lock);
+ idxd_wq_put(wq);
+ mutex_unlock(&wq->wq_lock);
+}
+
+static struct device_type idxd_cdev_file_type = {
+ .name = "idxd_file",
+ .release = idxd_file_dev_release,
};
static void idxd_cdev_dev_release(struct device *dev)
@@ -107,10 +167,11 @@ static int idxd_cdev_open(struct inode *inode, struct file *filp)
struct idxd_user_context *ctx;
struct idxd_device *idxd;
struct idxd_wq *wq;
- struct device *dev;
+ struct device *dev, *fdev;
int rc = 0;
struct iommu_sva *sva;
unsigned int pasid;
+ struct idxd_cdev *idxd_cdev;
wq = inode_wq(inode);
idxd = wq->idxd;
@@ -166,10 +227,41 @@ static int idxd_cdev_open(struct inode *inode, struct file *filp)
}
}
+ idxd_cdev = wq->idxd_cdev;
+ mutex_lock(&ida_lock);
+ ctx->id = ida_alloc(&file_ida, GFP_KERNEL);
+ mutex_unlock(&ida_lock);
+ if (ctx->id < 0) {
+ dev_warn(dev, "ida alloc failure\n");
+ goto failed_ida;
+ }
+ ctx->idxd_dev.type = IDXD_DEV_CDEV_FILE;
+ fdev = user_ctx_dev(ctx);
+ device_initialize(fdev);
+ fdev->parent = cdev_dev(idxd_cdev);
+ fdev->bus = &dsa_bus_type;
+ fdev->type = &idxd_cdev_file_type;
+
+ rc = dev_set_name(fdev, "file%d", ctx->id);
+ if (rc < 0) {
+ dev_warn(dev, "set name failure\n");
+ goto failed_dev_name;
+ }
+
+ rc = device_add(fdev);
+ if (rc < 0) {
+ dev_warn(dev, "file device add failure\n");
+ goto failed_dev_add;
+ }
+
idxd_wq_get(wq);
mutex_unlock(&wq->wq_lock);
return 0;
+failed_dev_add:
+failed_dev_name:
+ put_device(fdev);
+failed_ida:
failed_set_pasid:
if (device_user_pasid_enabled(idxd))
idxd_xa_pasid_remove(ctx);
@@ -217,34 +309,12 @@ static int idxd_cdev_release(struct inode *node, struct file *filep)
struct idxd_wq *wq = ctx->wq;
struct idxd_device *idxd = wq->idxd;
struct device *dev = &idxd->pdev->dev;
- int rc;
dev_dbg(dev, "%s called\n", __func__);
filep->private_data = NULL;
- /* Wait for in-flight operations to complete. */
- if (wq_shared(wq)) {
- idxd_device_drain_pasid(idxd, ctx->pasid);
- } else {
- if (device_user_pasid_enabled(idxd)) {
- /* The wq disable in the disable pasid function will drain the wq */
- rc = idxd_wq_disable_pasid(wq);
- if (rc < 0)
- dev_err(dev, "wq disable pasid failed.\n");
- } else {
- idxd_wq_drain(wq);
- }
- }
+ device_unregister(user_ctx_dev(ctx));
- if (ctx->sva) {
- idxd_cdev_evl_drain_pasid(wq, ctx->pasid);
- iommu_sva_unbind_device(ctx->sva);
- idxd_xa_pasid_remove(ctx);
- }
- kfree(ctx);
- mutex_lock(&wq->wq_lock);
- idxd_wq_put(wq);
- mutex_unlock(&wq->wq_lock);
return 0;
}
@@ -375,6 +445,7 @@ void idxd_wq_del_cdev(struct idxd_wq *wq)
struct idxd_cdev *idxd_cdev;
idxd_cdev = wq->idxd_cdev;
+ ida_destroy(&file_ida);
wq->idxd_cdev = NULL;
cdev_device_del(&idxd_cdev->cdev, cdev_dev(idxd_cdev));
put_device(cdev_dev(idxd_cdev));
diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h
index 9fb26d017285..bd544eb2ddcb 100644
--- a/drivers/dma/idxd/idxd.h
+++ b/drivers/dma/idxd/idxd.h
@@ -32,6 +32,7 @@ enum idxd_dev_type {
IDXD_DEV_GROUP,
IDXD_DEV_ENGINE,
IDXD_DEV_CDEV,
+ IDXD_DEV_CDEV_FILE,
IDXD_DEV_MAX_TYPE,
};
@@ -405,6 +406,7 @@ enum idxd_completion_status {
#define engine_confdev(engine) &engine->idxd_dev.conf_dev
#define group_confdev(group) &group->idxd_dev.conf_dev
#define cdev_dev(cdev) &cdev->idxd_dev.conf_dev
+#define user_ctx_dev(ctx) (&(ctx)->idxd_dev.conf_dev)
#define confdev_to_idxd_dev(dev) container_of(dev, struct idxd_dev, conf_dev)
#define idxd_dev_to_idxd(idxd_dev) container_of(idxd_dev, struct idxd_device, idxd_dev)
--
2.37.1
next prev parent reply other threads:[~2023-04-07 20:32 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-07 20:31 [PATCH v4 00/16] Enable DSA 2.0 Event Log and completion record faulting features Fenghua Yu
2023-04-07 20:31 ` [PATCH v4 01/16] dmaengine: idxd: make misc interrupt one shot Fenghua Yu
2023-04-07 20:31 ` [PATCH v4 02/16] dmaengine: idxd: add event log size sysfs attribute Fenghua Yu
2023-04-07 20:31 ` [PATCH v4 03/16] dmaengine: idxd: setup event log configuration Fenghua Yu
2023-04-07 20:31 ` [PATCH v4 04/16] dmaengine: idxd: add interrupt handling for event log Fenghua Yu
2023-04-07 20:31 ` [PATCH v4 05/16] dmanegine: idxd: add debugfs for event log dump Fenghua Yu
2023-04-07 20:31 ` [PATCH v4 06/16] dmaengine: idxd: add per DSA wq workqueue for processing cr faults Fenghua Yu
2023-04-07 20:31 ` [PATCH v4 07/16] dmaengine: idxd: create kmem cache for event log fault items Fenghua Yu
2023-04-07 20:31 ` [PATCH v4 08/16] dmaengine: idxd: add idxd_copy_cr() to copy user completion record during page fault handling Fenghua Yu
2023-04-07 20:31 ` [PATCH v4 09/16] dmaengine: idxd: process user page faults for completion record Fenghua Yu
2023-04-07 20:31 ` [PATCH v4 10/16] dmaengine: idxd: add descs_completed field " Fenghua Yu
2023-04-07 20:31 ` [PATCH v4 11/16] dmaengine: idxd: process batch descriptor completion record faults Fenghua Yu
2023-04-07 20:31 ` [PATCH v4 12/16] dmaengine: idxd: add per file user counters for " Fenghua Yu
2023-04-07 20:31 ` Fenghua Yu [this message]
2023-04-07 20:31 ` [PATCH v4 14/16] dmaengine: idxd: expose fault counters to sysfs Fenghua Yu
2023-04-07 20:31 ` [PATCH v4 15/16] dmaengine: idxd: add pid to exported sysfs attribute for opened file Fenghua Yu
2023-04-07 20:31 ` [PATCH v4 16/16] dmaengine: idxd: add per wq PRS disable Fenghua Yu
2023-04-12 17:18 ` [PATCH v4 00/16] Enable DSA 2.0 Event Log and completion record faulting features Vinod Koul
2023-04-12 17:49 ` Fenghua Yu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230407203143.2189681-14-fenghua.yu@intel.com \
--to=fenghua.yu@intel.com \
--cc=dave.jiang@intel.com \
--cc=dmaengine@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=tony.zhu@intel.com \
--cc=vkoul@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox