Skip to content

Commit 403cdc4

Browse files
davidarinzonkuba-moo
authored andcommitted
net: ena: Extend customer metrics reporting support
ENA currently supports the following customer metrics: - `bw_in_allowance_exceeded` - `bw_out_allowance_exceeded` - `conntrack_allowance_exceeded` - `linklocal_allowance_exceeded` - `pps_allowance_exceeded` This patch adds a new metric named: `conntrack_allowance_available`. Information about these metrics is available in [1]. In addition, the interface between the driver and the device has been upgraded to allow more flexibility and expendability to additional metrics in the future. [1]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-network-performance-ena.html#network-performance-metrics Signed-off-by: Ron Beider <[email protected]> Signed-off-by: Shahar Itzko <[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 49f66e1 commit 403cdc4

File tree

5 files changed

+344
-78
lines changed

5 files changed

+344
-78
lines changed

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,21 @@
77

88
#define ENA_ADMIN_RSS_KEY_PARTS 10
99

10+
#define ENA_ADMIN_CUSTOMER_METRICS_SUPPORT_MASK 0x3F
11+
#define ENA_ADMIN_CUSTOMER_METRICS_MIN_SUPPORT_MASK 0x1F
12+
13+
/* customer metrics - in correlation with
14+
* ENA_ADMIN_CUSTOMER_METRICS_SUPPORT_MASK
15+
*/
16+
enum ena_admin_customer_metrics_id {
17+
ENA_ADMIN_BW_IN_ALLOWANCE_EXCEEDED = 0,
18+
ENA_ADMIN_BW_OUT_ALLOWANCE_EXCEEDED = 1,
19+
ENA_ADMIN_PPS_ALLOWANCE_EXCEEDED = 2,
20+
ENA_ADMIN_CONNTRACK_ALLOWANCE_EXCEEDED = 3,
21+
ENA_ADMIN_LINKLOCAL_ALLOWANCE_EXCEEDED = 4,
22+
ENA_ADMIN_CONNTRACK_ALLOWANCE_AVAILABLE = 5,
23+
};
24+
1025
enum ena_admin_aq_opcode {
1126
ENA_ADMIN_CREATE_SQ = 1,
1227
ENA_ADMIN_DESTROY_SQ = 2,
@@ -53,6 +68,7 @@ enum ena_admin_aq_caps_id {
5368
ENA_ADMIN_ENI_STATS = 0,
5469
/* ENA SRD customer metrics */
5570
ENA_ADMIN_ENA_SRD_INFO = 1,
71+
ENA_ADMIN_CUSTOMER_METRICS = 2,
5672
};
5773

5874
enum ena_admin_placement_policy_type {
@@ -103,6 +119,7 @@ enum ena_admin_get_stats_type {
103119
ENA_ADMIN_GET_STATS_TYPE_ENI = 2,
104120
/* extra HW stats for ENA SRD */
105121
ENA_ADMIN_GET_STATS_TYPE_ENA_SRD = 3,
122+
ENA_ADMIN_GET_STATS_TYPE_CUSTOMER_METRICS = 4,
106123
};
107124

108125
enum ena_admin_get_stats_scope {
@@ -377,6 +394,9 @@ struct ena_admin_aq_get_stats_cmd {
377394
* stats of other device
378395
*/
379396
u16 device_id;
397+
398+
/* a bitmap representing the requested metric values */
399+
u64 requested_metrics;
380400
};
381401

382402
/* Basic Statistics Command. */
@@ -459,6 +479,14 @@ struct ena_admin_ena_srd_info {
459479
struct ena_admin_ena_srd_stats ena_srd_stats;
460480
};
461481

482+
/* Customer Metrics Command. */
483+
struct ena_admin_customer_metrics {
484+
/* A bitmap representing the reported customer metrics according to
485+
* the order they are reported
486+
*/
487+
u64 reported_metrics;
488+
};
489+
462490
struct ena_admin_acq_get_stats_resp {
463491
struct ena_admin_acq_common_desc acq_common_desc;
464492

@@ -470,6 +498,8 @@ struct ena_admin_acq_get_stats_resp {
470498
struct ena_admin_eni_stats eni_stats;
471499

472500
struct ena_admin_ena_srd_info ena_srd_info;
501+
502+
struct ena_admin_customer_metrics customer_metrics;
473503
} u;
474504
};
475505

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

Lines changed: 127 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1881,6 +1881,56 @@ int ena_com_get_link_params(struct ena_com_dev *ena_dev,
18811881
return ena_com_get_feature(ena_dev, resp, ENA_ADMIN_LINK_CONFIG, 0);
18821882
}
18831883

1884+
static int ena_get_dev_stats(struct ena_com_dev *ena_dev,
1885+
struct ena_com_stats_ctx *ctx,
1886+
enum ena_admin_get_stats_type type)
1887+
{
1888+
struct ena_admin_acq_get_stats_resp *get_resp = &ctx->get_resp;
1889+
struct ena_admin_aq_get_stats_cmd *get_cmd = &ctx->get_cmd;
1890+
struct ena_com_admin_queue *admin_queue;
1891+
int ret;
1892+
1893+
admin_queue = &ena_dev->admin_queue;
1894+
1895+
get_cmd->aq_common_descriptor.opcode = ENA_ADMIN_GET_STATS;
1896+
get_cmd->aq_common_descriptor.flags = 0;
1897+
get_cmd->type = type;
1898+
1899+
ret = ena_com_execute_admin_command(admin_queue,
1900+
(struct ena_admin_aq_entry *)get_cmd,
1901+
sizeof(*get_cmd),
1902+
(struct ena_admin_acq_entry *)get_resp,
1903+
sizeof(*get_resp));
1904+
1905+
if (unlikely(ret))
1906+
netdev_err(ena_dev->net_device, "Failed to get stats. error: %d\n", ret);
1907+
1908+
return ret;
1909+
}
1910+
1911+
static void ena_com_set_supported_customer_metrics(struct ena_com_dev *ena_dev)
1912+
{
1913+
struct ena_customer_metrics *customer_metrics;
1914+
struct ena_com_stats_ctx ctx;
1915+
int ret;
1916+
1917+
customer_metrics = &ena_dev->customer_metrics;
1918+
if (!ena_com_get_cap(ena_dev, ENA_ADMIN_CUSTOMER_METRICS)) {
1919+
customer_metrics->supported_metrics = ENA_ADMIN_CUSTOMER_METRICS_MIN_SUPPORT_MASK;
1920+
return;
1921+
}
1922+
1923+
memset(&ctx, 0x0, sizeof(ctx));
1924+
ctx.get_cmd.requested_metrics = ENA_ADMIN_CUSTOMER_METRICS_SUPPORT_MASK;
1925+
ret = ena_get_dev_stats(ena_dev, &ctx, ENA_ADMIN_GET_STATS_TYPE_CUSTOMER_METRICS);
1926+
if (likely(ret == 0))
1927+
customer_metrics->supported_metrics =
1928+
ctx.get_resp.u.customer_metrics.reported_metrics;
1929+
else
1930+
netdev_err(ena_dev->net_device,
1931+
"Failed to query customer metrics support. error: %d\n", ret);
1932+
}
1933+
18841934
int ena_com_get_dev_attr_feat(struct ena_com_dev *ena_dev,
18851935
struct ena_com_dev_get_features_ctx *get_feat_ctx)
18861936
{
@@ -1960,6 +2010,8 @@ int ena_com_get_dev_attr_feat(struct ena_com_dev *ena_dev,
19602010
else
19612011
return rc;
19622012

2013+
ena_com_set_supported_customer_metrics(ena_dev);
2014+
19632015
return 0;
19642016
}
19652017

@@ -2104,33 +2156,6 @@ int ena_com_dev_reset(struct ena_com_dev *ena_dev,
21042156
return 0;
21052157
}
21062158

2107-
static int ena_get_dev_stats(struct ena_com_dev *ena_dev,
2108-
struct ena_com_stats_ctx *ctx,
2109-
enum ena_admin_get_stats_type type)
2110-
{
2111-
struct ena_admin_aq_get_stats_cmd *get_cmd = &ctx->get_cmd;
2112-
struct ena_admin_acq_get_stats_resp *get_resp = &ctx->get_resp;
2113-
struct ena_com_admin_queue *admin_queue;
2114-
int ret;
2115-
2116-
admin_queue = &ena_dev->admin_queue;
2117-
2118-
get_cmd->aq_common_descriptor.opcode = ENA_ADMIN_GET_STATS;
2119-
get_cmd->aq_common_descriptor.flags = 0;
2120-
get_cmd->type = type;
2121-
2122-
ret = ena_com_execute_admin_command(admin_queue,
2123-
(struct ena_admin_aq_entry *)get_cmd,
2124-
sizeof(*get_cmd),
2125-
(struct ena_admin_acq_entry *)get_resp,
2126-
sizeof(*get_resp));
2127-
2128-
if (unlikely(ret))
2129-
netdev_err(ena_dev->net_device, "Failed to get stats. error: %d\n", ret);
2130-
2131-
return ret;
2132-
}
2133-
21342159
int ena_com_get_eni_stats(struct ena_com_dev *ena_dev,
21352160
struct ena_admin_eni_stats *stats)
21362161
{
@@ -2188,6 +2213,50 @@ int ena_com_get_dev_basic_stats(struct ena_com_dev *ena_dev,
21882213
return ret;
21892214
}
21902215

2216+
int ena_com_get_customer_metrics(struct ena_com_dev *ena_dev, char *buffer, u32 len)
2217+
{
2218+
struct ena_admin_aq_get_stats_cmd *get_cmd;
2219+
struct ena_com_stats_ctx ctx;
2220+
int ret;
2221+
2222+
if (unlikely(len > ena_dev->customer_metrics.buffer_len)) {
2223+
netdev_err(ena_dev->net_device,
2224+
"Invalid buffer size %u. The given buffer is too big.\n", len);
2225+
return -EINVAL;
2226+
}
2227+
2228+
if (!ena_com_get_cap(ena_dev, ENA_ADMIN_CUSTOMER_METRICS)) {
2229+
netdev_err(ena_dev->net_device, "Capability %d not supported.\n",
2230+
ENA_ADMIN_CUSTOMER_METRICS);
2231+
return -EOPNOTSUPP;
2232+
}
2233+
2234+
if (!ena_dev->customer_metrics.supported_metrics) {
2235+
netdev_err(ena_dev->net_device, "No supported customer metrics.\n");
2236+
return -EOPNOTSUPP;
2237+
}
2238+
2239+
get_cmd = &ctx.get_cmd;
2240+
memset(&ctx, 0x0, sizeof(ctx));
2241+
ret = ena_com_mem_addr_set(ena_dev,
2242+
&get_cmd->u.control_buffer.address,
2243+
ena_dev->customer_metrics.buffer_dma_addr);
2244+
if (unlikely(ret)) {
2245+
netdev_err(ena_dev->net_device, "Memory address set failed.\n");
2246+
return ret;
2247+
}
2248+
2249+
get_cmd->u.control_buffer.length = ena_dev->customer_metrics.buffer_len;
2250+
get_cmd->requested_metrics = ena_dev->customer_metrics.supported_metrics;
2251+
ret = ena_get_dev_stats(ena_dev, &ctx, ENA_ADMIN_GET_STATS_TYPE_CUSTOMER_METRICS);
2252+
if (likely(ret == 0))
2253+
memcpy(buffer, ena_dev->customer_metrics.buffer_virt_addr, len);
2254+
else
2255+
netdev_err(ena_dev->net_device, "Failed to get customer metrics. error: %d\n", ret);
2256+
2257+
return ret;
2258+
}
2259+
21912260
int ena_com_set_dev_mtu(struct ena_com_dev *ena_dev, u32 mtu)
21922261
{
21932262
struct ena_com_admin_queue *admin_queue;
@@ -2727,6 +2796,24 @@ int ena_com_allocate_debug_area(struct ena_com_dev *ena_dev,
27272796
return 0;
27282797
}
27292798

2799+
int ena_com_allocate_customer_metrics_buffer(struct ena_com_dev *ena_dev)
2800+
{
2801+
struct ena_customer_metrics *customer_metrics = &ena_dev->customer_metrics;
2802+
2803+
customer_metrics->buffer_len = ENA_CUSTOMER_METRICS_BUFFER_SIZE;
2804+
customer_metrics->buffer_virt_addr = NULL;
2805+
2806+
customer_metrics->buffer_virt_addr =
2807+
dma_alloc_coherent(ena_dev->dmadev, customer_metrics->buffer_len,
2808+
&customer_metrics->buffer_dma_addr, GFP_KERNEL);
2809+
if (!customer_metrics->buffer_virt_addr) {
2810+
customer_metrics->buffer_len = 0;
2811+
return -ENOMEM;
2812+
}
2813+
2814+
return 0;
2815+
}
2816+
27302817
void ena_com_delete_host_info(struct ena_com_dev *ena_dev)
27312818
{
27322819
struct ena_host_attribute *host_attr = &ena_dev->host_attr;
@@ -2749,6 +2836,19 @@ void ena_com_delete_debug_area(struct ena_com_dev *ena_dev)
27492836
}
27502837
}
27512838

2839+
void ena_com_delete_customer_metrics_buffer(struct ena_com_dev *ena_dev)
2840+
{
2841+
struct ena_customer_metrics *customer_metrics = &ena_dev->customer_metrics;
2842+
2843+
if (customer_metrics->buffer_virt_addr) {
2844+
dma_free_coherent(ena_dev->dmadev, customer_metrics->buffer_len,
2845+
customer_metrics->buffer_virt_addr,
2846+
customer_metrics->buffer_dma_addr);
2847+
customer_metrics->buffer_virt_addr = NULL;
2848+
customer_metrics->buffer_len = 0;
2849+
}
2850+
}
2851+
27522852
int ena_com_set_host_attributes(struct ena_com_dev *ena_dev)
27532853
{
27542854
struct ena_host_attribute *host_attr = &ena_dev->host_attr;

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

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
#define ADMIN_CQ_SIZE(depth) ((depth) * sizeof(struct ena_admin_acq_entry))
4343
#define ADMIN_AENQ_SIZE(depth) ((depth) * sizeof(struct ena_admin_aenq_entry))
4444

45+
#define ENA_CUSTOMER_METRICS_BUFFER_SIZE 512
46+
4547
/*****************************************************************************/
4648
/*****************************************************************************/
4749
/* ENA adaptive interrupt moderation settings */
@@ -278,6 +280,16 @@ struct ena_rss {
278280

279281
};
280282

283+
struct ena_customer_metrics {
284+
/* in correlation with ENA_ADMIN_CUSTOMER_METRICS_SUPPORT_MASK
285+
* and ena_admin_customer_metrics_id
286+
*/
287+
u64 supported_metrics;
288+
dma_addr_t buffer_dma_addr;
289+
void *buffer_virt_addr;
290+
u32 buffer_len;
291+
};
292+
281293
struct ena_host_attribute {
282294
/* Debug area */
283295
u8 *debug_area_virt_addr;
@@ -327,6 +339,8 @@ struct ena_com_dev {
327339
struct ena_intr_moder_entry *intr_moder_tbl;
328340

329341
struct ena_com_llq_info llq_info;
342+
343+
struct ena_customer_metrics customer_metrics;
330344
};
331345

332346
struct ena_com_dev_get_features_ctx {
@@ -604,6 +618,15 @@ int ena_com_get_eni_stats(struct ena_com_dev *ena_dev,
604618
int ena_com_get_ena_srd_info(struct ena_com_dev *ena_dev,
605619
struct ena_admin_ena_srd_info *info);
606620

621+
/* ena_com_get_customer_metrics - Get customer metrics for network interface
622+
* @ena_dev: ENA communication layer struct
623+
* @buffer: buffer for returned customer metrics
624+
* @len: size of the buffer
625+
*
626+
* @return: 0 on Success and negative value otherwise.
627+
*/
628+
int ena_com_get_customer_metrics(struct ena_com_dev *ena_dev, char *buffer, u32 len);
629+
607630
/* ena_com_set_dev_mtu - Configure the device mtu.
608631
* @ena_dev: ENA communication layer struct
609632
* @mtu: mtu value
@@ -814,6 +837,13 @@ int ena_com_allocate_host_info(struct ena_com_dev *ena_dev);
814837
int ena_com_allocate_debug_area(struct ena_com_dev *ena_dev,
815838
u32 debug_area_size);
816839

840+
/* ena_com_allocate_customer_metrics_buffer - Allocate customer metrics resources.
841+
* @ena_dev: ENA communication layer struct
842+
*
843+
* @return: 0 on Success and negative value otherwise.
844+
*/
845+
int ena_com_allocate_customer_metrics_buffer(struct ena_com_dev *ena_dev);
846+
817847
/* ena_com_delete_debug_area - Free the debug area resources.
818848
* @ena_dev: ENA communication layer struct
819849
*
@@ -828,6 +858,13 @@ void ena_com_delete_debug_area(struct ena_com_dev *ena_dev);
828858
*/
829859
void ena_com_delete_host_info(struct ena_com_dev *ena_dev);
830860

861+
/* ena_com_delete_customer_metrics_buffer - Free the customer metrics resources.
862+
* @ena_dev: ENA communication layer struct
863+
*
864+
* Free the allocated customer metrics area.
865+
*/
866+
void ena_com_delete_customer_metrics_buffer(struct ena_com_dev *ena_dev);
867+
831868
/* ena_com_set_host_attributes - Update the device with the host
832869
* attributes (debug area and host info) base address.
833870
* @ena_dev: ENA communication layer struct
@@ -984,6 +1021,28 @@ static inline bool ena_com_get_cap(struct ena_com_dev *ena_dev,
9841021
return !!(ena_dev->capabilities & BIT(cap_id));
9851022
}
9861023

1024+
/* ena_com_get_customer_metric_support - query whether device supports a given customer metric.
1025+
* @ena_dev: ENA communication layer struct
1026+
* @metric_id: enum value representing the customer metric
1027+
*
1028+
* @return - true if customer metric is supported or false otherwise
1029+
*/
1030+
static inline bool ena_com_get_customer_metric_support(struct ena_com_dev *ena_dev,
1031+
enum ena_admin_customer_metrics_id metric_id)
1032+
{
1033+
return !!(ena_dev->customer_metrics.supported_metrics & BIT(metric_id));
1034+
}
1035+
1036+
/* ena_com_get_customer_metric_count - return the number of supported customer metrics.
1037+
* @ena_dev: ENA communication layer struct
1038+
*
1039+
* @return - the number of supported customer metrics
1040+
*/
1041+
static inline int ena_com_get_customer_metric_count(struct ena_com_dev *ena_dev)
1042+
{
1043+
return hweight64(ena_dev->customer_metrics.supported_metrics);
1044+
}
1045+
9871046
/* ena_com_update_intr_reg - Prepare interrupt register
9881047
* @intr_reg: interrupt register to update.
9891048
* @rx_delay_interval: Rx interval in usecs

0 commit comments

Comments
 (0)