[v4,08/11] dma/ioat: add statistics

Message ID 20210917154227.737554-9-conor.walsh@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers
Series dma: add dmadev driver for ioat devices |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Conor Walsh Sept. 17, 2021, 3:42 p.m. UTC
Add statistic tracking for operations in IOAT.

Signed-off-by: Conor Walsh <conor.walsh@intel.com>
Reviewed-by: Kevin Laatz <kevin.laatz@intel.com>
---
 doc/guides/dmadevs/ioat.rst    | 23 ++++++++++++++++++
 drivers/dma/ioat/ioat_dmadev.c | 43 ++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+)
  

Comments

Bruce Richardson Sept. 20, 2021, 1:48 p.m. UTC | #1
On Fri, Sep 17, 2021 at 03:42:24PM +0000, Conor Walsh wrote:
> Add statistic tracking for operations in IOAT.
> 
> Signed-off-by: Conor Walsh <conor.walsh@intel.com>
> Reviewed-by: Kevin Laatz <kevin.laatz@intel.com>
> ---
>  doc/guides/dmadevs/ioat.rst    | 23 ++++++++++++++++++
>  drivers/dma/ioat/ioat_dmadev.c | 43 ++++++++++++++++++++++++++++++++++
>  2 files changed, 66 insertions(+)
> 
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
  

Patch

diff --git a/doc/guides/dmadevs/ioat.rst b/doc/guides/dmadevs/ioat.rst
index 42ecf1fb57..69f3c56a7a 100644
--- a/doc/guides/dmadevs/ioat.rst
+++ b/doc/guides/dmadevs/ioat.rst
@@ -189,3 +189,26 @@  of memory is overwritten, or filled, with a short pattern of data.
 Fill operations can be performed in much the same was as copy operations
 described above, just using the ``rte_dma_fill()`` function rather
 than the ``rte_dma_copy()`` function.
+
+Querying Device Statistics
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The statistics from the IOAT dmadev device can be got via the
+``rte_dma_stats_get()`` API in the ``rte_dmadev`` library.
+
+The statistics returned for each IOAT device are:
+
+* ``submitted``: The number of operations submitted to the device.
+* ``completed``: The number of operations completed by the device (both successful and failed).
+* ``errors``: The number of operations that failed.
+
+The stats function can be used as follows:
+
+.. code-block:: C
+
+   struct rte_dma_stats stats;
+   if (rte_dma_stats_get(dmadev_id, vchan, &stats) >= 0) {
+      printf("Total submitted ops: %lu", stats.submitted);
+      printf("Total completed ops: %lu", stats.completed);
+      printf("Total failed ops: %lu", stats.errors);
+   }
diff --git a/drivers/dma/ioat/ioat_dmadev.c b/drivers/dma/ioat/ioat_dmadev.c
index fc89babc4a..f596637da4 100644
--- a/drivers/dma/ioat/ioat_dmadev.c
+++ b/drivers/dma/ioat/ioat_dmadev.c
@@ -77,6 +77,9 @@  ioat_vchan_setup(struct rte_dma_dev *dev, uint16_t vchan __rte_unused,
 	ioat->offset = 0;
 	ioat->failure = 0;
 
+	/* Reset Stats. */
+	ioat->stats = (struct rte_dma_stats){0};
+
 	/* Configure descriptor ring - each one points to next. */
 	for (i = 0; i < ioat->qcfg.nb_desc; i++) {
 		ioat->desc_ring[i].next = ioat->ring_addr +
@@ -208,6 +211,8 @@  __submit(struct ioat_dmadev *ioat)
 {
 	*ioat->doorbell = ioat->next_write - ioat->offset;
 
+	ioat->stats.submitted += (uint16_t)(ioat->next_write - ioat->last_write);
+
 	ioat->last_write = ioat->next_write;
 }
 
@@ -336,6 +341,10 @@  ioat_dev_dump(const struct rte_dma_dev *dev, FILE *f)
 	fprintf(f, "    Dest: 0x%"PRIx64"\n", ioat->desc_ring[ioat->next_read & mask].dest_addr);
 	fprintf(f, "    Next: 0x%"PRIx64"\n", ioat->desc_ring[ioat->next_read & mask].next);
 	fprintf(f, "  }\n");
+	fprintf(f, "  Key Stats { submitted: %"PRIu64", comp: %"PRIu64", failed: %"PRIu64" }\n",
+			ioat->stats.submitted,
+			ioat->stats.completed,
+			ioat->stats.errors);
 
 	return 0;
 }
@@ -425,6 +434,9 @@  ioat_completed(struct rte_dma_dev *dev, uint16_t qid __rte_unused, const uint16_
 		*last_idx = ioat->next_read - 2;
 	}
 
+	ioat->stats.completed += count;
+	ioat->stats.errors += fails;
+
 	return count;
 }
 
@@ -475,9 +487,38 @@  ioat_completed_status(struct rte_dma_dev *dev, uint16_t qid __rte_unused,
 
 	*last_idx = ioat->next_read - 1;
 
+	ioat->stats.completed += count;
+	ioat->stats.errors += fails;
+
 	return count;
 }
 
+/* Retrieve the generic stats of a DMA device. */
+static int
+ioat_stats_get(const struct rte_dma_dev *dev, uint16_t vchan __rte_unused,
+		struct rte_dma_stats *rte_stats, uint32_t size)
+{
+	struct rte_dma_stats *stats = (&((struct ioat_dmadev *)dev->dev_private)->stats);
+
+	if (size < sizeof(rte_stats))
+		return -EINVAL;
+	if (rte_stats == NULL)
+		return -EINVAL;
+
+	*rte_stats = *stats;
+	return 0;
+}
+
+/* Reset the generic stat counters for the DMA device. */
+static int
+ioat_stats_reset(struct rte_dma_dev *dev, uint16_t vchan __rte_unused)
+{
+	struct ioat_dmadev *ioat = dev->dev_private;
+
+	ioat->stats = (struct rte_dma_stats){0};
+	return 0;
+}
+
 /* Create a DMA device. */
 static int
 ioat_dmadev_create(const char *name, struct rte_pci_device *dev)
@@ -489,6 +530,8 @@  ioat_dmadev_create(const char *name, struct rte_pci_device *dev)
 		.dev_info_get = ioat_dev_info_get,
 		.dev_start = ioat_dev_start,
 		.dev_stop = ioat_dev_stop,
+		.stats_get = ioat_stats_get,
+		.stats_reset = ioat_stats_reset,
 		.vchan_setup = ioat_vchan_setup,
 	};