Skip to content

Commit 49f66e1

Browse files
davidarinzonkuba-moo
authored andcommitted
net: ena: Add ENA Express metrics support
ENA Express metrics, called `ena_srd` are exposed to customers via `ethtool`. The metrics allow customers to check the configuration (mode), tx/rx counters as well as resource utilization. The documentation is also updated to provide a general explanation about ENA Express as well as links for further information about metrics and configurations. Signed-off-by: Igor Chauskin <[email protected]> Signed-off-by: David Arinzon <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 46ae4d0 commit 49f66e1

File tree

7 files changed

+142
-34
lines changed

7 files changed

+142
-34
lines changed

Documentation/networking/device_drivers/ethernet/amazon/ena.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,11 @@ per-queue stats) from the device.
230230

231231
In addition the driver logs the stats to syslog upon device reset.
232232

233+
On supported instance types, the statistics will also include the
234+
ENA Express data (fields prefixed with `ena_srd`). For a complete
235+
documentation of ENA Express data refer to
236+
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ena-express.html#ena-express-monitor
237+
233238
MTU
234239
===
235240

drivers/net/ethernet/amazon/ena/ena_admin_defs.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ enum ena_admin_aq_feature_id {
5151
/* device capabilities */
5252
enum ena_admin_aq_caps_id {
5353
ENA_ADMIN_ENI_STATS = 0,
54+
/* ENA SRD customer metrics */
55+
ENA_ADMIN_ENA_SRD_INFO = 1,
5456
};
5557

5658
enum ena_admin_placement_policy_type {
@@ -99,13 +101,25 @@ enum ena_admin_get_stats_type {
99101
ENA_ADMIN_GET_STATS_TYPE_EXTENDED = 1,
100102
/* extra HW stats for specific network interface */
101103
ENA_ADMIN_GET_STATS_TYPE_ENI = 2,
104+
/* extra HW stats for ENA SRD */
105+
ENA_ADMIN_GET_STATS_TYPE_ENA_SRD = 3,
102106
};
103107

104108
enum ena_admin_get_stats_scope {
105109
ENA_ADMIN_SPECIFIC_QUEUE = 0,
106110
ENA_ADMIN_ETH_TRAFFIC = 1,
107111
};
108112

113+
/* ENA SRD configuration for ENI */
114+
enum ena_admin_ena_srd_flags {
115+
/* Feature enabled */
116+
ENA_ADMIN_ENA_SRD_ENABLED = BIT(0),
117+
/* UDP support enabled */
118+
ENA_ADMIN_ENA_SRD_UDP_ENABLED = BIT(1),
119+
/* Bypass Rx UDP ordering */
120+
ENA_ADMIN_ENA_SRD_UDP_ORDERING_BYPASS_ENABLED = BIT(2),
121+
};
122+
109123
struct ena_admin_aq_common_desc {
110124
/* 11:0 : command_id
111125
* 15:12 : reserved12
@@ -419,6 +433,32 @@ struct ena_admin_eni_stats {
419433
u64 linklocal_allowance_exceeded;
420434
};
421435

436+
struct ena_admin_ena_srd_stats {
437+
/* Number of packets transmitted over ENA SRD */
438+
u64 ena_srd_tx_pkts;
439+
440+
/* Number of packets transmitted or could have been
441+
* transmitted over ENA SRD
442+
*/
443+
u64 ena_srd_eligible_tx_pkts;
444+
445+
/* Number of packets received over ENA SRD */
446+
u64 ena_srd_rx_pkts;
447+
448+
/* Percentage of the ENA SRD resources that is in use */
449+
u64 ena_srd_resource_utilization;
450+
};
451+
452+
/* ENA SRD Statistics Command */
453+
struct ena_admin_ena_srd_info {
454+
/* ENA SRD configuration bitmap. See ena_admin_ena_srd_flags for
455+
* details
456+
*/
457+
u64 flags;
458+
459+
struct ena_admin_ena_srd_stats ena_srd_stats;
460+
};
461+
422462
struct ena_admin_acq_get_stats_resp {
423463
struct ena_admin_acq_common_desc acq_common_desc;
424464

@@ -428,6 +468,8 @@ struct ena_admin_acq_get_stats_resp {
428468
struct ena_admin_basic_stats basic_stats;
429469

430470
struct ena_admin_eni_stats eni_stats;
471+
472+
struct ena_admin_ena_srd_info ena_srd_info;
431473
} u;
432474
};
433475

drivers/net/ethernet/amazon/ena/ena_com.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2152,6 +2152,27 @@ int ena_com_get_eni_stats(struct ena_com_dev *ena_dev,
21522152
return ret;
21532153
}
21542154

2155+
int ena_com_get_ena_srd_info(struct ena_com_dev *ena_dev,
2156+
struct ena_admin_ena_srd_info *info)
2157+
{
2158+
struct ena_com_stats_ctx ctx;
2159+
int ret;
2160+
2161+
if (!ena_com_get_cap(ena_dev, ENA_ADMIN_ENA_SRD_INFO)) {
2162+
netdev_err(ena_dev->net_device, "Capability %d isn't supported\n",
2163+
ENA_ADMIN_ENA_SRD_INFO);
2164+
return -EOPNOTSUPP;
2165+
}
2166+
2167+
memset(&ctx, 0x0, sizeof(ctx));
2168+
ret = ena_get_dev_stats(ena_dev, &ctx, ENA_ADMIN_GET_STATS_TYPE_ENA_SRD);
2169+
if (likely(ret == 0))
2170+
memcpy(info, &ctx.get_resp.u.ena_srd_info,
2171+
sizeof(ctx.get_resp.u.ena_srd_info));
2172+
2173+
return ret;
2174+
}
2175+
21552176
int ena_com_get_dev_basic_stats(struct ena_com_dev *ena_dev,
21562177
struct ena_admin_basic_stats *stats)
21572178
{

drivers/net/ethernet/amazon/ena/ena_com.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,15 @@ int ena_com_get_dev_basic_stats(struct ena_com_dev *ena_dev,
595595
int ena_com_get_eni_stats(struct ena_com_dev *ena_dev,
596596
struct ena_admin_eni_stats *stats);
597597

598+
/* ena_com_get_ena_srd_info - Get ENA SRD network interface statistics
599+
* @ena_dev: ENA communication layer struct
600+
* @info: ena srd stats and flags
601+
*
602+
* @return: 0 on Success and negative value otherwise.
603+
*/
604+
int ena_com_get_ena_srd_info(struct ena_com_dev *ena_dev,
605+
struct ena_admin_ena_srd_info *info);
606+
598607
/* ena_com_set_dev_mtu - Configure the device mtu.
599608
* @ena_dev: ENA communication layer struct
600609
* @mtu: mtu value

drivers/net/ethernet/amazon/ena/ena_ethtool.c

Lines changed: 64 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,14 @@ struct ena_stats {
4141
#define ENA_STAT_ENI_ENTRY(stat) \
4242
ENA_STAT_HW_ENTRY(stat, eni_stats)
4343

44+
#define ENA_STAT_ENA_SRD_ENTRY(stat) \
45+
ENA_STAT_HW_ENTRY(stat, ena_srd_stats)
46+
47+
#define ENA_STAT_ENA_SRD_MODE_ENTRY(stat) { \
48+
.name = #stat, \
49+
.stat_offset = offsetof(struct ena_admin_ena_srd_info, flags) / sizeof(u64) \
50+
}
51+
4452
static const struct ena_stats ena_stats_global_strings[] = {
4553
ENA_STAT_GLOBAL_ENTRY(tx_timeout),
4654
ENA_STAT_GLOBAL_ENTRY(suspend),
@@ -60,6 +68,14 @@ static const struct ena_stats ena_stats_eni_strings[] = {
6068
ENA_STAT_ENI_ENTRY(linklocal_allowance_exceeded),
6169
};
6270

71+
static const struct ena_stats ena_srd_info_strings[] = {
72+
ENA_STAT_ENA_SRD_MODE_ENTRY(ena_srd_mode),
73+
ENA_STAT_ENA_SRD_ENTRY(ena_srd_tx_pkts),
74+
ENA_STAT_ENA_SRD_ENTRY(ena_srd_eligible_tx_pkts),
75+
ENA_STAT_ENA_SRD_ENTRY(ena_srd_rx_pkts),
76+
ENA_STAT_ENA_SRD_ENTRY(ena_srd_resource_utilization)
77+
};
78+
6379
static const struct ena_stats ena_stats_tx_strings[] = {
6480
ENA_STAT_TX_ENTRY(cnt),
6581
ENA_STAT_TX_ENTRY(bytes),
@@ -112,7 +128,8 @@ static const struct ena_stats ena_stats_ena_com_strings[] = {
112128
#define ENA_STATS_ARRAY_TX ARRAY_SIZE(ena_stats_tx_strings)
113129
#define ENA_STATS_ARRAY_RX ARRAY_SIZE(ena_stats_rx_strings)
114130
#define ENA_STATS_ARRAY_ENA_COM ARRAY_SIZE(ena_stats_ena_com_strings)
115-
#define ENA_STATS_ARRAY_ENI(adapter) ARRAY_SIZE(ena_stats_eni_strings)
131+
#define ENA_STATS_ARRAY_ENI ARRAY_SIZE(ena_stats_eni_strings)
132+
#define ENA_STATS_ARRAY_ENA_SRD ARRAY_SIZE(ena_srd_info_strings)
116133

117134
static void ena_safe_update_stat(u64 *src, u64 *dst,
118135
struct u64_stats_sync *syncp)
@@ -179,7 +196,7 @@ static void ena_dev_admin_queue_stats(struct ena_adapter *adapter, u64 **data)
179196

180197
static void ena_get_stats(struct ena_adapter *adapter,
181198
u64 *data,
182-
bool eni_stats_needed)
199+
bool hw_stats_needed)
183200
{
184201
const struct ena_stats *ena_stats;
185202
u64 *ptr;
@@ -193,15 +210,37 @@ static void ena_get_stats(struct ena_adapter *adapter,
193210
ena_safe_update_stat(ptr, data++, &adapter->syncp);
194211
}
195212

196-
if (eni_stats_needed) {
197-
ena_update_hw_stats(adapter);
198-
for (i = 0; i < ENA_STATS_ARRAY_ENI(adapter); i++) {
199-
ena_stats = &ena_stats_eni_strings[i];
213+
if (hw_stats_needed) {
214+
if (ena_com_get_cap(adapter->ena_dev, ENA_ADMIN_ENI_STATS)) {
215+
ena_com_get_eni_stats(adapter->ena_dev, &adapter->eni_stats);
216+
/* Updating regardless of rc - once we told ethtool how many stats we have
217+
* it will print that much stats. We can't leave holes in the stats
218+
*/
219+
for (i = 0; i < ENA_STATS_ARRAY_ENI; i++) {
220+
ena_stats = &ena_stats_eni_strings[i];
200221

201-
ptr = (u64 *)&adapter->eni_stats +
202-
ena_stats->stat_offset;
222+
ptr = (u64 *)&adapter->eni_stats +
223+
ena_stats->stat_offset;
203224

225+
ena_safe_update_stat(ptr, data++, &adapter->syncp);
226+
}
227+
}
228+
229+
if (ena_com_get_cap(adapter->ena_dev, ENA_ADMIN_ENA_SRD_INFO)) {
230+
ena_com_get_ena_srd_info(adapter->ena_dev, &adapter->ena_srd_info);
231+
/* Get ENA SRD mode */
232+
ptr = (u64 *)&adapter->ena_srd_info;
204233
ena_safe_update_stat(ptr, data++, &adapter->syncp);
234+
for (i = 1; i < ENA_STATS_ARRAY_ENA_SRD; i++) {
235+
ena_stats = &ena_srd_info_strings[i];
236+
/* Wrapped within an outer struct - need to accommodate an
237+
* additional offset of the ENA SRD mode that was already processed
238+
*/
239+
ptr = (u64 *)&adapter->ena_srd_info +
240+
ena_stats->stat_offset + 1;
241+
242+
ena_safe_update_stat(ptr, data++, &adapter->syncp);
243+
}
205244
}
206245
}
207246

@@ -214,9 +253,8 @@ static void ena_get_ethtool_stats(struct net_device *netdev,
214253
u64 *data)
215254
{
216255
struct ena_adapter *adapter = netdev_priv(netdev);
217-
struct ena_com_dev *dev = adapter->ena_dev;
218256

219-
ena_get_stats(adapter, data, ena_com_get_cap(dev, ENA_ADMIN_ENI_STATS));
257+
ena_get_stats(adapter, data, true);
220258
}
221259

222260
static int ena_get_sw_stats_count(struct ena_adapter *adapter)
@@ -228,9 +266,8 @@ static int ena_get_sw_stats_count(struct ena_adapter *adapter)
228266

229267
static int ena_get_hw_stats_count(struct ena_adapter *adapter)
230268
{
231-
bool supported = ena_com_get_cap(adapter->ena_dev, ENA_ADMIN_ENI_STATS);
232-
233-
return ENA_STATS_ARRAY_ENI(adapter) * supported;
269+
return ENA_STATS_ARRAY_ENI * ena_com_get_cap(adapter->ena_dev, ENA_ADMIN_ENI_STATS) +
270+
ENA_STATS_ARRAY_ENA_SRD * ena_com_get_cap(adapter->ena_dev, ENA_ADMIN_ENA_SRD_INFO);
234271
}
235272

236273
int ena_get_sset_count(struct net_device *netdev, int sset)
@@ -291,7 +328,7 @@ static void ena_com_dev_strings(u8 **data)
291328

292329
static void ena_get_strings(struct ena_adapter *adapter,
293330
u8 *data,
294-
bool eni_stats_needed)
331+
bool hw_stats_needed)
295332
{
296333
const struct ena_stats *ena_stats;
297334
int i;
@@ -301,10 +338,18 @@ static void ena_get_strings(struct ena_adapter *adapter,
301338
ethtool_puts(&data, ena_stats->name);
302339
}
303340

304-
if (eni_stats_needed) {
305-
for (i = 0; i < ENA_STATS_ARRAY_ENI(adapter); i++) {
306-
ena_stats = &ena_stats_eni_strings[i];
307-
ethtool_puts(&data, ena_stats->name);
341+
if (hw_stats_needed) {
342+
if (ena_com_get_cap(adapter->ena_dev, ENA_ADMIN_ENI_STATS)) {
343+
for (i = 0; i < ENA_STATS_ARRAY_ENI; i++) {
344+
ena_stats = &ena_stats_eni_strings[i];
345+
ethtool_puts(&data, ena_stats->name);
346+
}
347+
}
348+
if (ena_com_get_cap(adapter->ena_dev, ENA_ADMIN_ENA_SRD_INFO)) {
349+
for (i = 0; i < ENA_STATS_ARRAY_ENA_SRD; i++) {
350+
ena_stats = &ena_srd_info_strings[i];
351+
ethtool_puts(&data, ena_stats->name);
352+
}
308353
}
309354
}
310355

@@ -317,11 +362,10 @@ static void ena_get_ethtool_strings(struct net_device *netdev,
317362
u8 *data)
318363
{
319364
struct ena_adapter *adapter = netdev_priv(netdev);
320-
struct ena_com_dev *dev = adapter->ena_dev;
321365

322366
switch (sset) {
323367
case ETH_SS_STATS:
324-
ena_get_strings(adapter, data, ena_com_get_cap(dev, ENA_ADMIN_ENI_STATS));
368+
ena_get_strings(adapter, data, true);
325369
break;
326370
}
327371
}

drivers/net/ethernet/amazon/ena/ena_netdev.c

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2798,19 +2798,6 @@ static void ena_config_debug_area(struct ena_adapter *adapter)
27982798
ena_com_delete_debug_area(adapter->ena_dev);
27992799
}
28002800

2801-
int ena_update_hw_stats(struct ena_adapter *adapter)
2802-
{
2803-
int rc;
2804-
2805-
rc = ena_com_get_eni_stats(adapter->ena_dev, &adapter->eni_stats);
2806-
if (rc) {
2807-
netdev_err(adapter->netdev, "Failed to get ENI stats\n");
2808-
return rc;
2809-
}
2810-
2811-
return 0;
2812-
}
2813-
28142801
static void ena_get_stats64(struct net_device *netdev,
28152802
struct rtnl_link_stats64 *stats)
28162803
{

drivers/net/ethernet/amazon/ena/ena_netdev.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ struct ena_adapter {
373373
struct u64_stats_sync syncp;
374374
struct ena_stats_dev dev_stats;
375375
struct ena_admin_eni_stats eni_stats;
376+
struct ena_admin_ena_srd_info ena_srd_info;
376377

377378
/* last queue index that was checked for uncompleted tx packets */
378379
u32 last_monitored_tx_qid;
@@ -390,7 +391,6 @@ void ena_dump_stats_to_dmesg(struct ena_adapter *adapter);
390391

391392
void ena_dump_stats_to_buf(struct ena_adapter *adapter, u8 *buf);
392393

393-
int ena_update_hw_stats(struct ena_adapter *adapter);
394394

395395
int ena_update_queue_params(struct ena_adapter *adapter,
396396
u32 new_tx_size,

0 commit comments

Comments
 (0)