@@ -127,6 +127,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 Intel cpfl driver.**
@@ -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,6 +143,7 @@ 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)
@@ -272,6 +284,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 +338,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 +596,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 +818,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);
}
@@ -3250,6 +3282,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
*
@@ -3282,6 +3335,10 @@ static int ena_xstats_get_names(struct rte_eth_dev *dev,
rte_strscpy(xstats_names[count].name,
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++)
@@ -3353,6 +3410,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;
@@ -3404,6 +3470,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;
@@ -3430,6 +3497,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;
@@ -3467,7 +3543,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];
@@ -3497,8 +3575,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;
@@ -3993,6 +4090,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;
@@ -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);