[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20250620130953.1943703-3-yi.sun@intel.com>
Date: Fri, 20 Jun 2025 21:09:53 +0800
From: Yi Sun <yi.sun@...el.com>
To: dave.jiang@...el.com,
vinicius.gomes@...el.com,
dmaengine@...r.kernel.org,
linux-kernel@...r.kernel.org,
fenghuay@...dia.com,
philip.lantz@...el.com
Cc: yi.sun@...el.com,
gordon.jin@...el.com,
anil.s.keshavamurthy@...el.com
Subject: [PATCH v2 2/2] dmaengine: idxd: Add Max SGL Size Support for DSA3.0
Certain DSA 3.0 opcodes, such as Gather copy and Gather reduce, require max
SGL configured for workqueues prior to supporting these opcodes.
Configure the maximum scatter-gather list (SGL) size for workqueues during
setup on the supported HW. Application can then properly handle the SGL
size without explicitly setting it.
Signed-off-by: Yi Sun <yi.sun@...el.com>
Co-developed-by: Anil S Keshavamurthy <anil.s.keshavamurthy@...el.com>
Signed-off-by: Anil S Keshavamurthy <anil.s.keshavamurthy@...el.com>
Reviewed-by: Dave Jiang <dave.jiang@...el.com>
diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c
index 5cf419fe6b46..1c10b030bea7 100644
--- a/drivers/dma/idxd/device.c
+++ b/drivers/dma/idxd/device.c
@@ -375,6 +375,7 @@ static void idxd_wq_disable_cleanup(struct idxd_wq *wq)
memset(wq->name, 0, WQ_NAME_SIZE);
wq->max_xfer_bytes = WQ_DEFAULT_MAX_XFER;
idxd_wq_set_max_batch_size(idxd->data->type, wq, WQ_DEFAULT_MAX_BATCH);
+ idxd_wq_set_init_max_sgl_size(idxd, wq);
if (wq->opcap_bmap)
bitmap_copy(wq->opcap_bmap, idxd->opcap_bmap, IDXD_MAX_OPCAP_BITS);
}
@@ -974,6 +975,8 @@ static int idxd_wq_config_write(struct idxd_wq *wq)
/* bytes 12-15 */
wq->wqcfg->max_xfer_shift = ilog2(wq->max_xfer_bytes);
idxd_wqcfg_set_max_batch_shift(idxd->data->type, wq->wqcfg, ilog2(wq->max_batch_size));
+ if (idxd_sgl_supported(idxd))
+ wq->wqcfg->max_sgl_shift = ilog2(wq->max_sgl_size);
/* bytes 32-63 */
if (idxd->hw.wq_cap.op_config && wq->opcap_bmap) {
@@ -1152,6 +1155,8 @@ static int idxd_wq_load_config(struct idxd_wq *wq)
wq->max_xfer_bytes = 1ULL << wq->wqcfg->max_xfer_shift;
idxd_wq_set_max_batch_size(idxd->data->type, wq, 1U << wq->wqcfg->max_batch_shift);
+ if (idxd_sgl_supported(idxd))
+ wq->max_sgl_size = 1U << wq->wqcfg->max_sgl_shift;
for (i = 0; i < WQCFG_STRIDES(idxd); i++) {
wqcfg_offset = WQCFG_OFFSET(idxd, wq->id, i);
diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h
index cc0a3fe1c957..ea8c4daed38d 100644
--- a/drivers/dma/idxd/idxd.h
+++ b/drivers/dma/idxd/idxd.h
@@ -227,6 +227,7 @@ struct idxd_wq {
char name[WQ_NAME_SIZE + 1];
u64 max_xfer_bytes;
u32 max_batch_size;
+ u32 max_sgl_size;
/* Lock to protect upasid_xa access. */
struct mutex uc_lock;
@@ -348,6 +349,7 @@ struct idxd_device {
u64 max_xfer_bytes;
u32 max_batch_size;
+ u32 max_sgl_size;
int max_groups;
int max_engines;
int max_rdbufs;
@@ -692,6 +694,20 @@ static inline void idxd_wq_set_max_batch_size(int idxd_type, struct idxd_wq *wq,
wq->max_batch_size = max_batch_size;
}
+static bool idxd_sgl_supported(struct idxd_device *idxd)
+{
+ return idxd->data->type == IDXD_TYPE_DSA &&
+ idxd->hw.version >= DEVICE_VERSION_3 &&
+ idxd->hw.dsacap0.sgl_formats;
+}
+
+static inline void idxd_wq_set_init_max_sgl_size(struct idxd_device *idxd,
+ struct idxd_wq *wq)
+{
+ if (idxd_sgl_supported(idxd))
+ wq->max_sgl_size = 1U << idxd->hw.dsacap0.max_sgl_shift;
+}
+
static inline void idxd_wqcfg_set_max_batch_shift(int idxd_type, union wqcfg *wqcfg,
u32 max_batch_shift)
{
diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
index 216461aa0cd1..4daf5995acee 100644
--- a/drivers/dma/idxd/init.c
+++ b/drivers/dma/idxd/init.c
@@ -217,6 +217,7 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
init_completion(&wq->wq_resurrect);
wq->max_xfer_bytes = WQ_DEFAULT_MAX_XFER;
idxd_wq_set_max_batch_size(idxd->data->type, wq, WQ_DEFAULT_MAX_BATCH);
+ idxd_wq_set_init_max_sgl_size(idxd, wq);
wq->enqcmds_retries = IDXD_ENQCMDS_RETRIES;
wq->wqcfg = kzalloc_node(idxd->wqcfg_size, GFP_KERNEL, dev_to_node(dev));
if (!wq->wqcfg) {
@@ -587,6 +588,10 @@ static void idxd_read_caps(struct idxd_device *idxd)
idxd->hw.dsacap1.bits = ioread64(idxd->reg_base + IDXD_DSACAP1_OFFSET);
idxd->hw.dsacap2.bits = ioread64(idxd->reg_base + IDXD_DSACAP2_OFFSET);
}
+ if (idxd_sgl_supported(idxd)) {
+ idxd->max_sgl_size = 1U << idxd->hw.dsacap0.max_sgl_shift;
+ dev_dbg(dev, "max sgl size: %u\n", idxd->max_sgl_size);
+ }
/* read iaa cap */
if (idxd->data->type == IDXD_TYPE_IAX && idxd->hw.version >= DEVICE_VERSION_2)
diff --git a/drivers/dma/idxd/registers.h b/drivers/dma/idxd/registers.h
index b430bddbd1e4..c665687913c6 100644
--- a/drivers/dma/idxd/registers.h
+++ b/drivers/dma/idxd/registers.h
@@ -385,7 +385,8 @@ union wqcfg {
/* bytes 12-15 */
u32 max_xfer_shift:5;
u32 max_batch_shift:4;
- u32 rsvd4:23;
+ u32 max_sgl_shift:4;
+ u32 rsvd4:19;
/* bytes 16-19 */
u16 occupancy_inth;
--
2.43.0
Powered by blists - more mailing lists