[v2,4/5] net/ena: add support for ena-express metrics

Message ID 20231025133609.17931-5-shaibran@amazon.com (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers
Series net/ena: v2.8.0 driver release |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Brandes, Shai Oct. 25, 2023, 1:36 p.m. UTC
From: Shai Brandes <shaibran@amazon.com>

ENA-express is powered by AWS scalable reliable datagram (SRD)
technology. SRD is a high performance network transport protocol
that uses dynamic routing to increase throughput and minimize
tail latency.

The driver expose the following ENA-express metrics via xstats:
* ena_srd_mode – Describes which ENA-express features are enabled
* ena_srd_eligible_tx_pkts – The number of network packets sent
  within a given time period that meet SRD requirements for
  eligibility
* ena_srd_tx_pkts – The number of SRD packets transmitted within
  a given time period.
* ena_srd_rx_pkts – The number of SRD packets received within
  a given time period.
* ena_srd_resource_utilization – The percentage of the maximum
  allowed memory utilization for concurrent SRD connections
  that the instance has consumed.

Probing the ENA Express metrics is performed via an admin command.
Thus, a multi-process proxy handler was added.

Signed-off-by: Shai Brandes <shaibran@amazon.com>
Reviewed-by: Amit Bernstein <amitbern@amazon.com>
---
 doc/guides/rel_notes/release_23_11.rst |   1 +
 drivers/net/ena/ena_ethdev.c           | 105 ++++++++++++++++++++++++-
 drivers/net/ena/ena_ethdev.h           |  18 +++++
 3 files changed, 123 insertions(+), 1 deletion(-)
  

Patch

diff --git a/doc/guides/rel_notes/release_23_11.rst b/doc/guides/rel_notes/release_23_11.rst
index f622d93384..7aaa78e6c9 100644
--- a/doc/guides/rel_notes/release_23_11.rst
+++ b/doc/guides/rel_notes/release_23_11.rst
@@ -149,6 +149,7 @@  New Features
   * Upgraded ENA HAL to latest version.
   * Added support for connection tracking allowance utilization metric.
   * Added support for reporting rx overrun errors in xstats.
+  * Added support for ENA-express metrics.
 
 * **Updated Solarflare net driver.**
 
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index b3ebda6049..59cb2792d4 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -66,6 +66,9 @@  struct ena_stats {
 #define ENA_STAT_GLOBAL_ENTRY(stat) \
 	ENA_STAT_ENTRY(stat, dev)
 
+#define ENA_STAT_ENA_SRD_ENTRY(stat) \
+	ENA_STAT_ENTRY(stat, srd)
+
 /* Device arguments */
 #define ENA_DEVARG_LARGE_LLQ_HDR "large_llq_hdr"
 /* Timeout in seconds after which a single uncompleted Tx packet should be
@@ -106,6 +109,14 @@  static struct ena_stats ena_stats_metrics_strings[] = {
 	ENA_STAT_METRICS_ENTRY(conntrack_allowance_available),
 };
 
+static const struct ena_stats ena_stats_srd_strings[] = {
+	ENA_STAT_ENA_SRD_ENTRY(ena_srd_mode),
+	ENA_STAT_ENA_SRD_ENTRY(ena_srd_tx_pkts),
+	ENA_STAT_ENA_SRD_ENTRY(ena_srd_eligible_tx_pkts),
+	ENA_STAT_ENA_SRD_ENTRY(ena_srd_rx_pkts),
+	ENA_STAT_ENA_SRD_ENTRY(ena_srd_resource_utilization),
+};
+
 static const struct ena_stats ena_stats_tx_strings[] = {
 	ENA_STAT_TX_ENTRY(cnt),
 	ENA_STAT_TX_ENTRY(bytes),
@@ -132,9 +143,11 @@  static const struct ena_stats ena_stats_rx_strings[] = {
 #define ENA_STATS_ARRAY_GLOBAL	ARRAY_SIZE(ena_stats_global_strings)
 #define ENA_STATS_ARRAY_METRICS	ARRAY_SIZE(ena_stats_metrics_strings)
 #define ENA_STATS_ARRAY_METRICS_LEGACY	(ENA_STATS_ARRAY_METRICS - 1)
+#define ENA_STATS_ARRAY_ENA_SRD	ARRAY_SIZE(ena_stats_srd_strings)
 #define ENA_STATS_ARRAY_TX	ARRAY_SIZE(ena_stats_tx_strings)
 #define ENA_STATS_ARRAY_RX	ARRAY_SIZE(ena_stats_rx_strings)
 
+
 #define QUEUE_OFFLOADS (RTE_ETH_TX_OFFLOAD_TCP_CKSUM |\
 			RTE_ETH_TX_OFFLOAD_UDP_CKSUM |\
 			RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |\
@@ -272,6 +285,8 @@  static int ena_parse_devargs(struct ena_adapter *adapter,
 static void ena_copy_customer_metrics(struct ena_adapter *adapter,
 					uint64_t *buf,
 					size_t buf_size);
+static void ena_copy_ena_srd_info(struct ena_adapter *adapter,
+				  struct ena_stats_srd *srd_info);
 static int ena_setup_rx_intr(struct rte_eth_dev *dev);
 static int ena_rx_queue_intr_enable(struct rte_eth_dev *dev,
 				    uint16_t queue_id);
@@ -324,6 +339,7 @@  enum ena_mp_req {
 	ENA_MP_IND_TBL_GET,
 	ENA_MP_IND_TBL_SET,
 	ENA_MP_CUSTOMER_METRICS_GET,
+	ENA_MP_SRD_STATS_GET,
 };
 
 /** Proxy message body. Shared between requests and responses. */
@@ -581,6 +597,22 @@  ENA_PROXY_DESC(ena_com_get_customer_metrics, ENA_MP_CUSTOMER_METRICS_GET,
 }),
 	struct ena_com_dev *ena_dev, char *buf, size_t buf_size);
 
