* [PATCH] dmaengine: idxd: don't load pasid config until needed
@ 2022-03-04 21:21 Dave Jiang
2022-03-10 16:14 ` Dave Jiang
0 siblings, 1 reply; 2+ messages in thread
From: Dave Jiang @ 2022-03-04 21:21 UTC (permalink / raw)
To: vkoul; +Cc: dmaengine
The driver currently programs the system pasid to the WQ preemptively when
system pasid is enabled. Given that a dwq will reprogram the pasid and
possibly a different pasid, the programming is not necessary. The pasid_en
bit can be set for swq as it does not need pasid pasid programming but
needs the pasid_en bit. Remove system pasid programming on device config
write. Add pasid programming for kernel wq type on wq driver enable. The
char dev driver already reprograms the dwq on ->open() call so there's no
change.
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
drivers/dma/idxd/device.c | 46 ++++++++++++++++++++++++++++++++++--------
drivers/dma/idxd/registers.h | 1 +
2 files changed, 38 insertions(+), 9 deletions(-)
diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c
index 573ad8b86804..b2aaf4b64a8b 100644
--- a/drivers/dma/idxd/device.c
+++ b/drivers/dma/idxd/device.c
@@ -299,16 +299,25 @@ void idxd_wqs_unmap_portal(struct idxd_device *idxd)
}
}
-int idxd_wq_set_pasid(struct idxd_wq *wq, int pasid)
+static void __idxd_wq_set_priv_locked(struct idxd_wq *wq)
{
struct idxd_device *idxd = wq->idxd;
- int rc;
union wqcfg wqcfg;
unsigned int offset;
- rc = idxd_wq_disable(wq, false);
- if (rc < 0)
- return rc;
+ offset = WQCFG_OFFSET(idxd, wq->id, WQCFG_PRIVL_IDX);
+ spin_lock(&idxd->dev_lock);
+ wqcfg.bits[WQCFG_PRIVL_IDX] = ioread32(idxd->reg_base + offset);
+ wqcfg.priv = 1;
+ iowrite32(wqcfg.bits[WQCFG_PRIVL_IDX], idxd->reg_base + offset);
+ spin_unlock(&idxd->dev_lock);
+}
+
+static void __idxd_wq_set_pasid_locked(struct idxd_wq *wq, int pasid)
+{
+ struct idxd_device *idxd = wq->idxd;
+ union wqcfg wqcfg;
+ unsigned int offset;
offset = WQCFG_OFFSET(idxd, wq->id, WQCFG_PASID_IDX);
spin_lock(&idxd->dev_lock);
@@ -317,6 +326,17 @@ int idxd_wq_set_pasid(struct idxd_wq *wq, int pasid)
wqcfg.pasid = pasid;
iowrite32(wqcfg.bits[WQCFG_PASID_IDX], idxd->reg_base + offset);
spin_unlock(&idxd->dev_lock);
+}
+
+int idxd_wq_set_pasid(struct idxd_wq *wq, int pasid)
+{
+ int rc;
+
+ rc = idxd_wq_disable(wq, false);
+ if (rc < 0)
+ return rc;
+
+ __idxd_wq_set_pasid_locked(wq, pasid);
rc = idxd_wq_enable(wq);
if (rc < 0)
@@ -808,11 +828,13 @@ static int idxd_wq_config_write(struct idxd_wq *wq)
if (wq_dedicated(wq))
wq->wqcfg->mode = 1;
- if (device_pasid_enabled(idxd)) {
+ /*
+ * Enable this for shared WQ. swq does not need to program the pasid field,
+ * but pasid_en needs to be set. Programming here prevents swq needing to
+ * be disabled and re-enabled for reprogramming, which is something to avoid.
+ */
+ if (device_pasid_enabled(idxd))
wq->wqcfg->pasid_en = 1;
- if (wq->type == IDXD_WQT_KERNEL && wq_dedicated(wq))
- wq->wqcfg->pasid = idxd->pasid;
- }
/*
* Here the priv bit is set depending on the WQ type. priv = 1 if the
@@ -1258,6 +1280,12 @@ int __drv_enable_wq(struct idxd_wq *wq)
}
}
+ if (is_idxd_wq_kernel(wq)) {
+ if (device_pasid_enabled(idxd) && wq_dedicated(wq))
+ __idxd_wq_set_pasid_locked(wq, idxd->pasid);
+ __idxd_wq_set_priv_locked(wq);
+ }
+
rc = 0;
spin_lock(&idxd->dev_lock);
if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags))
diff --git a/drivers/dma/idxd/registers.h b/drivers/dma/idxd/registers.h
index aa642aecdc0b..02449aa9c454 100644
--- a/drivers/dma/idxd/registers.h
+++ b/drivers/dma/idxd/registers.h
@@ -353,6 +353,7 @@ union wqcfg {
} __packed;
#define WQCFG_PASID_IDX 2
+#define WQCFG_PRIVL_IDX 2
#define WQCFG_OCCUP_IDX 6
#define WQCFG_OCCUP_MASK 0xffff
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] dmaengine: idxd: don't load pasid config until needed
2022-03-04 21:21 [PATCH] dmaengine: idxd: don't load pasid config until needed Dave Jiang
@ 2022-03-10 16:14 ` Dave Jiang
0 siblings, 0 replies; 2+ messages in thread
From: Dave Jiang @ 2022-03-10 16:14 UTC (permalink / raw)
To: vkoul; +Cc: dmaengine
On 3/4/2022 2:21 PM, Dave Jiang wrote:
> The driver currently programs the system pasid to the WQ preemptively when
> system pasid is enabled. Given that a dwq will reprogram the pasid and
> possibly a different pasid, the programming is not necessary. The pasid_en
> bit can be set for swq as it does not need pasid pasid programming but
> needs the pasid_en bit. Remove system pasid programming on device config
> write. Add pasid programming for kernel wq type on wq driver enable. The
> char dev driver already reprograms the dwq on ->open() call so there's no
> change.
>
> Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Vinod, pls ignore this patch. There will be a v2.
> ---
> drivers/dma/idxd/device.c | 46 ++++++++++++++++++++++++++++++++++--------
> drivers/dma/idxd/registers.h | 1 +
> 2 files changed, 38 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c
> index 573ad8b86804..b2aaf4b64a8b 100644
> --- a/drivers/dma/idxd/device.c
> +++ b/drivers/dma/idxd/device.c
> @@ -299,16 +299,25 @@ void idxd_wqs_unmap_portal(struct idxd_device *idxd)
> }
> }
>
> -int idxd_wq_set_pasid(struct idxd_wq *wq, int pasid)
> +static void __idxd_wq_set_priv_locked(struct idxd_wq *wq)
> {
> struct idxd_device *idxd = wq->idxd;
> - int rc;
> union wqcfg wqcfg;
> unsigned int offset;
>
> - rc = idxd_wq_disable(wq, false);
> - if (rc < 0)
> - return rc;
> + offset = WQCFG_OFFSET(idxd, wq->id, WQCFG_PRIVL_IDX);
> + spin_lock(&idxd->dev_lock);
> + wqcfg.bits[WQCFG_PRIVL_IDX] = ioread32(idxd->reg_base + offset);
> + wqcfg.priv = 1;
> + iowrite32(wqcfg.bits[WQCFG_PRIVL_IDX], idxd->reg_base + offset);
> + spin_unlock(&idxd->dev_lock);
> +}
> +
> +static void __idxd_wq_set_pasid_locked(struct idxd_wq *wq, int pasid)
> +{
> + struct idxd_device *idxd = wq->idxd;
> + union wqcfg wqcfg;
> + unsigned int offset;
>
> offset = WQCFG_OFFSET(idxd, wq->id, WQCFG_PASID_IDX);
> spin_lock(&idxd->dev_lock);
> @@ -317,6 +326,17 @@ int idxd_wq_set_pasid(struct idxd_wq *wq, int pasid)
> wqcfg.pasid = pasid;
> iowrite32(wqcfg.bits[WQCFG_PASID_IDX], idxd->reg_base + offset);
> spin_unlock(&idxd->dev_lock);
> +}
> +
> +int idxd_wq_set_pasid(struct idxd_wq *wq, int pasid)
> +{
> + int rc;
> +
> + rc = idxd_wq_disable(wq, false);
> + if (rc < 0)
> + return rc;
> +
> + __idxd_wq_set_pasid_locked(wq, pasid);
>
> rc = idxd_wq_enable(wq);
> if (rc < 0)
> @@ -808,11 +828,13 @@ static int idxd_wq_config_write(struct idxd_wq *wq)
> if (wq_dedicated(wq))
> wq->wqcfg->mode = 1;
>
> - if (device_pasid_enabled(idxd)) {
> + /*
> + * Enable this for shared WQ. swq does not need to program the pasid field,
> + * but pasid_en needs to be set. Programming here prevents swq needing to
> + * be disabled and re-enabled for reprogramming, which is something to avoid.
> + */
> + if (device_pasid_enabled(idxd))
> wq->wqcfg->pasid_en = 1;
> - if (wq->type == IDXD_WQT_KERNEL && wq_dedicated(wq))
> - wq->wqcfg->pasid = idxd->pasid;
> - }
>
> /*
> * Here the priv bit is set depending on the WQ type. priv = 1 if the
> @@ -1258,6 +1280,12 @@ int __drv_enable_wq(struct idxd_wq *wq)
> }
> }
>
> + if (is_idxd_wq_kernel(wq)) {
> + if (device_pasid_enabled(idxd) && wq_dedicated(wq))
> + __idxd_wq_set_pasid_locked(wq, idxd->pasid);
> + __idxd_wq_set_priv_locked(wq);
> + }
> +
> rc = 0;
> spin_lock(&idxd->dev_lock);
> if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags))
> diff --git a/drivers/dma/idxd/registers.h b/drivers/dma/idxd/registers.h
> index aa642aecdc0b..02449aa9c454 100644
> --- a/drivers/dma/idxd/registers.h
> +++ b/drivers/dma/idxd/registers.h
> @@ -353,6 +353,7 @@ union wqcfg {
> } __packed;
>
> #define WQCFG_PASID_IDX 2
> +#define WQCFG_PRIVL_IDX 2
> #define WQCFG_OCCUP_IDX 6
>
> #define WQCFG_OCCUP_MASK 0xffff
>
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2022-03-10 16:14 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-04 21:21 [PATCH] dmaengine: idxd: don't load pasid config until needed Dave Jiang
2022-03-10 16:14 ` Dave Jiang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).