164 lines
5.3 KiB
Diff
164 lines
5.3 KiB
Diff
From: Arthur Kiyanovski <akiyano@amazon.com>
|
|
Date: Mon, 16 Sep 2019 14:31:27 +0300
|
|
Subject: [PATCH] net: ena: switch to dim algorithm for rx adaptive interrupt
|
|
moderation
|
|
Origin: https://git.kernel.org/linus/282faf61a053be43910fcc42d86ecf16c0d30123
|
|
Bug-Debian: https://bugs.debian.org/941291
|
|
|
|
Use the dim library for the rx adaptive interrupt moderation implementation
|
|
|
|
Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
---
|
|
drivers/net/ethernet/amazon/ena/ena_com.c | 4 +-
|
|
drivers/net/ethernet/amazon/ena/ena_netdev.c | 55 +++++++++++++-------
|
|
drivers/net/ethernet/amazon/ena/ena_netdev.h | 3 ++
|
|
3 files changed, 41 insertions(+), 21 deletions(-)
|
|
|
|
Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c
|
|
===================================================================
|
|
--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c
|
|
+++ linux/drivers/net/ethernet/amazon/ena/ena_com.c
|
|
@@ -2839,9 +2839,7 @@ int ena_com_init_interrupt_moderation(st
|
|
delay_resolution = get_resp.u.intr_moderation.intr_delay_resolution;
|
|
ena_com_update_intr_delay_resolution(ena_dev, delay_resolution);
|
|
|
|
- /* Disable adaptive moderation by default - can be enabled from
|
|
- * ethtool
|
|
- */
|
|
+ /* Disable adaptive moderation by default - can be enabled later */
|
|
ena_com_disable_adaptive_moderation(ena_dev);
|
|
|
|
return 0;
|
|
Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
|
|
===================================================================
|
|
--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
|
|
+++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
|
|
@@ -196,6 +196,7 @@ static void ena_init_io_rings(struct ena
|
|
rxr->smoothed_interval =
|
|
ena_com_get_nonadaptive_moderation_interval_rx(ena_dev);
|
|
rxr->empty_rx_queue = 0;
|
|
+ adapter->ena_napi[i].dim.mode = NET_DIM_CQ_PERIOD_MODE_START_FROM_EQE;
|
|
}
|
|
}
|
|
|
|
@@ -712,6 +713,7 @@ static void ena_destroy_all_rx_queues(st
|
|
|
|
for (i = 0; i < adapter->num_queues; i++) {
|
|
ena_qid = ENA_IO_RXQ_IDX(i);
|
|
+ cancel_work_sync(&adapter->ena_napi[i].dim.work);
|
|
ena_com_destroy_io_queue(adapter->ena_dev, ena_qid);
|
|
}
|
|
}
|
|
@@ -1156,23 +1158,35 @@ error:
|
|
return 0;
|
|
}
|
|
|
|
-void ena_adjust_intr_moderation(struct ena_ring *rx_ring,
|
|
- struct ena_ring *tx_ring)
|
|
+static void ena_dim_work(struct work_struct *w)
|
|
{
|
|
- /* We apply adaptive moderation on Rx path only.
|
|
- * Tx uses static interrupt moderation.
|
|
- */
|
|
- ena_com_calculate_interrupt_delay(rx_ring->ena_dev,
|
|
- rx_ring->per_napi_packets,
|
|
- rx_ring->per_napi_bytes,
|
|
- &rx_ring->smoothed_interval,
|
|
- &rx_ring->moder_tbl_idx);
|
|
-
|
|
- /* Reset per napi packets/bytes */
|
|
- tx_ring->per_napi_packets = 0;
|
|
- tx_ring->per_napi_bytes = 0;
|
|
+ struct net_dim *dim = container_of(w, struct net_dim, work);
|
|
+ struct net_dim_cq_moder cur_moder =
|
|
+ net_dim_get_rx_moderation(dim->mode, dim->profile_ix);
|
|
+ struct ena_napi *ena_napi = container_of(dim, struct ena_napi, dim);
|
|
+
|
|
+ ena_napi->rx_ring->smoothed_interval = cur_moder.usec;
|
|
+ dim->state = NET_DIM_START_MEASURE;
|
|
+}
|
|
+
|
|
+static void ena_adjust_adaptive_rx_intr_moderation(struct ena_napi *ena_napi)
|
|
+{
|
|
+ struct net_dim_sample dim_sample;
|
|
+ struct ena_ring *rx_ring = ena_napi->rx_ring;
|
|
+
|
|
+ if (!rx_ring->per_napi_packets)
|
|
+ return;
|
|
+
|
|
+ rx_ring->non_empty_napi_events++;
|
|
+
|
|
+ net_dim_sample(rx_ring->non_empty_napi_events,
|
|
+ rx_ring->rx_stats.cnt,
|
|
+ rx_ring->rx_stats.bytes,
|
|
+ &dim_sample);
|
|
+
|
|
+ net_dim(&ena_napi->dim, dim_sample);
|
|
+
|
|
rx_ring->per_napi_packets = 0;
|
|
- rx_ring->per_napi_bytes = 0;
|
|
}
|
|
|
|
static void ena_unmask_interrupt(struct ena_ring *tx_ring,
|
|
@@ -1261,9 +1275,11 @@ static int ena_io_poll(struct napi_struc
|
|
* from the interrupt context (vs from sk_busy_loop)
|
|
*/
|
|
if (napi_complete_done(napi, rx_work_done)) {
|
|
- /* Tx and Rx share the same interrupt vector */
|
|
+ /* We apply adaptive moderation on Rx path only.
|
|
+ * Tx uses static interrupt moderation.
|
|
+ */
|
|
if (ena_com_get_adaptive_moderation_enabled(rx_ring->ena_dev))
|
|
- ena_adjust_intr_moderation(rx_ring, tx_ring);
|
|
+ ena_adjust_adaptive_rx_intr_moderation(ena_napi);
|
|
|
|
ena_unmask_interrupt(tx_ring, rx_ring);
|
|
}
|
|
@@ -1741,13 +1757,16 @@ static int ena_create_all_io_rx_queues(s
|
|
rc = ena_create_io_rx_queue(adapter, i);
|
|
if (rc)
|
|
goto create_err;
|
|
+ INIT_WORK(&adapter->ena_napi[i].dim.work, ena_dim_work);
|
|
}
|
|
|
|
return 0;
|
|
|
|
create_err:
|
|
- while (i--)
|
|
+ while (i--) {
|
|
+ cancel_work_sync(&adapter->ena_napi[i].dim.work);
|
|
ena_com_destroy_io_queue(ena_dev, ENA_IO_RXQ_IDX(i));
|
|
+ }
|
|
|
|
return rc;
|
|
}
|
|
Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
|
|
===================================================================
|
|
--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h
|
|
+++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
|
|
@@ -34,6 +34,7 @@
|
|
#define ENA_H
|
|
|
|
#include <linux/bitops.h>
|
|
+#include <linux/net_dim.h>
|
|
#include <linux/etherdevice.h>
|
|
#include <linux/inetdevice.h>
|
|
#include <linux/interrupt.h>
|
|
@@ -153,6 +154,7 @@ struct ena_napi {
|
|
struct ena_ring *tx_ring;
|
|
struct ena_ring *rx_ring;
|
|
u32 qid;
|
|
+ struct net_dim dim;
|
|
};
|
|
|
|
struct ena_calc_queue_size_ctx {
|
|
@@ -280,6 +282,7 @@ struct ena_ring {
|
|
u32 per_napi_packets;
|
|
u32 per_napi_bytes;
|
|
enum ena_intr_moder_level moder_tbl_idx;
|
|
+ u16 non_empty_napi_events;
|
|
struct u64_stats_sync syncp;
|
|
union {
|
|
struct ena_stats_tx tx_stats;
|