+ENA_PROXY_DESC(ena_com_get_ena_srd_info, ENA_MP_SRD_STATS_GET,
+({
+	ENA_TOUCH(adapter);
+	ENA_TOUCH(req);
+	ENA_TOUCH(ena_dev);
+	ENA_TOUCH(info);
+}),
+({
+	ENA_TOUCH(rsp);
+	ENA_TOUCH(ena_dev);
+	if ((struct ena_stats_srd *)info != &adapter->srd_stats)
+		rte_memcpy((struct ena_stats_srd *)info,
+				&adapter->srd_stats,
+				sizeof(struct ena_stats_srd));
+}),
+	struct ena_com_dev *ena_dev, struct ena_admin_ena_srd_info *info);
 
 static inline void ena_trigger_reset(struct ena_adapter *adapter,
 				     enum ena_regs_reset_reason_types reason)
@@ -787,6 +819,7 @@  static unsigned int ena_xstats_calc_num(struct rte_eth_dev_data *data)
 
 	return ENA_STATS_ARRAY_GLOBAL +
 		adapter->metrics_num +
+		ENA_STATS_ARRAY_ENA_SRD +
 		(data->nb_tx_queues * ENA_STATS_ARRAY_TX) +
 		(data->nb_rx_queues * ENA_STATS_ARRAY_RX);
 }
@@ -3238,6 +3271,27 @@  static void ena_copy_customer_metrics(struct ena_adapter *adapter, uint64_t *buf
 	}
 }
 
+static void ena_copy_ena_srd_info(struct ena_adapter *adapter,
+		struct ena_stats_srd *srd_info)
+{
+	int rc;
+
+	if (!ena_com_get_cap(&adapter->ena_dev, ENA_ADMIN_ENA_SRD_INFO))
+		return;
+
+	rte_spinlock_lock(&adapter->admin_lock);
+	rc = ENA_PROXY(adapter,
+		       ena_com_get_ena_srd_info,
+		       &adapter->ena_dev,
+		       (struct ena_admin_ena_srd_info *)srd_info);
+	rte_spinlock_unlock(&adapter->admin_lock);
+	if (rc != ENA_COM_OK && rc != ENA_COM_UNSUPPORTED) {
+		PMD_DRV_LOG(WARNING,
+				"Failed to get ENA express srd info, rc: %d\n", rc);
+		return;
+	}
+}
+
 /**
  * DPDK callback to retrieve names of extended device statistics
  *
@@ -3271,6 +3325,11 @@  static int ena_xstats_get_names(struct rte_eth_dev *dev,
 			    ena_stats_metrics_strings[stat].name,
 			    RTE_ETH_XSTATS_NAME_SIZE);
 
+	for (stat = 0; stat < ENA_STATS_ARRAY_ENA_SRD; stat++, count++)
+		rte_strscpy(xstats_names[count].name,
+			    ena_stats_srd_strings[stat].name,
+			    RTE_ETH_XSTATS_NAME_SIZE);
+
 	for (stat = 0; stat < ENA_STATS_ARRAY_RX; stat++)
 		for (i = 0; i < dev->data->nb_rx_queues; i++, count++)
 			snprintf(xstats_names[count].name,
@@ -3341,6 +3400,15 @@  static int ena_xstats_get_names_by_id(struct rte_eth_dev *dev,
 		}
 
 		id -= adapter->metrics_num;
+
+		if (id < ENA_STATS_ARRAY_ENA_SRD) {
+			rte_strscpy(xstats_names[i].name,
+				    ena_stats_srd_strings[id].name,
+				    RTE_ETH_XSTATS_NAME_SIZE);
+			continue;
+		}
+		id -= ENA_STATS_ARRAY_ENA_SRD;
+
 		if (id < ENA_STATS_ARRAY_RX) {
 			qid = id / dev->data->nb_rx_queues;
 			id %= dev->data->nb_rx_queues;
@@ -3392,6 +3460,7 @@  static int ena_xstats_get(struct rte_eth_dev *dev,
 	int stat_offset;
 	void *stats_begin;
 	uint64_t metrics_stats[ENA_MAX_CUSTOMER_METRICS];
+	struct ena_stats_srd srd_info = {0};
 
 	if (n < xstats_count)
 		return xstats_count;
@@ -3418,6 +3487,15 @@  static int ena_xstats_get(struct rte_eth_dev *dev,
 		    ((char *)stats_begin + stat_offset));
 	}
 
+	ena_copy_ena_srd_info(adapter, &srd_info);
+	stats_begin = &srd_info;
+	for (stat = 0; stat < ENA_STATS_ARRAY_ENA_SRD; stat++, count++) {
+		stat_offset = ena_stats_srd_strings[stat].stat_offset;
+		xstats[count].id = count;
+		xstats[count].value = *((uint64_t *)
+		    ((char *)stats_begin + stat_offset));
+	}
+
 	for (stat = 0; stat < ENA_STATS_ARRAY_RX; stat++) {
 		for (i = 0; i < dev->data->nb_rx_queues; i++, count++) {
 			stat_offset = ena_stats_rx_strings[stat].stat_offset;
@@ -3455,7 +3533,9 @@  static int ena_xstats_get_by_id(struct rte_eth_dev *dev,
 	int qid;
 	int valid = 0;
 	bool were_metrics_copied = false;
+	bool was_srd_info_copied = false;
 	uint64_t metrics_stats[ENA_MAX_CUSTOMER_METRICS];
+	struct ena_stats_srd srd_info = {0};
 
 	for (i = 0; i < n; ++i) {
 		id = ids[i];
@@ -3485,8 +3565,27 @@  static int ena_xstats_get_by_id(struct rte_eth_dev *dev,
 			continue;
 		}
 
-		/* Check if id belongs to rx queue statistics */
+		/* Check if id belongs to SRD info statistics */
 		id -= adapter->metrics_num;
