diff options
| -rw-r--r-- | sys/dev/ena/ena.c | 58 | ||||
| -rw-r--r-- | sys/dev/ena/ena.h | 4 |
2 files changed, 46 insertions, 16 deletions
diff --git a/sys/dev/ena/ena.c b/sys/dev/ena/ena.c index 3528f365cc1c..3ef1f41f4604 100644 --- a/sys/dev/ena/ena.c +++ b/sys/dev/ena/ena.c @@ -141,6 +141,7 @@ static void ena_free_irqs(struct ena_adapter*); static void ena_disable_msix(struct ena_adapter *); static void ena_unmask_all_io_irqs(struct ena_adapter *); static int ena_rss_configure(struct ena_adapter *); +static void ena_update_hw_stats(void *, int); static int ena_up_complete(struct ena_adapter *); static int ena_up(struct ena_adapter *); static void ena_down(struct ena_adapter *); @@ -2058,6 +2059,25 @@ static int ena_rss_configure(struct ena_adapter *adapter) return 0; } +static void +ena_update_hw_stats(void *arg, int pending) +{ + struct ena_adapter *adapter = arg; + int rc; + + for (;;) { + if (!adapter->up) + return; + + rc = ena_update_stats_counters(adapter); + if (rc) + ena_trace(ENA_WARNING, + "Error updating stats counters, rc = %d", rc); + + pause("ena update hw stats", hz); + } +} + static int ena_up_complete(struct ena_adapter *adapter) { @@ -2141,6 +2161,8 @@ ena_up(struct ena_adapter *adapter) callout_reset_sbt(&adapter->timer_service, SBT_1S, SBT_1S, ena_timer_service, (void *)adapter, 0); + taskqueue_enqueue(adapter->stats_tq, &adapter->stats_task); + adapter->up = true; } @@ -2193,24 +2215,8 @@ ena_get_counter(if_t ifp, ift_counter cnt) { struct ena_adapter *adapter; struct ena_hw_stats *stats; - int rc; adapter = if_getsoftc(ifp); - - /* - * Update only when asking for first counter and interface is up. - * Usually asks for all statistics in sequence. - */ - if (adapter->up) { - if (cnt == 0) { - rc = ena_update_stats_counters(adapter); - if (rc) { - ena_trace(ENA_WARNING, - "Error updating stats counters, rc = %d", - rc); - } - } - } stats = &adapter->hw_stats; switch (cnt) { @@ -2501,6 +2507,10 @@ ena_down(struct ena_adapter *adapter) if_setdrvflagbits(adapter->ifp, IFF_DRV_OACTIVE, IFF_DRV_RUNNING); + /* Drain task responsible for updating hw stats */ + while (taskqueue_cancel(adapter->stats_tq, &adapter->stats_task, NULL)) + taskqueue_drain(adapter->stats_tq, &adapter->stats_task); + ena_free_io_irq(adapter); ena_destroy_all_io_queues(adapter); @@ -3616,6 +3626,18 @@ ena_attach(device_t pdev) taskqueue_start_threads(&adapter->reset_tq, 1, PI_NET, "%s rstq", device_get_nameunit(adapter->pdev)); + /* Initialize task queue responsible for updating hw stats */ + TASK_INIT(&adapter->stats_task, 0, ena_update_hw_stats, adapter); + adapter->stats_tq = taskqueue_create_fast("ena_stats_update", + M_WAITOK | M_ZERO, taskqueue_thread_enqueue, &adapter->stats_tq); + if (adapter->stats_tq == NULL) { + device_printf(adapter->pdev, + "Unable to create taskqueue for updating hw stats\n"); + goto err_stats_tq; + } + taskqueue_start_threads(&adapter->stats_tq, 1, PI_REALTIME, + "%s stats tq", device_get_nameunit(adapter->pdev)); + /* Initialize statistics */ ena_alloc_counters((counter_u64_t *)&adapter->dev_stats, sizeof(struct ena_stats_dev)); @@ -3628,6 +3650,8 @@ ena_attach(device_t pdev) adapter->running = true; return (0); +err_stats_tq: + taskqueue_free(adapter->reset_tq); err_reset_tq: ena_free_mgmnt_irq(adapter); ena_disable_msix(adapter); @@ -3683,6 +3707,8 @@ ena_detach(device_t pdev) ena_down(adapter); sx_unlock(&adapter->ioctl_sx); + taskqueue_free(adapter->stats_tq); + if (adapter->ifp != NULL) { ether_ifdetach(adapter->ifp); if_free(adapter->ifp); diff --git a/sys/dev/ena/ena.h b/sys/dev/ena/ena.h index abb3871c701d..a20498546db8 100644 --- a/sys/dev/ena/ena.h +++ b/sys/dev/ena/ena.h @@ -403,6 +403,10 @@ struct ena_adapter { uint32_t missing_tx_max_queues; uint32_t missing_tx_threshold; + /* Task updating hw stats */ + struct task stats_task; + struct taskqueue *stats_tq; + /* Statistics */ struct ena_stats_dev dev_stats; struct ena_hw_stats hw_stats; |
