[v3,07/17] dma/idxd: add datapath structures

Message ID 20210908103016.1661914-8-kevin.laatz@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers
Series add dmadev driver for idxd devices |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Kevin Laatz Sept. 8, 2021, 10:30 a.m. UTC
  Add data structures required for the data path for IDXD devices.

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
Signed-off-by: Kevin Laatz <kevin.laatz@intel.com>

---
v2: add completion status for invalid opcode
---
 drivers/dma/idxd/idxd_bus.c      |  1 +
 drivers/dma/idxd/idxd_common.c   | 33 ++++++++++++++++++
 drivers/dma/idxd/idxd_hw_defs.h  | 60 ++++++++++++++++++++++++++++++++
 drivers/dma/idxd/idxd_internal.h |  3 ++
 drivers/dma/idxd/idxd_pci.c      |  2 +-
 5 files changed, 98 insertions(+), 1 deletion(-)
  

Comments

Conor Walsh Sept. 9, 2021, 11:23 a.m. UTC | #1
> Add data structures required for the data path for IDXD devices.
>
> Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> Signed-off-by: Kevin Laatz <kevin.laatz@intel.com>

<snip>

> +int
> +idxd_dump(const struct rte_dmadev *dev, FILE *f)
> +{
> +	struct idxd_dmadev *idxd = dev->dev_private;
> +	unsigned int i;
> +
> +	fprintf(f, "== Private Data ==\n");

Minor nit could you call out IDXD somewhere here just to make it clear 
which driver is being used?

It may be helpful for debugging just to quickly see if the correct 
driver was used.

> +	fprintf(f, "  Portal: %p\n", idxd->portal);
> +	fprintf(f, "  Config: { ring_size: %u }\n",
> +			idxd->qcfg.nb_desc);
> +	fprintf(f, "  Batch ring (sz = %u, max_batches = %u):\n\t",
> +			idxd->max_batches + 1, idxd->max_batches);
> +	for (i = 0; i <= idxd->max_batches; i++) {
> +		fprintf(f, " %u ", idxd->batch_idx_ring[i]);
> +		if (i == idxd->batch_idx_read && i == idxd->batch_idx_write)
> +			fprintf(f, "[rd ptr, wr ptr] ");
> +		else if (i == idxd->batch_idx_read)
> +			fprintf(f, "[rd ptr] ");
> +		else if (i == idxd->batch_idx_write)
> +			fprintf(f, "[wr ptr] ");
> +		if (i == idxd->max_batches)
> +			fprintf(f, "\n");
> +	}
> +
> +	fprintf(f, "  Curr batch: start = %u, size = %u\n", idxd->batch_start, idxd->batch_size);
> +	fprintf(f, "  IDS: avail = %u, returned: %u\n", idxd->ids_avail, idxd->ids_returned);
> +	return 0;
> +}

Reviewed-by: Conor Walsh <conor.walsh@intel.com>

<snip>
  

Patch

diff --git a/drivers/dma/idxd/idxd_bus.c b/drivers/dma/idxd/idxd_bus.c
index 9b55451ad2..20d17c20ca 100644
--- a/drivers/dma/idxd/idxd_bus.c
+++ b/drivers/dma/idxd/idxd_bus.c
@@ -95,6 +95,7 @@  idxd_dev_close(struct rte_dmadev *dev)
 
 static const struct rte_dmadev_ops idxd_vdev_ops = {
 		.dev_close = idxd_dev_close,
+		.dev_dump = idxd_dump,
 };
 
 static void *
diff --git a/drivers/dma/idxd/idxd_common.c b/drivers/dma/idxd/idxd_common.c
index 7770b2e264..9490439fdc 100644
--- a/drivers/dma/idxd/idxd_common.c
+++ b/drivers/dma/idxd/idxd_common.c
@@ -10,6 +10,35 @@ 
 
 #define IDXD_PMD_NAME_STR "dmadev_idxd"
 