+
+		if (id < ENA_STATS_ARRAY_ENA_SRD) {
+			/*
+			 * Avoid reading srd info multiple times in a single
+			 * function call, as it requires communication with the
+			 * admin queue.
+			 */
+			if (!was_srd_info_copied) {
+				was_srd_info_copied = true;
+				ena_copy_ena_srd_info(adapter, &srd_info);
+			}
+			values[i] = *((uint64_t *)&adapter->srd_stats + id);
+			++valid;
+			continue;
+		}
+
+		/* Check if id belongs to rx queue statistics */
+		id -= ENA_STATS_ARRAY_ENA_SRD;
+
 		rx_entries = ENA_STATS_ARRAY_RX * dev->data->nb_rx_queues;
 		if (id < rx_entries) {
 			qid = id % dev->data->nb_rx_queues;
@@ -3981,6 +4080,10 @@  ena_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
 				(char *)adapter->metrics_stats,
 				sizeof(uint64_t) * adapter->metrics_num);
 		break;
+	case ENA_MP_SRD_STATS_GET:
+		res = ena_com_get_ena_srd_info(ena_dev,
+				(struct ena_admin_ena_srd_info *)&adapter->srd_stats);
+		break;
 	default:
 		PMD_DRV_LOG(ERR, "Unknown request type %d\n", req->type);
 		res = -EINVAL;
diff --git a/drivers/net/ena/ena_ethdev.h b/drivers/net/ena/ena_ethdev.h
index 3f29764ca6..4988fbffb5 100644
--- a/drivers/net/ena/ena_ethdev.h
+++ b/drivers/net/ena/ena_ethdev.h
@@ -252,6 +252,23 @@  struct ena_stats_metrics {
 	uint64_t conntrack_allowance_available;
 };
 
+struct ena_stats_srd {
+	/* Describes which ENA Express features are enabled */
+	uint64_t ena_srd_mode;
+
+	/* Number of packets transmitted over ENA SRD */
+	uint64_t ena_srd_tx_pkts;
+
+	/* Number of packets transmitted or could have been transmitted over ENA SRD */
+	uint64_t ena_srd_eligible_tx_pkts;
+
+	/* Number of packets received over ENA SRD */
+	uint64_t ena_srd_rx_pkts;
+
+	/* Percentage of the ENA SRD resources that is in use */
+	uint64_t ena_srd_resource_utilization;
+};
+
 struct ena_offloads {
 	uint32_t tx_offloads;
 	uint32_t rx_offloads;
@@ -329,6 +346,7 @@  struct ena_adapter {
 	 */
 	uint64_t metrics_stats[ENA_MAX_CUSTOMER_METRICS] __rte_cache_aligned;
 	uint16_t metrics_num;
+	struct ena_stats_srd srd_stats __rte_cache_aligned;
 };
 
 int ena_mp_indirect_table_set(struct ena_adapter *adapter);