* [PATCH] net/gve: Enable stats reporting for GQ format
@ 2023-12-22 15:39 Rushil Gupta
2024-01-12 15:06 ` Ferruh Yigit
` (3 more replies)
0 siblings, 4 replies; 12+ messages in thread
From: Rushil Gupta @ 2023-12-22 15:39 UTC (permalink / raw)
To: junfeng.guo, jeroendb, joshwash, ferruh.yigit; +Cc: dev, Rushil Gupta
Read from shared region to retrieve imissed statistics for GQ from device.
Tested using `show port xstats <port-id>` in interactive mode.
This metric can be triggered by using queues > cores.
Signed-off-by: Rushil Gupta <rushilg@google.com>
Reviewed-by: Joshua Washington <joshwash@google.com>
---
drivers/net/gve/base/gve_adminq.h | 11 ++++
drivers/net/gve/gve_ethdev.c | 95 +++++++++++++++++++++++++++++++
drivers/net/gve/gve_ethdev.h | 6 ++
3 files changed, 112 insertions(+)
diff --git a/drivers/net/gve/base/gve_adminq.h b/drivers/net/gve/base/gve_adminq.h
index e30b184913..f05362f85f 100644
--- a/drivers/net/gve/base/gve_adminq.h
+++ b/drivers/net/gve/base/gve_adminq.h
@@ -314,6 +314,17 @@ struct gve_stats_report {
GVE_CHECK_STRUCT_LEN(8, gve_stats_report);
+/* Numbers of gve tx/rx stats in stats report. */
+#define GVE_TX_STATS_REPORT_NUM 6
+#define GVE_RX_STATS_REPORT_NUM 2
+
+/* Interval to schedule a stats report update, 20000ms. */
+#define GVE_STATS_REPORT_TIMER_PERIOD 20000
+
+/* Numbers of NIC tx/rx stats in stats report. */
+#define NIC_TX_STATS_REPORT_NUM 0
+#define NIC_RX_STATS_REPORT_NUM 4
+
enum gve_stat_names {
/* stats from gve */
TX_WAKE_CNT = 1,
diff --git a/drivers/net/gve/gve_ethdev.c b/drivers/net/gve/gve_ethdev.c
index ecd37ff37f..836136d993 100644
--- a/drivers/net/gve/gve_ethdev.c
+++ b/drivers/net/gve/gve_ethdev.c
@@ -125,6 +125,73 @@ gve_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
return rte_eth_linkstatus_set(dev, &link);
}
+static int gve_alloc_stats_report(struct gve_priv *priv,
+ uint16_t nb_tx_queues, uint16_t nb_rx_queues)
+{
+ char z_name[RTE_MEMZONE_NAMESIZE];
+ int tx_stats_cnt;
+ int rx_stats_cnt;
+
+ tx_stats_cnt = (GVE_TX_STATS_REPORT_NUM + NIC_TX_STATS_REPORT_NUM) *
+ nb_tx_queues;
+ rx_stats_cnt = (GVE_RX_STATS_REPORT_NUM + NIC_RX_STATS_REPORT_NUM) *
+ nb_rx_queues;
+ priv->stats_report_len = sizeof(struct gve_stats_report) +
+ sizeof(struct stats) * (tx_stats_cnt + rx_stats_cnt);
+
+ snprintf(z_name, sizeof(z_name), "stats_report_%s", priv->pci_dev->device.name);
+ priv->stats_report_mem = rte_memzone_reserve_aligned(z_name,
+ priv->stats_report_len,
+ rte_socket_id(),
+ RTE_MEMZONE_IOVA_CONTIG, PAGE_SIZE);
+
+ if (!priv->stats_report_mem)
+ return -ENOMEM;
+
+ /* offset by skipping stats written by gve. */
+ priv->stats_start_idx = (GVE_TX_STATS_REPORT_NUM * nb_tx_queues) +
+ (GVE_RX_STATS_REPORT_NUM * nb_rx_queues);
+ priv->stats_end_idx = priv->stats_start_idx +
+ (NIC_TX_STATS_REPORT_NUM * nb_tx_queues) +
+ (NIC_RX_STATS_REPORT_NUM * nb_rx_queues) - 1;
+
+ return 0;
+}
+
+static void gve_free_stats_report(struct rte_eth_dev *dev)
+{
+ struct gve_priv *priv = dev->data->dev_private;
+ rte_memzone_free(priv->stats_report_mem);
+}
+
+/* Read Rx NIC stats from shared region */
+static void gve_get_imissed_from_nic(struct rte_eth_dev *dev)
+{
+ struct gve_stats_report *stats_report;
+ struct gve_rx_queue *rxq;
+ struct gve_priv *priv;
+ struct stats stat;
+ int queue_id;
+ int stat_id;
+ int i;
+
+ priv = dev->data->dev_private;
+ stats_report = (struct gve_stats_report *)
+ priv->stats_report_mem->addr;
+
+ for (i = priv->stats_start_idx; i <= priv->stats_end_idx; i++) {
+ stat = stats_report->stats[i];
+ queue_id = cpu_to_be32(stat.queue_id);
+ rxq = dev->data->rx_queues[queue_id];
+ if (rxq == NULL)
+ continue;
+ stat_id = cpu_to_be32(stat.stat_name);
+ /* Update imissed. */
+ if (stat_id == RX_NO_BUFFERS_POSTED)
+ rxq->stats.imissed = cpu_to_be64(stat.value);
+ }
+}
+
static int
gve_start_queues(struct rte_eth_dev *dev)
{
@@ -176,6 +243,7 @@ gve_start_queues(struct rte_eth_dev *dev)
static int
gve_dev_start(struct rte_eth_dev *dev)
{
+ struct gve_priv *priv;
int ret;
ret = gve_start_queues(dev);
@@ -187,6 +255,26 @@ gve_dev_start(struct rte_eth_dev *dev)
dev->data->dev_started = 1;
gve_link_update(dev, 0);
+ priv = dev->data->dev_private;
+ /* No stats available yet for Dqo. */
+ if (gve_is_gqi(priv)) {
+ ret = gve_alloc_stats_report(priv,
+ dev->data->nb_tx_queues,
+ dev->data->nb_rx_queues);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR,
+ "Failed to allocate region for stats reporting.");
+ return ret;
+ }
+ ret = gve_adminq_report_stats(priv, priv->stats_report_len,
+ priv->stats_report_mem->iova,
+ GVE_STATS_REPORT_TIMER_PERIOD);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR, "gve_adminq_report_stats command failed.");
+ return ret;
+ }
+ }
+
return 0;
}
@@ -200,6 +288,9 @@ gve_dev_stop(struct rte_eth_dev *dev)
dev->data->dev_started = 0;
+ if (gve_is_gqi(dev->data->dev_private))
+ gve_free_stats_report(dev);
+
return 0;
}
@@ -352,6 +443,8 @@ static int
gve_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
{
uint16_t i;
+ if (gve_is_gqi(dev->data->dev_private))
+ gve_get_imissed_from_nic(dev);
for (i = 0; i < dev->data->nb_tx_queues; i++) {
struct gve_tx_queue *txq = dev->data->tx_queues[i];
@@ -372,6 +465,7 @@ gve_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
stats->ibytes += rxq->stats.bytes;
stats->ierrors += rxq->stats.errors;
stats->rx_nombuf += rxq->stats.no_mbufs;
+ stats->imissed += rxq->stats.imissed;
}
return 0;
@@ -443,6 +537,7 @@ static const struct gve_xstats_name_offset rx_xstats_name_offset[] = {
{ "errors", RX_QUEUE_STATS_OFFSET(errors) },
{ "mbuf_alloc_errors", RX_QUEUE_STATS_OFFSET(no_mbufs) },
{ "mbuf_alloc_errors_bulk", RX_QUEUE_STATS_OFFSET(no_mbufs_bulk) },
+ { "imissed", RX_QUEUE_STATS_OFFSET(imissed) },
};
static int
diff --git a/drivers/net/gve/gve_ethdev.h b/drivers/net/gve/gve_ethdev.h
index 58d8943e71..9893fcfee6 100644
--- a/drivers/net/gve/gve_ethdev.h
+++ b/drivers/net/gve/gve_ethdev.h
@@ -85,6 +85,7 @@ struct gve_rx_stats {
uint64_t errors;
uint64_t no_mbufs;
uint64_t no_mbufs_bulk;
+ uint64_t imissed;
};
struct gve_xstats_name_offset {
@@ -272,6 +273,11 @@ struct gve_priv {
struct gve_tx_queue **txqs;
struct gve_rx_queue **rxqs;
+
+ uint32_t stats_report_len;
+ const struct rte_memzone *stats_report_mem;
+ uint16_t stats_start_idx; /* start index of array of stats written by NIC */
+ uint16_t stats_end_idx; /* end index of array of stats written by NIC */
};
static inline bool
--
2.43.0.472.g3155946c3a-goog
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] net/gve: Enable stats reporting for GQ format
2023-12-22 15:39 [PATCH] net/gve: Enable stats reporting for GQ format Rushil Gupta
@ 2024-01-12 15:06 ` Ferruh Yigit
2024-01-16 6:18 ` Rushil Gupta
2024-01-16 6:43 ` [v2] net/gve: enable imissed stats " Rushil Gupta
` (2 subsequent siblings)
3 siblings, 1 reply; 12+ messages in thread
From: Ferruh Yigit @ 2024-01-12 15:06 UTC (permalink / raw)
To: Rushil Gupta, junfeng.guo, jeroendb, joshwash; +Cc: dev
On 12/22/2023 3:39 PM, Rushil Gupta wrote:
> Read from shared region to retrieve imissed statistics for GQ from device.
> Tested using `show port xstats <port-id>` in interactive mode.
> This metric can be triggered by using queues > cores.
>
Looks good but please check following comments:
Checkpatch gives warning on the patch title, and this patch adds
'imissed' support so it can be added to the patch title, something like:
"net/gve: enable imissed stats for GQ format"
<...>
> +static int gve_alloc_stats_report(struct gve_priv *priv,
> + uint16_t nb_tx_queues, uint16_t nb_rx_queues)
> +{
> + char z_name[RTE_MEMZONE_NAMESIZE];
> + int tx_stats_cnt;
> + int rx_stats_cnt;
> +
> + tx_stats_cnt = (GVE_TX_STATS_REPORT_NUM + NIC_TX_STATS_REPORT_NUM) *
> + nb_tx_queues;
> + rx_stats_cnt = (GVE_RX_STATS_REPORT_NUM + NIC_RX_STATS_REPORT_NUM) *
> + nb_rx_queues;
> + priv->stats_report_len = sizeof(struct gve_stats_report) +
> + sizeof(struct stats) * (tx_stats_cnt + rx_stats_cnt);
> +
> + snprintf(z_name, sizeof(z_name), "stats_report_%s", priv->pci_dev->device.name);
>
Can you please add 'gve_' prefix to the memzone name, to prevent any
possible collision.
<...>
> +static void gve_free_stats_report(struct rte_eth_dev *dev)
> +{
> + struct gve_priv *priv = dev->data->dev_private;
> + rte_memzone_free(priv->stats_report_mem);
>
What will happen if user asks stats/xstats after port stopped?
<...>
> gve_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
> {
> uint16_t i;
> + if (gve_is_gqi(dev->data->dev_private))
> + gve_get_imissed_from_nic(dev);
>
This updates imissed in RxQ struct for all queues for basic stats, but
what if user only calls xstats, I guess in that case stat won't be updated.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] net/gve: Enable stats reporting for GQ format
2024-01-12 15:06 ` Ferruh Yigit
@ 2024-01-16 6:18 ` Rushil Gupta
2024-01-17 7:06 ` Joshua Washington
2024-01-17 9:40 ` Ferruh Yigit
0 siblings, 2 replies; 12+ messages in thread
From: Rushil Gupta @ 2024-01-16 6:18 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: junfeng.guo, jeroendb, joshwash, dev
[-- Attachment #1: Type: text/plain, Size: 2370 bytes --]
On Fri, Jan 12, 2024 at 8:36 PM Ferruh Yigit <ferruh.yigit@amd.com> wrote:
> On 12/22/2023 3:39 PM, Rushil Gupta wrote:
> > Read from shared region to retrieve imissed statistics for GQ from
> device.
> > Tested using `show port xstats <port-id>` in interactive mode.
> > This metric can be triggered by using queues > cores.
> >
>
> Looks good but please check following comments:
>
> Checkpatch gives warning on the patch title, and this patch adds
> 'imissed' support so it can be added to the patch title, something like:
> "net/gve: enable imissed stats for GQ format"
>
> <...>
>
> > +static int gve_alloc_stats_report(struct gve_priv *priv,
> > + uint16_t nb_tx_queues, uint16_t nb_rx_queues)
> > +{
> > + char z_name[RTE_MEMZONE_NAMESIZE];
> > + int tx_stats_cnt;
> > + int rx_stats_cnt;
> > +
> > + tx_stats_cnt = (GVE_TX_STATS_REPORT_NUM + NIC_TX_STATS_REPORT_NUM)
> *
> > + nb_tx_queues;
> > + rx_stats_cnt = (GVE_RX_STATS_REPORT_NUM + NIC_RX_STATS_REPORT_NUM)
> *
> > + nb_rx_queues;
> > + priv->stats_report_len = sizeof(struct gve_stats_report) +
> > + sizeof(struct stats) * (tx_stats_cnt + rx_stats_cnt);
> > +
> > + snprintf(z_name, sizeof(z_name), "stats_report_%s", priv->pci_dev->
> device.name);
> >
>
> Can you please add 'gve_' prefix to the memzone name, to prevent any
> possible collision.
>
Done.
>
> <...>
>
> > +static void gve_free_stats_report(struct rte_eth_dev *dev)
> > +{
> > + struct gve_priv *priv = dev->data->dev_private;
> > + rte_memzone_free(priv->stats_report_mem);
> >
>
> What will happen if user asks stats/xstats after port stopped?
>
Good catch. I have added a null check so that the driver doesn't try to
read stats from memory region that doesn't exist.
>
> <...>
>
> > gve_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
> > {
> > uint16_t i;
> > + if (gve_is_gqi(dev->data->dev_private))
> > + gve_get_imissed_from_nic(dev);
> >
>
> This updates imissed in RxQ struct for all queues for basic stats, but
> what if user only calls xstats, I guess in that case stat won't be updated.
>
Yes; that is expected. Since imissed is a member of rte_eth_stats; calling
gve_dev_stats_get is the right way to get this stat.
[-- Attachment #2: Type: text/html, Size: 3409 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* [v2] net/gve: enable imissed stats for GQ format
2023-12-22 15:39 [PATCH] net/gve: Enable stats reporting for GQ format Rushil Gupta
2024-01-12 15:06 ` Ferruh Yigit
@ 2024-01-16 6:43 ` Rushil Gupta
2024-01-19 14:26 ` [v3] " Rushil Gupta
2024-01-19 17:09 ` [v4] " Rushil Gupta
3 siblings, 0 replies; 12+ messages in thread
From: Rushil Gupta @ 2024-01-16 6:43 UTC (permalink / raw)
To: junfeng.guo, jeroendb, joshwash, ferruh.yigit; +Cc: dev, Rushil Gupta
Read from shared region to retrieve imissed statistics for GQ from device.
Tested using `show port xstats <port-id>` in interactive mode.
Signed-off-by: Rushil Gupta <rushilg@google.com>
Reviewed-by: Joshua Washington <joshwash@google.com>
---
drivers/net/gve/base/gve_adminq.h | 11 ++++
drivers/net/gve/gve_ethdev.c | 100 ++++++++++++++++++++++++++++++
drivers/net/gve/gve_ethdev.h | 6 ++
3 files changed, 117 insertions(+)
diff --git a/drivers/net/gve/base/gve_adminq.h b/drivers/net/gve/base/gve_adminq.h
index e30b184913..f05362f85f 100644
--- a/drivers/net/gve/base/gve_adminq.h
+++ b/drivers/net/gve/base/gve_adminq.h
@@ -314,6 +314,17 @@ struct gve_stats_report {
GVE_CHECK_STRUCT_LEN(8, gve_stats_report);
+/* Numbers of gve tx/rx stats in stats report. */
+#define GVE_TX_STATS_REPORT_NUM 6
+#define GVE_RX_STATS_REPORT_NUM 2
+
+/* Interval to schedule a stats report update, 20000ms. */
+#define GVE_STATS_REPORT_TIMER_PERIOD 20000
+
+/* Numbers of NIC tx/rx stats in stats report. */
+#define NIC_TX_STATS_REPORT_NUM 0
+#define NIC_RX_STATS_REPORT_NUM 4
+
enum gve_stat_names {
/* stats from gve */
TX_WAKE_CNT = 1,
diff --git a/drivers/net/gve/gve_ethdev.c b/drivers/net/gve/gve_ethdev.c
index ecd37ff37f..fe91e790bc 100644
--- a/drivers/net/gve/gve_ethdev.c
+++ b/drivers/net/gve/gve_ethdev.c
@@ -125,6 +125,78 @@ gve_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
return rte_eth_linkstatus_set(dev, &link);
}
+static int
+gve_alloc_stats_report(struct gve_priv *priv,
+ uint16_t nb_tx_queues, uint16_t nb_rx_queues)
+{
+ char z_name[RTE_MEMZONE_NAMESIZE];
+ int tx_stats_cnt;
+ int rx_stats_cnt;
+
+ tx_stats_cnt = (GVE_TX_STATS_REPORT_NUM + NIC_TX_STATS_REPORT_NUM) *
+ nb_tx_queues;
+ rx_stats_cnt = (GVE_RX_STATS_REPORT_NUM + NIC_RX_STATS_REPORT_NUM) *
+ nb_rx_queues;
+ priv->stats_report_len = sizeof(struct gve_stats_report) +
+ sizeof(struct stats) * (tx_stats_cnt + rx_stats_cnt);
+
+ snprintf(z_name, sizeof(z_name), "stats_report_%s", priv->pci_dev->device.name);
+ priv->gve_stats_report_mem = rte_memzone_reserve_aligned(z_name,
+ priv->stats_report_len,
+ rte_socket_id(),
+ RTE_MEMZONE_IOVA_CONTIG, PAGE_SIZE);
+
+ if (!priv->gve_stats_report_mem)
+ return -ENOMEM;
+
+ /* offset by skipping stats written by gve. */
+ priv->stats_start_idx = (GVE_TX_STATS_REPORT_NUM * nb_tx_queues) +
+ (GVE_RX_STATS_REPORT_NUM * nb_rx_queues);
+ priv->stats_end_idx = priv->stats_start_idx +
+ (NIC_TX_STATS_REPORT_NUM * nb_tx_queues) +
+ (NIC_RX_STATS_REPORT_NUM * nb_rx_queues) - 1;
+
+ return 0;
+}
+
+static void
+gve_free_stats_report(struct rte_eth_dev *dev)
+{
+ struct gve_priv *priv = dev->data->dev_private;
+ rte_memzone_free(priv->gve_stats_report_mem);
+ priv->gve_stats_report_mem = NULL;
+}
+
+/* Read Rx NIC stats from shared region */
+static void
+gve_get_imissed_from_nic(struct rte_eth_dev *dev)
+{
+ struct gve_stats_report *stats_report;
+ struct gve_rx_queue *rxq;
+ struct gve_priv *priv;
+ struct stats stat;
+ int queue_id;
+ int stat_id;
+ int i;
+
+ priv = dev->data->dev_private;
+ if (!priv->gve_stats_report_mem)
+ return;
+ stats_report = (struct gve_stats_report *)
+ priv->gve_stats_report_mem->addr;
+ for (i = priv->stats_start_idx; i <= priv->stats_end_idx; i++) {
+ stat = stats_report->stats[i];
+ queue_id = cpu_to_be32(stat.queue_id);
+ rxq = dev->data->rx_queues[queue_id];
+ if (rxq == NULL)
+ continue;
+ stat_id = cpu_to_be32(stat.stat_name);
+ /* Update imissed. */
+ if (stat_id == RX_NO_BUFFERS_POSTED)
+ rxq->stats.imissed = cpu_to_be64(stat.value);
+ }
+}
+
static int
gve_start_queues(struct rte_eth_dev *dev)
{
@@ -176,6 +248,7 @@ gve_start_queues(struct rte_eth_dev *dev)
static int
gve_dev_start(struct rte_eth_dev *dev)
{
+ struct gve_priv *priv;
int ret;
ret = gve_start_queues(dev);
@@ -187,6 +260,26 @@ gve_dev_start(struct rte_eth_dev *dev)
dev->data->dev_started = 1;
gve_link_update(dev, 0);
+ priv = dev->data->dev_private;
+ /* No stats available yet for Dqo. */
+ if (gve_is_gqi(priv)) {
+ ret = gve_alloc_stats_report(priv,
+ dev->data->nb_tx_queues,
+ dev->data->nb_rx_queues);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR,
+ "Failed to allocate region for stats reporting.");
+ return ret;
+ }
+ ret = gve_adminq_report_stats(priv, priv->stats_report_len,
+ priv->gve_stats_report_mem->iova,
+ GVE_STATS_REPORT_TIMER_PERIOD);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR, "gve_adminq_report_stats command failed.");
+ return ret;
+ }
+ }
+
return 0;
}
@@ -200,6 +293,9 @@ gve_dev_stop(struct rte_eth_dev *dev)
dev->data->dev_started = 0;
+ if (gve_is_gqi(dev->data->dev_private))
+ gve_free_stats_report(dev);
+
return 0;
}
@@ -352,6 +448,8 @@ static int
gve_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
{
uint16_t i;
+ if (gve_is_gqi(dev->data->dev_private))
+ gve_get_imissed_from_nic(dev);
for (i = 0; i < dev->data->nb_tx_queues; i++) {
struct gve_tx_queue *txq = dev->data->tx_queues[i];
@@ -372,6 +470,7 @@ gve_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
stats->ibytes += rxq->stats.bytes;
stats->ierrors += rxq->stats.errors;
stats->rx_nombuf += rxq->stats.no_mbufs;
+ stats->imissed += rxq->stats.imissed;
}
return 0;
@@ -443,6 +542,7 @@ static const struct gve_xstats_name_offset rx_xstats_name_offset[] = {
{ "errors", RX_QUEUE_STATS_OFFSET(errors) },
{ "mbuf_alloc_errors", RX_QUEUE_STATS_OFFSET(no_mbufs) },
{ "mbuf_alloc_errors_bulk", RX_QUEUE_STATS_OFFSET(no_mbufs_bulk) },
+ { "imissed", RX_QUEUE_STATS_OFFSET(imissed) },
};
static int
diff --git a/drivers/net/gve/gve_ethdev.h b/drivers/net/gve/gve_ethdev.h
index 58d8943e71..6ffc5c2deb 100644
--- a/drivers/net/gve/gve_ethdev.h
+++ b/drivers/net/gve/gve_ethdev.h
@@ -85,6 +85,7 @@ struct gve_rx_stats {
uint64_t errors;
uint64_t no_mbufs;
uint64_t no_mbufs_bulk;
+ uint64_t imissed;
};
struct gve_xstats_name_offset {
@@ -272,6 +273,11 @@ struct gve_priv {
struct gve_tx_queue **txqs;
struct gve_rx_queue **rxqs;
+
+ uint32_t stats_report_len;
+ const struct rte_memzone *gve_stats_report_mem;
+ uint16_t stats_start_idx; /* start index of array of stats written by NIC */
+ uint16_t stats_end_idx; /* end index of array of stats written by NIC */
};
static inline bool
--
2.34.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] net/gve: Enable stats reporting for GQ format
2024-01-16 6:18 ` Rushil Gupta
@ 2024-01-17 7:06 ` Joshua Washington
2024-01-17 9:40 ` Ferruh Yigit
1 sibling, 0 replies; 12+ messages in thread
From: Joshua Washington @ 2024-01-17 7:06 UTC (permalink / raw)
To: Rushil Gupta; +Cc: Ferruh Yigit, junfeng.guo, jeroendb, dev
[-- Attachment #1: Type: text/plain, Size: 3454 bytes --]
>
>
>> <...>
>>
>> > gve_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
>> > {
>> > uint16_t i;
>> > + if (gve_is_gqi(dev->data->dev_private))
>> > + gve_get_imissed_from_nic(dev);
>> >
>>
>> This updates imissed in RxQ struct for all queues for basic stats, but
>> what if user only calls xstats, I guess in that case stat won't be
>> updated.
>>
>
> Yes; that is expected. Since imissed is a member of rte_eth_stats; calling
> gve_dev_stats_get is the right way to get this stat.
>
I actually think that this should be a counter backed by an xstat as well.
As far as I can tell xstats is meant to be a more flexible version of
stats, and ultimately should be able to handle a superset of what basic
stats can handle, for the purposes of querying, etc.
On Mon, Jan 15, 2024 at 10:18 PM Rushil Gupta <rushilg@google.com> wrote:
>
>
> On Fri, Jan 12, 2024 at 8:36 PM Ferruh Yigit <ferruh.yigit@amd.com> wrote:
>
>> On 12/22/2023 3:39 PM, Rushil Gupta wrote:
>> > Read from shared region to retrieve imissed statistics for GQ from
>> device.
>> > Tested using `show port xstats <port-id>` in interactive mode.
>> > This metric can be triggered by using queues > cores.
>> >
>>
>> Looks good but please check following comments:
>>
>> Checkpatch gives warning on the patch title, and this patch adds
>> 'imissed' support so it can be added to the patch title, something like:
>> "net/gve: enable imissed stats for GQ format"
>>
>> <...>
>>
>> > +static int gve_alloc_stats_report(struct gve_priv *priv,
>> > + uint16_t nb_tx_queues, uint16_t nb_rx_queues)
>> > +{
>> > + char z_name[RTE_MEMZONE_NAMESIZE];
>> > + int tx_stats_cnt;
>> > + int rx_stats_cnt;
>> > +
>> > + tx_stats_cnt = (GVE_TX_STATS_REPORT_NUM +
>> NIC_TX_STATS_REPORT_NUM) *
>> > + nb_tx_queues;
>> > + rx_stats_cnt = (GVE_RX_STATS_REPORT_NUM +
>> NIC_RX_STATS_REPORT_NUM) *
>> > + nb_rx_queues;
>> > + priv->stats_report_len = sizeof(struct gve_stats_report) +
>> > + sizeof(struct stats) * (tx_stats_cnt + rx_stats_cnt);
>> > +
>> > + snprintf(z_name, sizeof(z_name), "stats_report_%s",
>> priv->pci_dev->device.name);
>> >
>>
>> Can you please add 'gve_' prefix to the memzone name, to prevent any
>> possible collision.
>>
> Done.
>
>>
>> <...>
>>
>> > +static void gve_free_stats_report(struct rte_eth_dev *dev)
>> > +{
>> > + struct gve_priv *priv = dev->data->dev_private;
>> > + rte_memzone_free(priv->stats_report_mem);
>> >
>>
>> What will happen if user asks stats/xstats after port stopped?
>>
> Good catch. I have added a null check so that the driver doesn't try to
> read stats from memory region that doesn't exist.
>
>>
>> <...>
>>
>> > gve_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
>> > {
>> > uint16_t i;
>> > + if (gve_is_gqi(dev->data->dev_private))
>> > + gve_get_imissed_from_nic(dev);
>> >
>>
>> This updates imissed in RxQ struct for all queues for basic stats, but
>> what if user only calls xstats, I guess in that case stat won't be
>> updated.
>>
>
> Yes; that is expected. Since imissed is a member of rte_eth_stats; calling
> gve_dev_stats_get is the right way to get this stat.
>
--
Joshua Washington | Software Engineer | joshwash@google.com | (414) 366-4423
[-- Attachment #2: Type: text/html, Size: 5973 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] net/gve: Enable stats reporting for GQ format
2024-01-16 6:18 ` Rushil Gupta
2024-01-17 7:06 ` Joshua Washington
@ 2024-01-17 9:40 ` Ferruh Yigit
2024-01-19 13:37 ` Rushil Gupta
1 sibling, 1 reply; 12+ messages in thread
From: Ferruh Yigit @ 2024-01-17 9:40 UTC (permalink / raw)
To: Rushil Gupta; +Cc: junfeng.guo, jeroendb, joshwash, dev
On 1/16/2024 6:18 AM, Rushil Gupta wrote:
>
>
> On Fri, Jan 12, 2024 at 8:36 PM Ferruh Yigit <ferruh.yigit@amd.com
> <mailto:ferruh.yigit@amd.com>> wrote:
>
> On 12/22/2023 3:39 PM, Rushil Gupta wrote:
> > Read from shared region to retrieve imissed statistics for GQ from
> device.
> > Tested using `show port xstats <port-id>` in interactive mode.
> > This metric can be triggered by using queues > cores.
> >
>
> Looks good but please check following comments:
>
> Checkpatch gives warning on the patch title, and this patch adds
> 'imissed' support so it can be added to the patch title, something like:
> "net/gve: enable imissed stats for GQ format"
>
> <...>
>
> > +static int gve_alloc_stats_report(struct gve_priv *priv,
> > + uint16_t nb_tx_queues, uint16_t nb_rx_queues)
> > +{
> > + char z_name[RTE_MEMZONE_NAMESIZE];
> > + int tx_stats_cnt;
> > + int rx_stats_cnt;
> > +
> > + tx_stats_cnt = (GVE_TX_STATS_REPORT_NUM +
> NIC_TX_STATS_REPORT_NUM) *
> > + nb_tx_queues;
> > + rx_stats_cnt = (GVE_RX_STATS_REPORT_NUM +
> NIC_RX_STATS_REPORT_NUM) *
> > + nb_rx_queues;
> > + priv->stats_report_len = sizeof(struct gve_stats_report) +
> > + sizeof(struct stats) * (tx_stats_cnt + rx_stats_cnt);
> > +
> > + snprintf(z_name, sizeof(z_name), "stats_report_%s",
> priv->pci_dev->device.name <http://device.name>);
> >
>
> Can you please add 'gve_' prefix to the memzone name, to prevent any
> possible collision.
>
> Done.
>
>
> <...>
>
> > +static void gve_free_stats_report(struct rte_eth_dev *dev)
> > +{
> > + struct gve_priv *priv = dev->data->dev_private;
> > + rte_memzone_free(priv->stats_report_mem);
> >
>
> What will happen if user asks stats/xstats after port stopped?
>
> Good catch. I have added a null check so that the driver doesn't try to
> read stats from memory region that doesn't exist.
>
>
> <...>
>
> > gve_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats
> *stats)
> > {
> > uint16_t i;
> > + if (gve_is_gqi(dev->data->dev_private))
> > + gve_get_imissed_from_nic(dev);
> >
>
> This updates imissed in RxQ struct for all queues for basic stats, but
> what if user only calls xstats, I guess in that case stat won't be
> updated.
>
>
> Yes; that is expected. Since imissed is a member of rte_eth_stats;
> calling gve_dev_stats_get is the right way to get this stat.
>
I don't think it is expected.
xstats contains the basic stats too, if users calls xstats API,
expectation is to get correct values.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] net/gve: Enable stats reporting for GQ format
2024-01-17 9:40 ` Ferruh Yigit
@ 2024-01-19 13:37 ` Rushil Gupta
0 siblings, 0 replies; 12+ messages in thread
From: Rushil Gupta @ 2024-01-19 13:37 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: junfeng.guo, jeroendb, joshwash, dev
[-- Attachment #1: Type: text/plain, Size: 3212 bytes --]
Those are fair points. I'll fix this by simply
calling gve_get_imissed_from_nic from gve_xstats_get in the v3 patch.
On Wed, Jan 17, 2024 at 3:10 PM Ferruh Yigit <ferruh.yigit@amd.com> wrote:
> On 1/16/2024 6:18 AM, Rushil Gupta wrote:
> >
> >
> > On Fri, Jan 12, 2024 at 8:36 PM Ferruh Yigit <ferruh.yigit@amd.com
> > <mailto:ferruh.yigit@amd.com>> wrote:
> >
> > On 12/22/2023 3:39 PM, Rushil Gupta wrote:
> > > Read from shared region to retrieve imissed statistics for GQ from
> > device.
> > > Tested using `show port xstats <port-id>` in interactive mode.
> > > This metric can be triggered by using queues > cores.
> > >
> >
> > Looks good but please check following comments:
> >
> > Checkpatch gives warning on the patch title, and this patch adds
> > 'imissed' support so it can be added to the patch title, something
> like:
> > "net/gve: enable imissed stats for GQ format"
> >
> > <...>
> >
> > > +static int gve_alloc_stats_report(struct gve_priv *priv,
> > > + uint16_t nb_tx_queues, uint16_t nb_rx_queues)
> > > +{
> > > + char z_name[RTE_MEMZONE_NAMESIZE];
> > > + int tx_stats_cnt;
> > > + int rx_stats_cnt;
> > > +
> > > + tx_stats_cnt = (GVE_TX_STATS_REPORT_NUM +
> > NIC_TX_STATS_REPORT_NUM) *
> > > + nb_tx_queues;
> > > + rx_stats_cnt = (GVE_RX_STATS_REPORT_NUM +
> > NIC_RX_STATS_REPORT_NUM) *
> > > + nb_rx_queues;
> > > + priv->stats_report_len = sizeof(struct gve_stats_report) +
> > > + sizeof(struct stats) * (tx_stats_cnt + rx_stats_cnt);
> > > +
> > > + snprintf(z_name, sizeof(z_name), "stats_report_%s",
> > priv->pci_dev->device.name <http://device.name>);
> > >
> >
> > Can you please add 'gve_' prefix to the memzone name, to prevent any
> > possible collision.
> >
> > Done.
> >
> >
> > <...>
> >
> > > +static void gve_free_stats_report(struct rte_eth_dev *dev)
> > > +{
> > > + struct gve_priv *priv = dev->data->dev_private;
> > > + rte_memzone_free(priv->stats_report_mem);
> > >
> >
> > What will happen if user asks stats/xstats after port stopped?
> >
> > Good catch. I have added a null check so that the driver doesn't try to
> > read stats from memory region that doesn't exist.
> >
> >
> > <...>
> >
> > > gve_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats
> > *stats)
> > > {
> > > uint16_t i;
> > > + if (gve_is_gqi(dev->data->dev_private))
> > > + gve_get_imissed_from_nic(dev);
> > >
> >
> > This updates imissed in RxQ struct for all queues for basic stats,
> but
> > what if user only calls xstats, I guess in that case stat won't be
> > updated.
> >
> >
> > Yes; that is expected. Since imissed is a member of rte_eth_stats;
> > calling gve_dev_stats_get is the right way to get this stat.
> >
>
> I don't think it is expected.
> xstats contains the basic stats too, if users calls xstats API,
> expectation is to get correct values.
>
>
[-- Attachment #2: Type: text/html, Size: 4599 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* [v3] net/gve: enable imissed stats for GQ format
2023-12-22 15:39 [PATCH] net/gve: Enable stats reporting for GQ format Rushil Gupta
2024-01-12 15:06 ` Ferruh Yigit
2024-01-16 6:43 ` [v2] net/gve: enable imissed stats " Rushil Gupta
@ 2024-01-19 14:26 ` Rushil Gupta
2024-01-19 15:25 ` Ferruh Yigit
2024-01-19 17:09 ` [v4] " Rushil Gupta
3 siblings, 1 reply; 12+ messages in thread
From: Rushil Gupta @ 2024-01-19 14:26 UTC (permalink / raw)
To: junfeng.guo, jeroendb, joshwash, ferruh.yigit; +Cc: dev, Rushil Gupta
Read from shared region to retrieve imissed statistics for GQ from device.
Signed-off-by: Rushil Gupta <rushilg@google.com>
Reviewed-by: Joshua Washington <joshwash@google.com>
---
drivers/net/gve/base/gve_adminq.h | 11 ++++
drivers/net/gve/gve_ethdev.c | 103 ++++++++++++++++++++++++++++++
drivers/net/gve/gve_ethdev.h | 6 ++
3 files changed, 120 insertions(+)
diff --git a/drivers/net/gve/base/gve_adminq.h b/drivers/net/gve/base/gve_adminq.h
index e30b184913..f05362f85f 100644
--- a/drivers/net/gve/base/gve_adminq.h
+++ b/drivers/net/gve/base/gve_adminq.h
@@ -314,6 +314,17 @@ struct gve_stats_report {
GVE_CHECK_STRUCT_LEN(8, gve_stats_report);
+/* Numbers of gve tx/rx stats in stats report. */
+#define GVE_TX_STATS_REPORT_NUM 6
+#define GVE_RX_STATS_REPORT_NUM 2
+
+/* Interval to schedule a stats report update, 20000ms. */
+#define GVE_STATS_REPORT_TIMER_PERIOD 20000
+
+/* Numbers of NIC tx/rx stats in stats report. */
+#define NIC_TX_STATS_REPORT_NUM 0
+#define NIC_RX_STATS_REPORT_NUM 4
+
enum gve_stat_names {
/* stats from gve */
TX_WAKE_CNT = 1,
diff --git a/drivers/net/gve/gve_ethdev.c b/drivers/net/gve/gve_ethdev.c
index ecd37ff37f..723b9332b8 100644
--- a/drivers/net/gve/gve_ethdev.c
+++ b/drivers/net/gve/gve_ethdev.c
@@ -125,6 +125,78 @@ gve_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
return rte_eth_linkstatus_set(dev, &link);
}
+static int
+gve_alloc_stats_report(struct gve_priv *priv,
+ uint16_t nb_tx_queues, uint16_t nb_rx_queues)
+{
+ char z_name[RTE_MEMZONE_NAMESIZE];
+ int tx_stats_cnt;
+ int rx_stats_cnt;
+
+ tx_stats_cnt = (GVE_TX_STATS_REPORT_NUM + NIC_TX_STATS_REPORT_NUM) *
+ nb_tx_queues;
+ rx_stats_cnt = (GVE_RX_STATS_REPORT_NUM + NIC_RX_STATS_REPORT_NUM) *
+ nb_rx_queues;
+ priv->stats_report_len = sizeof(struct gve_stats_report) +
+ sizeof(struct stats) * (tx_stats_cnt + rx_stats_cnt);
+
+ snprintf(z_name, sizeof(z_name), "stats_report_%s", priv->pci_dev->device.name);
+ priv->gve_stats_report_mem = rte_memzone_reserve_aligned(z_name,
+ priv->stats_report_len,
+ rte_socket_id(),
+ RTE_MEMZONE_IOVA_CONTIG, PAGE_SIZE);
+
+ if (!priv->gve_stats_report_mem)
+ return -ENOMEM;
+
+ /* offset by skipping stats written by gve. */
+ priv->stats_start_idx = (GVE_TX_STATS_REPORT_NUM * nb_tx_queues) +
+ (GVE_RX_STATS_REPORT_NUM * nb_rx_queues);
+ priv->stats_end_idx = priv->stats_start_idx +
+ (NIC_TX_STATS_REPORT_NUM * nb_tx_queues) +
+ (NIC_RX_STATS_REPORT_NUM * nb_rx_queues) - 1;
+
+ return 0;
+}
+
+static void
+gve_free_stats_report(struct rte_eth_dev *dev)
+{
+ struct gve_priv *priv = dev->data->dev_private;
+ rte_memzone_free(priv->gve_stats_report_mem);
+ priv->gve_stats_report_mem = NULL;
+}
+
+/* Read Rx NIC stats from shared region */
+static void
+gve_get_imissed_from_nic(struct rte_eth_dev *dev)
+{
+ struct gve_stats_report *stats_report;
+ struct gve_rx_queue *rxq;
+ struct gve_priv *priv;
+ struct stats stat;
+ int queue_id;
+ int stat_id;
+ int i;
+
+ priv = dev->data->dev_private;
+ if (!priv->gve_stats_report_mem)
+ return;
+ stats_report = (struct gve_stats_report *)
+ priv->gve_stats_report_mem->addr;
+ for (i = priv->stats_start_idx; i <= priv->stats_end_idx; i++) {
+ stat = stats_report->stats[i];
+ queue_id = cpu_to_be32(stat.queue_id);
+ rxq = dev->data->rx_queues[queue_id];
+ if (rxq == NULL)
+ continue;
+ stat_id = cpu_to_be32(stat.stat_name);
+ /* Update imissed. */
+ if (stat_id == RX_NO_BUFFERS_POSTED)
+ rxq->stats.imissed = cpu_to_be64(stat.value);
+ }
+}
+
static int
gve_start_queues(struct rte_eth_dev *dev)
{
@@ -176,6 +248,7 @@ gve_start_queues(struct rte_eth_dev *dev)
static int
gve_dev_start(struct rte_eth_dev *dev)
{
+ struct gve_priv *priv;
int ret;
ret = gve_start_queues(dev);
@@ -187,6 +260,26 @@ gve_dev_start(struct rte_eth_dev *dev)
dev->data->dev_started = 1;
gve_link_update(dev, 0);
+ priv = dev->data->dev_private;
+ /* No stats available yet for Dqo. */
+ if (gve_is_gqi(priv)) {
+ ret = gve_alloc_stats_report(priv,
+ dev->data->nb_tx_queues,
+ dev->data->nb_rx_queues);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR,
+ "Failed to allocate region for stats reporting.");
+ return ret;
+ }
+ ret = gve_adminq_report_stats(priv, priv->stats_report_len,
+ priv->gve_stats_report_mem->iova,
+ GVE_STATS_REPORT_TIMER_PERIOD);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR, "gve_adminq_report_stats command failed.");
+ return ret;
+ }
+ }
+
return 0;
}
@@ -200,6 +293,9 @@ gve_dev_stop(struct rte_eth_dev *dev)
dev->data->dev_started = 0;
+ if (gve_is_gqi(dev->data->dev_private))
+ gve_free_stats_report(dev);
+
return 0;
}
@@ -352,6 +448,8 @@ static int
gve_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
{
uint16_t i;
+ if (gve_is_gqi(dev->data->dev_private))
+ gve_get_imissed_from_nic(dev);
for (i = 0; i < dev->data->nb_tx_queues; i++) {
struct gve_tx_queue *txq = dev->data->tx_queues[i];
@@ -372,6 +470,7 @@ gve_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
stats->ibytes += rxq->stats.bytes;
stats->ierrors += rxq->stats.errors;
stats->rx_nombuf += rxq->stats.no_mbufs;
+ stats->imissed += rxq->stats.imissed;
}
return 0;
@@ -443,6 +542,7 @@ static const struct gve_xstats_name_offset rx_xstats_name_offset[] = {
{ "errors", RX_QUEUE_STATS_OFFSET(errors) },
{ "mbuf_alloc_errors", RX_QUEUE_STATS_OFFSET(no_mbufs) },
{ "mbuf_alloc_errors_bulk", RX_QUEUE_STATS_OFFSET(no_mbufs_bulk) },
+ { "imissed", RX_QUEUE_STATS_OFFSET(imissed) },
};
static int
@@ -471,6 +571,9 @@ gve_xstats_get(struct rte_eth_dev *dev,
uint16_t i, j, count = gve_xstats_count(dev);
const char *stats;
+ if (gve_is_gqi(dev->data->dev_private))
+ gve_get_imissed_from_nic(dev);
+
if (xstats == NULL || size < count)
return count;
diff --git a/drivers/net/gve/gve_ethdev.h b/drivers/net/gve/gve_ethdev.h
index 58d8943e71..6ffc5c2deb 100644
--- a/drivers/net/gve/gve_ethdev.h
+++ b/drivers/net/gve/gve_ethdev.h
@@ -85,6 +85,7 @@ struct gve_rx_stats {
uint64_t errors;
uint64_t no_mbufs;
uint64_t no_mbufs_bulk;
+ uint64_t imissed;
};
struct gve_xstats_name_offset {
@@ -272,6 +273,11 @@ struct gve_priv {
struct gve_tx_queue **txqs;
struct gve_rx_queue **rxqs;
+
+ uint32_t stats_report_len;
+ const struct rte_memzone *gve_stats_report_mem;
+ uint16_t stats_start_idx; /* start index of array of stats written by NIC */
+ uint16_t stats_end_idx; /* end index of array of stats written by NIC */
};
static inline bool
--
2.34.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [v3] net/gve: enable imissed stats for GQ format
2024-01-19 14:26 ` [v3] " Rushil Gupta
@ 2024-01-19 15:25 ` Ferruh Yigit
2024-01-19 16:30 ` Rushil Gupta
0 siblings, 1 reply; 12+ messages in thread
From: Ferruh Yigit @ 2024-01-19 15:25 UTC (permalink / raw)
To: Rushil Gupta, junfeng.guo, jeroendb, joshwash; +Cc: dev
On 1/19/2024 2:26 PM, Rushil Gupta wrote:
> Read from shared region to retrieve imissed statistics for GQ from device.
>
> Signed-off-by: Rushil Gupta <rushilg@google.com>
> Reviewed-by: Joshua Washington <joshwash@google.com>
>
<...>
> +static int
> +gve_alloc_stats_report(struct gve_priv *priv,
> + uint16_t nb_tx_queues, uint16_t nb_rx_queues)
> +{
> + char z_name[RTE_MEMZONE_NAMESIZE];
> + int tx_stats_cnt;
> + int rx_stats_cnt;
> +
> + tx_stats_cnt = (GVE_TX_STATS_REPORT_NUM + NIC_TX_STATS_REPORT_NUM) *
> + nb_tx_queues;
> + rx_stats_cnt = (GVE_RX_STATS_REPORT_NUM + NIC_RX_STATS_REPORT_NUM) *
> + nb_rx_queues;
> + priv->stats_report_len = sizeof(struct gve_stats_report) +
> + sizeof(struct stats) * (tx_stats_cnt + rx_stats_cnt);
> +
> + snprintf(z_name, sizeof(z_name), "stats_report_%s", priv->pci_dev->device.name);
> + priv->gve_stats_report_mem = rte_memzone_reserve_aligned(z_name,
> + priv->stats_report_len,
> + rte_socket_id(),
> + RTE_MEMZONE_IOVA_CONTIG, PAGE_SIZE);
>
Adding 'gve_' prefix to memzone name comment seems missed.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [v3] net/gve: enable imissed stats for GQ format
2024-01-19 15:25 ` Ferruh Yigit
@ 2024-01-19 16:30 ` Rushil Gupta
0 siblings, 0 replies; 12+ messages in thread
From: Rushil Gupta @ 2024-01-19 16:30 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: junfeng.guo, jeroendb, joshwash, dev
[-- Attachment #1: Type: text/plain, Size: 1527 bytes --]
I misinterpreted your comment earlier and prefixed memzone variable name
with "gve" instead of memzone name. Will fix it in v4. Thanks!
On Fri, Jan 19, 2024 at 8:55 PM Ferruh Yigit <ferruh.yigit@amd.com> wrote:
> On 1/19/2024 2:26 PM, Rushil Gupta wrote:
> > Read from shared region to retrieve imissed statistics for GQ from
> device.
> >
> > Signed-off-by: Rushil Gupta <rushilg@google.com>
> > Reviewed-by: Joshua Washington <joshwash@google.com>
> >
>
> <...>
>
> > +static int
> > +gve_alloc_stats_report(struct gve_priv *priv,
> > + uint16_t nb_tx_queues, uint16_t nb_rx_queues)
> > +{
> > + char z_name[RTE_MEMZONE_NAMESIZE];
> > + int tx_stats_cnt;
> > + int rx_stats_cnt;
> > +
> > + tx_stats_cnt = (GVE_TX_STATS_REPORT_NUM + NIC_TX_STATS_REPORT_NUM)
> *
> > + nb_tx_queues;
> > + rx_stats_cnt = (GVE_RX_STATS_REPORT_NUM + NIC_RX_STATS_REPORT_NUM)
> *
> > + nb_rx_queues;
> > + priv->stats_report_len = sizeof(struct gve_stats_report) +
> > + sizeof(struct stats) * (tx_stats_cnt + rx_stats_cnt);
> > +
> > + snprintf(z_name, sizeof(z_name), "stats_report_%s", priv->pci_dev->
> device.name);
> > + priv->gve_stats_report_mem = rte_memzone_reserve_aligned(z_name,
> > + priv->stats_report_len,
> > + rte_socket_id(),
> > + RTE_MEMZONE_IOVA_CONTIG, PAGE_SIZE);
> >
>
> Adding 'gve_' prefix to memzone name comment seems missed.
>
>
[-- Attachment #2: Type: text/html, Size: 2277 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* [v4] net/gve: enable imissed stats for GQ format
2023-12-22 15:39 [PATCH] net/gve: Enable stats reporting for GQ format Rushil Gupta
` (2 preceding siblings ...)
2024-01-19 14:26 ` [v3] " Rushil Gupta
@ 2024-01-19 17:09 ` Rushil Gupta
2024-01-22 10:56 ` Ferruh Yigit
3 siblings, 1 reply; 12+ messages in thread
From: Rushil Gupta @ 2024-01-19 17:09 UTC (permalink / raw)
To: junfeng.guo, jeroendb, joshwash, ferruh.yigit; +Cc: dev, Rushil Gupta
Read from shared region to retrieve imissed statistics for GQ from device.
Signed-off-by: Rushil Gupta <rushilg@google.com>
Reviewed-by: Joshua Washington <joshwash@google.com>
---
drivers/net/gve/base/gve_adminq.h | 11 ++++
drivers/net/gve/gve_ethdev.c | 104 ++++++++++++++++++++++++++++++
drivers/net/gve/gve_ethdev.h | 6 ++
3 files changed, 121 insertions(+)
diff --git a/drivers/net/gve/base/gve_adminq.h b/drivers/net/gve/base/gve_adminq.h
index e30b184913..f05362f85f 100644
--- a/drivers/net/gve/base/gve_adminq.h
+++ b/drivers/net/gve/base/gve_adminq.h
@@ -314,6 +314,17 @@ struct gve_stats_report {
GVE_CHECK_STRUCT_LEN(8, gve_stats_report);
+/* Numbers of gve tx/rx stats in stats report. */
+#define GVE_TX_STATS_REPORT_NUM 6
+#define GVE_RX_STATS_REPORT_NUM 2
+
+/* Interval to schedule a stats report update, 20000ms. */
+#define GVE_STATS_REPORT_TIMER_PERIOD 20000
+
+/* Numbers of NIC tx/rx stats in stats report. */
+#define NIC_TX_STATS_REPORT_NUM 0
+#define NIC_RX_STATS_REPORT_NUM 4
+
enum gve_stat_names {
/* stats from gve */
TX_WAKE_CNT = 1,
diff --git a/drivers/net/gve/gve_ethdev.c b/drivers/net/gve/gve_ethdev.c
index ecd37ff37f..d162fd3864 100644
--- a/drivers/net/gve/gve_ethdev.c
+++ b/drivers/net/gve/gve_ethdev.c
@@ -125,6 +125,79 @@ gve_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
return rte_eth_linkstatus_set(dev, &link);
}
+static int
+gve_alloc_stats_report(struct gve_priv *priv,
+ uint16_t nb_tx_queues, uint16_t nb_rx_queues)
+{
+ char z_name[RTE_MEMZONE_NAMESIZE];
+ int tx_stats_cnt;
+ int rx_stats_cnt;
+
+ tx_stats_cnt = (GVE_TX_STATS_REPORT_NUM + NIC_TX_STATS_REPORT_NUM) *
+ nb_tx_queues;
+ rx_stats_cnt = (GVE_RX_STATS_REPORT_NUM + NIC_RX_STATS_REPORT_NUM) *
+ nb_rx_queues;
+ priv->stats_report_len = sizeof(struct gve_stats_report) +
+ sizeof(struct stats) * (tx_stats_cnt + rx_stats_cnt);
+
+ snprintf(z_name, sizeof(z_name), "gve_stats_report_%s",
+ priv->pci_dev->device.name);
+ priv->stats_report_mem = rte_memzone_reserve_aligned(z_name,
+ priv->stats_report_len,
+ rte_socket_id(),
+ RTE_MEMZONE_IOVA_CONTIG, PAGE_SIZE);
+
+ if (!priv->stats_report_mem)
+ return -ENOMEM;
+
+ /* offset by skipping stats written by gve. */
+ priv->stats_start_idx = (GVE_TX_STATS_REPORT_NUM * nb_tx_queues) +
+ (GVE_RX_STATS_REPORT_NUM * nb_rx_queues);
+ priv->stats_end_idx = priv->stats_start_idx +
+ (NIC_TX_STATS_REPORT_NUM * nb_tx_queues) +
+ (NIC_RX_STATS_REPORT_NUM * nb_rx_queues) - 1;
+
+ return 0;
+}
+
+static void
+gve_free_stats_report(struct rte_eth_dev *dev)
+{
+ struct gve_priv *priv = dev->data->dev_private;
+ rte_memzone_free(priv->stats_report_mem);
+ priv->stats_report_mem = NULL;
+}
+
+/* Read Rx NIC stats from shared region */
+static void
+gve_get_imissed_from_nic(struct rte_eth_dev *dev)
+{
+ struct gve_stats_report *stats_report;
+ struct gve_rx_queue *rxq;
+ struct gve_priv *priv;
+ struct stats stat;
+ int queue_id;
+ int stat_id;
+ int i;
+
+ priv = dev->data->dev_private;
+ if (!priv->stats_report_mem)
+ return;
+ stats_report = (struct gve_stats_report *)
+ priv->stats_report_mem->addr;
+ for (i = priv->stats_start_idx; i <= priv->stats_end_idx; i++) {
+ stat = stats_report->stats[i];
+ queue_id = cpu_to_be32(stat.queue_id);
+ rxq = dev->data->rx_queues[queue_id];
+ if (rxq == NULL)
+ continue;
+ stat_id = cpu_to_be32(stat.stat_name);
+ /* Update imissed. */
+ if (stat_id == RX_NO_BUFFERS_POSTED)
+ rxq->stats.imissed = cpu_to_be64(stat.value);
+ }
+}
+
static int
gve_start_queues(struct rte_eth_dev *dev)
{
@@ -176,6 +249,7 @@ gve_start_queues(struct rte_eth_dev *dev)
static int
gve_dev_start(struct rte_eth_dev *dev)
{
+ struct gve_priv *priv;
int ret;
ret = gve_start_queues(dev);
@@ -187,6 +261,26 @@ gve_dev_start(struct rte_eth_dev *dev)
dev->data->dev_started = 1;
gve_link_update(dev, 0);
+ priv = dev->data->dev_private;
+ /* No stats available yet for Dqo. */
+ if (gve_is_gqi(priv)) {
+ ret = gve_alloc_stats_report(priv,
+ dev->data->nb_tx_queues,
+ dev->data->nb_rx_queues);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR,
+ "Failed to allocate region for stats reporting.");
+ return ret;
+ }
+ ret = gve_adminq_report_stats(priv, priv->stats_report_len,
+ priv->stats_report_mem->iova,
+ GVE_STATS_REPORT_TIMER_PERIOD);
+ if (ret != 0) {
+ PMD_DRV_LOG(ERR, "gve_adminq_report_stats command failed.");
+ return ret;
+ }
+ }
+
return 0;
}
@@ -200,6 +294,9 @@ gve_dev_stop(struct rte_eth_dev *dev)
dev->data->dev_started = 0;
+ if (gve_is_gqi(dev->data->dev_private))
+ gve_free_stats_report(dev);
+
return 0;
}
@@ -352,6 +449,8 @@ static int
gve_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
{
uint16_t i;
+ if (gve_is_gqi(dev->data->dev_private))
+ gve_get_imissed_from_nic(dev);
for (i = 0; i < dev->data->nb_tx_queues; i++) {
struct gve_tx_queue *txq = dev->data->tx_queues[i];
@@ -372,6 +471,7 @@ gve_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
stats->ibytes += rxq->stats.bytes;
stats->ierrors += rxq->stats.errors;
stats->rx_nombuf += rxq->stats.no_mbufs;
+ stats->imissed += rxq->stats.imissed;
}
return 0;
@@ -443,6 +543,7 @@ static const struct gve_xstats_name_offset rx_xstats_name_offset[] = {
{ "errors", RX_QUEUE_STATS_OFFSET(errors) },
{ "mbuf_alloc_errors", RX_QUEUE_STATS_OFFSET(no_mbufs) },
{ "mbuf_alloc_errors_bulk", RX_QUEUE_STATS_OFFSET(no_mbufs_bulk) },
+ { "imissed", RX_QUEUE_STATS_OFFSET(imissed) },
};
static int
@@ -471,6 +572,9 @@ gve_xstats_get(struct rte_eth_dev *dev,
uint16_t i, j, count = gve_xstats_count(dev);
const char *stats;
+ if (gve_is_gqi(dev->data->dev_private))
+ gve_get_imissed_from_nic(dev);
+
if (xstats == NULL || size < count)
return count;
diff --git a/drivers/net/gve/gve_ethdev.h b/drivers/net/gve/gve_ethdev.h
index 58d8943e71..9893fcfee6 100644
--- a/drivers/net/gve/gve_ethdev.h
+++ b/drivers/net/gve/gve_ethdev.h
@@ -85,6 +85,7 @@ struct gve_rx_stats {
uint64_t errors;
uint64_t no_mbufs;
uint64_t no_mbufs_bulk;
+ uint64_t imissed;
};
struct gve_xstats_name_offset {
@@ -272,6 +273,11 @@ struct gve_priv {
struct gve_tx_queue **txqs;
struct gve_rx_queue **rxqs;
+
+ uint32_t stats_report_len;
+ const struct rte_memzone *stats_report_mem;
+ uint16_t stats_start_idx; /* start index of array of stats written by NIC */
+ uint16_t stats_end_idx; /* end index of array of stats written by NIC */
};
static inline bool
--
2.34.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [v4] net/gve: enable imissed stats for GQ format
2024-01-19 17:09 ` [v4] " Rushil Gupta
@ 2024-01-22 10:56 ` Ferruh Yigit
0 siblings, 0 replies; 12+ messages in thread
From: Ferruh Yigit @ 2024-01-22 10:56 UTC (permalink / raw)
To: Rushil Gupta, junfeng.guo, jeroendb, joshwash; +Cc: dev
On 1/19/2024 5:09 PM, Rushil Gupta wrote:
> Read from shared region to retrieve imissed statistics for GQ from device.
>
> Signed-off-by: Rushil Gupta <rushilg@google.com>
> Reviewed-by: Joshua Washington <joshwash@google.com>
>
Acked-by: Ferruh Yigit <ferruh.yigit@amd.com>
Applied to dpdk-next-net/main, thanks.
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2024-01-22 10:56 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-22 15:39 [PATCH] net/gve: Enable stats reporting for GQ format Rushil Gupta
2024-01-12 15:06 ` Ferruh Yigit
2024-01-16 6:18 ` Rushil Gupta
2024-01-17 7:06 ` Joshua Washington
2024-01-17 9:40 ` Ferruh Yigit
2024-01-19 13:37 ` Rushil Gupta
2024-01-16 6:43 ` [v2] net/gve: enable imissed stats " Rushil Gupta
2024-01-19 14:26 ` [v3] " Rushil Gupta
2024-01-19 15:25 ` Ferruh Yigit
2024-01-19 16:30 ` Rushil Gupta
2024-01-19 17:09 ` [v4] " Rushil Gupta
2024-01-22 10:56 ` Ferruh Yigit
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).