+int
+idxd_dump(const struct rte_dmadev *dev, FILE *f)
+{
+	struct idxd_dmadev *idxd = dev->dev_private;
+	unsigned int i;
+
+	fprintf(f, "== Private Data ==\n");
+	fprintf(f, "  Portal: %p\n", idxd->portal);
+	fprintf(f, "  Config: { ring_size: %u }\n",
+			idxd->qcfg.nb_desc);
+	fprintf(f, "  Batch ring (sz = %u, max_batches = %u):\n\t",
+			idxd->max_batches + 1, idxd->max_batches);
+	for (i = 0; i <= idxd->max_batches; i++) {
+		fprintf(f, " %u ", idxd->batch_idx_ring[i]);
+		if (i == idxd->batch_idx_read && i == idxd->batch_idx_write)
+			fprintf(f, "[rd ptr, wr ptr] ");
+		else if (i == idxd->batch_idx_read)
+			fprintf(f, "[rd ptr] ");
+		else if (i == idxd->batch_idx_write)
+			fprintf(f, "[wr ptr] ");
+		if (i == idxd->max_batches)
+			fprintf(f, "\n");
+	}
+
+	fprintf(f, "  Curr batch: start = %u, size = %u\n", idxd->batch_start, idxd->batch_size);
+	fprintf(f, "  IDS: avail = %u, returned: %u\n", idxd->ids_avail, idxd->ids_returned);
+	return 0;
+}
+
 int
 idxd_dmadev_create(const char *name, struct rte_device *dev,
 		   const struct idxd_dmadev *base_idxd,
@@ -19,6 +48,10 @@  idxd_dmadev_create(const char *name, struct rte_device *dev,
 	struct rte_dmadev *dmadev = NULL;
 	int ret = 0;
 
+	RTE_BUILD_BUG_ON(sizeof(struct idxd_hw_desc) != 64);
+	RTE_BUILD_BUG_ON(offsetof(struct idxd_hw_desc, size) != 32);
+	RTE_BUILD_BUG_ON(sizeof(struct idxd_completion) != 32);
+
 	if (!name) {
 		IDXD_PMD_ERR("Invalid name of the device!");
 		ret = -EINVAL;
diff --git a/drivers/dma/idxd/idxd_hw_defs.h b/drivers/dma/idxd/idxd_hw_defs.h
index ea627cba6d..55ca9f7f52 100644
--- a/drivers/dma/idxd/idxd_hw_defs.h
+++ b/drivers/dma/idxd/idxd_hw_defs.h
@@ -5,6 +5,66 @@ 
 #ifndef _IDXD_HW_DEFS_H_
 #define _IDXD_HW_DEFS_H_
 
+/*
+ * Defines used in the data path for interacting with IDXD hardware.
+ */
+#define IDXD_CMD_OP_SHIFT 24
+enum rte_idxd_ops {
+	idxd_op_nop = 0,
+	idxd_op_batch,
+	idxd_op_drain,
+	idxd_op_memmove,
+	idxd_op_fill
+};
+
+#define IDXD_FLAG_FENCE                 (1 << 0)
+#define IDXD_FLAG_COMPLETION_ADDR_VALID (1 << 2)
+#define IDXD_FLAG_REQUEST_COMPLETION    (1 << 3)
+#define IDXD_FLAG_CACHE_CONTROL         (1 << 8)
+
+/**
+ * Hardware descriptor used by DSA hardware, for both bursts and
+ * for individual operations.
+ */
+struct idxd_hw_desc {
+	uint32_t pasid;
+	uint32_t op_flags;
+	rte_iova_t completion;
+
+	RTE_STD_C11
+	union {
+		rte_iova_t src;      /* source address for copy ops etc. */
+		rte_iova_t desc_addr; /* descriptor pointer for batch */
+	};
+	rte_iova_t dst;
+
+	uint32_t size;    /* length of data for op, or batch size */
+
+	uint16_t intr_handle; /* completion interrupt handle */
+
+	/* remaining 26 bytes are reserved */
+	uint16_t __reserved[13];
+} __rte_aligned(64);
+
+#define IDXD_COMP_STATUS_INCOMPLETE        0
+#define IDXD_COMP_STATUS_SUCCESS           1
+#define IDXD_COMP_STATUS_INVALID_OPCODE 0x10
+#define IDXD_COMP_STATUS_INVALID_SIZE   0x13
+#define IDXD_COMP_STATUS_SKIPPED        0xFF /* not official IDXD error, needed as placeholder */
+
+/**
+ * Completion record structure written back by DSA
+ */
+struct idxd_completion {
+	uint8_t status;
+	uint8_t result;
+	/* 16-bits pad here */
+	uint32_t completed_size; /* data length, or descriptors for batch */
+
+	rte_iova_t fault_address;
+	uint32_t invalid_flags;
+} __rte_aligned(32);
+
 /*** Definitions for Intel(R) Data Streaming Accelerator  ***/
 
 #define IDXD_CMD_SHIFT 20
diff --git a/drivers/dma/idxd/idxd_internal.h b/drivers/dma/idxd/idxd_internal.h
index d92d7b3e6f..e558258ec4 100644
--- a/drivers/dma/idxd/idxd_internal.h
+++ b/drivers/dma/idxd/idxd_internal.h
@@ -39,6 +39,8 @@  struct idxd_pci_common {
 };
 
 struct idxd_dmadev {
+	struct idxd_hw_desc *desc_ring;
+
 	/* counters to track the batches */
 	unsigned short max_batches;
 	unsigned short batch_idx_read;
@@ -79,5 +81,6 @@  struct idxd_dmadev {
 
 int idxd_dmadev_create(const char *name, struct rte_device *dev,
 		const struct idxd_dmadev *base_idxd, const struct rte_dmadev_ops *ops);
+int idxd_dump(const struct rte_dmadev *dev, FILE *f);
 
 #endif /* _IDXD_INTERNAL_H_ */
diff --git a/drivers/dma/idxd/idxd_pci.c b/drivers/dma/idxd/idxd_pci.c
index 318931713c..96d58c8544 100644
--- a/drivers/dma/idxd/idxd_pci.c
+++ b/drivers/dma/idxd/idxd_pci.c
@@ -60,7 +60,7 @@  idxd_is_wq_enabled(struct idxd_dmadev *idxd)
 }
 
 static const struct rte_dmadev_ops idxd_pci_ops = {
-
+	.dev_dump = idxd_dump,
 };
 
 /* each portal uses 4 x 4k pages */