mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-07 00:50:50 +00:00
ena: Support customer metric with sysctl
This commit adds sysctl support for customer metrics. Different customer metrics can be found in the following sysctl node: sysctl dev.ena.<device index>.customer_metrics Approved by: cperciva (mentor) MFC after: 2 weeks Sponsored by: Amazon, Inc.
This commit is contained in:
parent
5b925280d9
commit
f97993ad7b
|
@ -166,6 +166,7 @@ static int ena_enable_msix_and_set_admin_interrupts(struct ena_adapter *);
|
|||
static void ena_update_on_link_change(void *, struct ena_admin_aenq_entry *);
|
||||
static void unimplemented_aenq_handler(void *, struct ena_admin_aenq_entry *);
|
||||
static int ena_copy_eni_metrics(struct ena_adapter *);
|
||||
static int ena_copy_customer_metrics(struct ena_adapter *);
|
||||
static void ena_timer_service(void *);
|
||||
|
||||
static char ena_version[] = ENA_DEVICE_NAME ENA_DRV_MODULE_NAME
|
||||
|
@ -3305,6 +3306,25 @@ ena_copy_eni_metrics(struct ena_adapter *adapter)
|
|||
return (rc);
|
||||
}
|
||||
|
||||
static int
|
||||
ena_copy_customer_metrics(struct ena_adapter *adapter)
|
||||
{
|
||||
struct ena_com_dev *dev;
|
||||
u32 supported_metrics_count;
|
||||
int rc, len;
|
||||
|
||||
dev = adapter->ena_dev;
|
||||
|
||||
supported_metrics_count = ena_com_get_customer_metric_count(dev);
|
||||
len = supported_metrics_count * sizeof(u64);
|
||||
|
||||
/* Fill the data buffer */
|
||||
rc = ena_com_get_customer_metrics(adapter->ena_dev,
|
||||
(char *)(adapter->customer_metrics_array), len);
|
||||
|
||||
return (rc);
|
||||
}
|
||||
|
||||
static void
|
||||
ena_timer_service(void *data)
|
||||
{
|
||||
|
@ -3542,7 +3562,12 @@ ena_metrics_task(void *arg, int pending)
|
|||
struct ena_adapter *adapter = (struct ena_adapter *)arg;
|
||||
|
||||
ENA_LOCK_LOCK();
|
||||
(void)ena_copy_eni_metrics(adapter);
|
||||
|
||||
if (ena_com_get_cap(adapter->ena_dev, ENA_ADMIN_CUSTOMER_METRICS))
|
||||
(void)ena_copy_customer_metrics(adapter);
|
||||
else if (ena_com_get_cap(adapter->ena_dev, ENA_ADMIN_ENI_STATS))
|
||||
(void)ena_copy_eni_metrics(adapter);
|
||||
|
||||
ENA_LOCK_UNLOCK();
|
||||
}
|
||||
|
||||
|
@ -3756,6 +3781,18 @@ ena_attach(device_t pdev)
|
|||
/* initialize rings basic information */
|
||||
ena_init_io_rings(adapter);
|
||||
|
||||
rc = ena_com_allocate_customer_metrics_buffer(ena_dev);
|
||||
if (rc) {
|
||||
ena_log(pdev, ERR, "Failed to allocate customer metrics buffer.\n");
|
||||
goto err_msix_free;
|
||||
}
|
||||
|
||||
rc = ena_sysctl_allocate_customer_metrics_buffer(adapter);
|
||||
if (unlikely(rc)){
|
||||
ena_log(pdev, ERR, "Failed to allocate sysctl customer metrics buffer.\n");
|
||||
goto err_metrics_buffer_destroy;
|
||||
}
|
||||
|
||||
/* Initialize statistics */
|
||||
ena_alloc_counters((counter_u64_t *)&adapter->dev_stats,
|
||||
sizeof(struct ena_stats_dev));
|
||||
|
@ -3767,7 +3804,7 @@ ena_attach(device_t pdev)
|
|||
rc = ena_setup_ifnet(pdev, adapter, &get_feat_ctx);
|
||||
if (unlikely(rc != 0)) {
|
||||
ena_log(pdev, ERR, "Error with network interface setup\n");
|
||||
goto err_msix_free;
|
||||
goto err_customer_metrics_alloc;
|
||||
}
|
||||
|
||||
/* Initialize reset task queue */
|
||||
|
@ -3805,6 +3842,10 @@ ena_attach(device_t pdev)
|
|||
err_detach:
|
||||
ether_ifdetach(adapter->ifp);
|
||||
#endif /* DEV_NETMAP */
|
||||
err_customer_metrics_alloc:
|
||||
free(adapter->customer_metrics_array, M_DEVBUF);
|
||||
err_metrics_buffer_destroy:
|
||||
ena_com_delete_customer_metrics_buffer(ena_dev);
|
||||
err_msix_free:
|
||||
ena_free_stats(adapter);
|
||||
ena_com_dev_reset(adapter->ena_dev, ENA_REGS_RESET_INIT_ERR);
|
||||
|
@ -3903,6 +3944,10 @@ ena_detach(device_t pdev)
|
|||
|
||||
ena_com_delete_host_info(ena_dev);
|
||||
|
||||
free(adapter->customer_metrics_array, M_DEVBUF);
|
||||
|
||||
ena_com_delete_customer_metrics_buffer(ena_dev);
|
||||
|
||||
if_free(adapter->ifp);
|
||||
|
||||
free(ena_dev->bus, M_DEVBUF);
|
||||
|
|
|
@ -487,6 +487,7 @@ struct ena_adapter {
|
|||
struct ena_stats_dev dev_stats;
|
||||
struct ena_hw_stats hw_stats;
|
||||
struct ena_admin_eni_stats eni_metrics;
|
||||
uint64_t *customer_metrics_array;
|
||||
|
||||
enum ena_regs_reset_reason_types reset_reason;
|
||||
};
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
static void ena_sysctl_add_wd(struct ena_adapter *);
|
||||
static void ena_sysctl_add_stats(struct ena_adapter *);
|
||||
static void ena_sysctl_add_eni_metrics(struct ena_adapter *);
|
||||
static void ena_sysctl_add_customer_metrics(struct ena_adapter *);
|
||||
static void ena_sysctl_add_tuneables(struct ena_adapter *);
|
||||
static void ena_sysctl_add_irq_affinity(struct ena_adapter *);
|
||||
/* Kernel option RSS prevents manipulation of key hash and indirection table. */
|
||||
|
@ -58,6 +59,39 @@ static int ena_sysctl_rss_indir_table(SYSCTL_HANDLER_ARGS);
|
|||
#define ENA_METRICS_MAX_SAMPLE_INTERVAL 3600
|
||||
#define ENA_HASH_KEY_MSG_SIZE (ENA_HASH_KEY_SIZE * 2 + 1)
|
||||
|
||||
#define SYSCTL_GSTRING_LEN 64
|
||||
|
||||
#define ENA_METRIC_ENI_ENTRY(stat, desc) { \
|
||||
.name = #stat, \
|
||||
.description = #desc, \
|
||||
}
|
||||
|
||||
struct ena_hw_metrics {
|
||||
char name[SYSCTL_GSTRING_LEN];
|
||||
char description[SYSCTL_GSTRING_LEN];
|
||||
};
|
||||
|
||||
static const struct ena_hw_metrics ena_hw_stats_strings[] = {
|
||||
ENA_METRIC_ENI_ENTRY(
|
||||
bw_in_allowance_exceeded, Inbound BW allowance exceeded),
|
||||
ENA_METRIC_ENI_ENTRY(
|
||||
bw_out_allowance_exceeded, Outbound BW allowance exceeded),
|
||||
ENA_METRIC_ENI_ENTRY(
|
||||
pps_allowance_exceeded, PPS allowance exceeded),
|
||||
ENA_METRIC_ENI_ENTRY(
|
||||
conntrack_allowance_exceeded, Connection tracking allowance exceeded),
|
||||
ENA_METRIC_ENI_ENTRY(
|
||||
linklocal_allowance_exceeded, Linklocal packet rate allowance),
|
||||
ENA_METRIC_ENI_ENTRY(
|
||||
conntrack_allowance_available, Number of available conntracks),
|
||||
};
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
||||
#endif
|
||||
|
||||
#define ENA_CUSTOMER_METRICS_ARRAY_SIZE ARRAY_SIZE(ena_hw_stats_strings)
|
||||
|
||||
static SYSCTL_NODE(_hw, OID_AUTO, ena, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
|
||||
"ENA driver parameters");
|
||||
|
||||
|
@ -98,12 +132,29 @@ SYSCTL_BOOL(_hw_ena, OID_AUTO, force_large_llq_header, CTLFLAG_RDTUN,
|
|||
|
||||
int ena_rss_table_size = ENA_RX_RSS_TABLE_SIZE;
|
||||
|
||||
int ena_sysctl_allocate_customer_metrics_buffer(struct ena_adapter *adapter)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
adapter->customer_metrics_array = malloc((sizeof(u64) * ENA_CUSTOMER_METRICS_ARRAY_SIZE),
|
||||
M_DEVBUF, M_NOWAIT | M_ZERO);
|
||||
if (unlikely(adapter->customer_metrics_array == NULL))
|
||||
rc = ENOMEM;
|
||||
|
||||
return rc;
|
||||
}
|
||||
void
|
||||
ena_sysctl_add_nodes(struct ena_adapter *adapter)
|
||||
{
|
||||
struct ena_com_dev *dev = adapter->ena_dev;
|
||||
|
||||
if (ena_com_get_cap(dev, ENA_ADMIN_CUSTOMER_METRICS))
|
||||
ena_sysctl_add_customer_metrics(adapter);
|
||||
else if (ena_com_get_cap(dev, ENA_ADMIN_ENI_STATS))
|
||||
ena_sysctl_add_eni_metrics(adapter);
|
||||
|
||||
ena_sysctl_add_wd(adapter);
|
||||
ena_sysctl_add_stats(adapter);
|
||||
ena_sysctl_add_eni_metrics(adapter);
|
||||
ena_sysctl_add_tuneables(adapter);
|
||||
ena_sysctl_add_irq_affinity(adapter);
|
||||
#ifndef RSS
|
||||
|
@ -328,6 +379,40 @@ ena_sysctl_add_stats(struct ena_adapter *adapter)
|
|||
&admin_stats->no_completion, 0, "Commands not completed");
|
||||
}
|
||||
|
||||
static void
|
||||
ena_sysctl_add_customer_metrics(struct ena_adapter *adapter)
|
||||
{
|
||||
device_t dev;
|
||||
struct ena_com_dev *ena_dev;
|
||||
|
||||
struct sysctl_ctx_list *ctx;
|
||||
struct sysctl_oid *tree;
|
||||
struct sysctl_oid_list *child;
|
||||
|
||||
struct sysctl_oid *customer_metric;
|
||||
struct sysctl_oid_list *customer_list;
|
||||
|
||||
int i;
|
||||
|
||||
dev = adapter->pdev;
|
||||
ena_dev = adapter->ena_dev;
|
||||
|
||||
ctx = device_get_sysctl_ctx(dev);
|
||||
tree = device_get_sysctl_tree(dev);
|
||||
child = SYSCTL_CHILDREN(tree);
|
||||
customer_metric = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "customer_metrics",
|
||||
CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "ENA's customer metrics");
|
||||
customer_list = SYSCTL_CHILDREN(customer_metric);
|
||||
|
||||
for (i = 0; i < ENA_CUSTOMER_METRICS_ARRAY_SIZE; i++) {
|
||||
if (ena_com_get_customer_metric_support(ena_dev, i)) {
|
||||
SYSCTL_ADD_U64(ctx, customer_list, OID_AUTO, ena_hw_stats_strings[i].name,
|
||||
CTLFLAG_RD, &adapter->customer_metrics_array[i], 0,
|
||||
ena_hw_stats_strings[i].description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ena_sysctl_add_eni_metrics(struct ena_adapter *adapter)
|
||||
{
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
void ena_sysctl_add_nodes(struct ena_adapter *adapter);
|
||||
void ena_sysctl_update_queue_node_nb(struct ena_adapter *adapter, int old,
|
||||
int new);
|
||||
int ena_sysctl_allocate_customer_metrics_buffer(struct ena_adapter *adapter);
|
||||
|
||||
extern int ena_enable_9k_mbufs;
|
||||
#define ena_mbuf_sz (ena_enable_9k_mbufs ? MJUM9BYTES : MJUMPAGESIZE)
|
||||
|
|
Loading…
Reference in a new issue