Commit 3157dd0a authored by Dave Jiang's avatar Dave Jiang Committed by Vinod Koul

dmaengine: idxd: don't load pasid config until needed

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 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: default avatarDave Jiang <dave.jiang@intel.com>
Link: https://lore.kernel.org/r/164935607115.1660372.6734518676950372366.stgit@djiang5-desk3.ch.intel.comSigned-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent 80380f89
...@@ -299,24 +299,46 @@ void idxd_wqs_unmap_portal(struct idxd_device *idxd) ...@@ -299,24 +299,46 @@ 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, int priv)
{ {
struct idxd_device *idxd = wq->idxd; struct idxd_device *idxd = wq->idxd;
int rc;
union wqcfg wqcfg; union wqcfg wqcfg;
unsigned int offset; unsigned int offset;
rc = idxd_wq_disable(wq, false); offset = WQCFG_OFFSET(idxd, wq->id, WQCFG_PRIVL_IDX);
if (rc < 0) spin_lock(&idxd->dev_lock);
return rc; wqcfg.bits[WQCFG_PRIVL_IDX] = ioread32(idxd->reg_base + offset);
wqcfg.priv = priv;
wq->wqcfg->bits[WQCFG_PRIVL_IDX] = wqcfg.bits[WQCFG_PRIVL_IDX];
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); offset = WQCFG_OFFSET(idxd, wq->id, WQCFG_PASID_IDX);
spin_lock(&idxd->dev_lock); spin_lock(&idxd->dev_lock);
wqcfg.bits[WQCFG_PASID_IDX] = ioread32(idxd->reg_base + offset); wqcfg.bits[WQCFG_PASID_IDX] = ioread32(idxd->reg_base + offset);
wqcfg.pasid_en = 1; wqcfg.pasid_en = 1;
wqcfg.pasid = pasid; wqcfg.pasid = pasid;
wq->wqcfg->bits[WQCFG_PASID_IDX] = wqcfg.bits[WQCFG_PASID_IDX];
iowrite32(wqcfg.bits[WQCFG_PASID_IDX], idxd->reg_base + offset); iowrite32(wqcfg.bits[WQCFG_PASID_IDX], idxd->reg_base + offset);
spin_unlock(&idxd->dev_lock); 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); rc = idxd_wq_enable(wq);
if (rc < 0) if (rc < 0)
...@@ -797,7 +819,7 @@ static int idxd_wq_config_write(struct idxd_wq *wq) ...@@ -797,7 +819,7 @@ static int idxd_wq_config_write(struct idxd_wq *wq)
*/ */
for (i = 0; i < WQCFG_STRIDES(idxd); i++) { for (i = 0; i < WQCFG_STRIDES(idxd); i++) {
wq_offset = WQCFG_OFFSET(idxd, wq->id, i); wq_offset = WQCFG_OFFSET(idxd, wq->id, i);
wq->wqcfg->bits[i] = ioread32(idxd->reg_base + wq_offset); wq->wqcfg->bits[i] |= ioread32(idxd->reg_base + wq_offset);
} }
if (wq->size == 0 && wq->type != IDXD_WQT_NONE) if (wq->size == 0 && wq->type != IDXD_WQT_NONE)
...@@ -813,14 +835,8 @@ static int idxd_wq_config_write(struct idxd_wq *wq) ...@@ -813,14 +835,8 @@ static int idxd_wq_config_write(struct idxd_wq *wq)
if (wq_dedicated(wq)) if (wq_dedicated(wq))
wq->wqcfg->mode = 1; wq->wqcfg->mode = 1;
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 * The WQ priv bit is set depending on the WQ type. priv = 1 if the
* WQ type is kernel to indicate privileged access. This setting only * WQ type is kernel to indicate privileged access. This setting only
* matters for dedicated WQ. According to the DSA spec: * matters for dedicated WQ. According to the DSA spec:
* If the WQ is in dedicated mode, WQ PASID Enable is 1, and the * If the WQ is in dedicated mode, WQ PASID Enable is 1, and the
...@@ -830,7 +846,6 @@ static int idxd_wq_config_write(struct idxd_wq *wq) ...@@ -830,7 +846,6 @@ static int idxd_wq_config_write(struct idxd_wq *wq)
* In the case of a dedicated kernel WQ that is not able to support * In the case of a dedicated kernel WQ that is not able to support
* the PASID cap, then the configuration will be rejected. * the PASID cap, then the configuration will be rejected.
*/ */
wq->wqcfg->priv = !!(wq->type == IDXD_WQT_KERNEL);
if (wq_dedicated(wq) && wq->wqcfg->pasid_en && if (wq_dedicated(wq) && wq->wqcfg->pasid_en &&
!idxd_device_pasid_priv_enabled(idxd) && !idxd_device_pasid_priv_enabled(idxd) &&
wq->type == IDXD_WQT_KERNEL) { wq->type == IDXD_WQT_KERNEL) {
...@@ -1263,6 +1278,29 @@ int __drv_enable_wq(struct idxd_wq *wq) ...@@ -1263,6 +1278,29 @@ int __drv_enable_wq(struct idxd_wq *wq)
} }
} }
/*
* In the event that the WQ is configurable for pasid and priv bits.
* For kernel wq, the driver should setup the pasid, pasid_en, and priv bit.
* However, for non-kernel wq, the driver should only set the pasid_en bit for
* shared wq. A dedicated wq that is not 'kernel' type will configure pasid and
* pasid_en later on so there is no need to setup.
*/
if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) {
int priv = 0;
if (device_pasid_enabled(idxd)) {
if (is_idxd_wq_kernel(wq) || wq_shared(wq)) {
u32 pasid = wq_dedicated(wq) ? idxd->pasid : 0;
__idxd_wq_set_pasid_locked(wq, pasid);
}
}
if (is_idxd_wq_kernel(wq))
priv = 1;
__idxd_wq_set_priv_locked(wq, priv);
}
rc = 0; rc = 0;
spin_lock(&idxd->dev_lock); spin_lock(&idxd->dev_lock);
if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags))
......
...@@ -353,6 +353,7 @@ union wqcfg { ...@@ -353,6 +353,7 @@ union wqcfg {
} __packed; } __packed;
#define WQCFG_PASID_IDX 2 #define WQCFG_PASID_IDX 2
#define WQCFG_PRIVL_IDX 2
#define WQCFG_OCCUP_IDX 6 #define WQCFG_OCCUP_IDX 6
#define WQCFG_OCCUP_MASK 0xffff #define WQCFG_OCCUP_MASK 0xffff
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment