git: a6205766b300 - main - ena: Fix RSS not working after driver reload

From: Arthur Kiyanovski <akiyano_at_FreeBSD.org>
Date: Thu, 29 Oct 2026 03:29:38 UTC
The branch main has been updated by akiyano:

URL: https://cgit.FreeBSD.org/src/commit/?id=a6205766b300e83d3aa2ddc740707987f3c3c97e

commit a6205766b300e83d3aa2ddc740707987f3c3c97e
Author:     Gilad Ben Yakov <giladben@amazon.com>
AuthorDate: 2026-05-19 10:18:37 +0000
Commit:     Arthur Kiyanovski <akiyano@FreeBSD.org>
CommitDate: 2026-10-29 03:25:50 +0000

    ena: Fix RSS not working after driver reload
    
    When reloading the driver (kldunload/kldload),
    ena_rss_init_default_deferred() is called before ena_attach()
    completes. At this point, devclass_get_softc() returns NULL for all
    devices because the adapter structs have not been populated yet. As a
    result, ena_rss_init_default() is never called and ENA_FLAG_RSS_ACTIVE
    is never set. Later, in ena_up_complete(), the code checks the flag,
    finds it unset, and skips ena_rss_configure() entirely. RSS is never
    initialized, and all traffic is directed to queue 0.
    
    Remove the ENA_FLAG_RSS_ACTIVE gate in ena_up_complete() and always call
    ena_rss_configure(), which initialises the table when tbl_log_size is
    zero. The deferred SYSINIT is now redundant, so remove it.
    
    Reviewed by: cperciva
    Fixes: 9b8d05b8ac78 ("Add support for Amazon Elastic Network Adapter (ENA) NIC")
    MFC after: 3 days
    Sponsored by: Amazon, Inc.
---
 sys/dev/ena/ena.c        | 13 ++++++-------
 sys/dev/ena/ena_rss.c    | 33 ---------------------------------
 sys/dev/ena/ena_sysctl.c |  2 +-
 3 files changed, 7 insertions(+), 41 deletions(-)

diff --git a/sys/dev/ena/ena.c b/sys/dev/ena/ena.c
index b16e8ff324be..74594fdb1496 100644
--- a/sys/dev/ena/ena.c
+++ b/sys/dev/ena/ena.c
@@ -2133,14 +2133,13 @@ ena_up_complete(struct ena_adapter *adapter)
 {
 	int rc;
 
-	if (likely(ENA_FLAG_ISSET(ENA_FLAG_RSS_ACTIVE, adapter))) {
-		rc = ena_rss_configure(adapter);
-		if (rc != 0) {
-			ena_log(adapter->pdev, ERR,
-			    "Failed to configure RSS\n");
-			return (rc);
-		}
+	rc = ena_rss_configure(adapter);
+	if (rc != 0) {
+		ena_log(adapter->pdev, ERR,
+		    "Failed to configure RSS\n");
+		return (rc);
 	}
+	ENA_FLAG_SET_ATOMIC(ENA_FLAG_RSS_ACTIVE, adapter);
 
 	rc = ena_change_mtu(adapter->ifp, if_getmtu(adapter->ifp));
 	if (unlikely(rc != 0))
diff --git a/sys/dev/ena/ena_rss.c b/sys/dev/ena/ena_rss.c
index 4680e476bb19..746db69970ca 100644
--- a/sys/dev/ena/ena_rss.c
+++ b/sys/dev/ena/ena_rss.c
@@ -198,39 +198,6 @@ ena_rss_configure(struct ena_adapter *adapter)
 	return (0);
 }
 
-static void
-ena_rss_init_default_deferred(void *arg)
-{
-	struct ena_adapter *adapter;
-	devclass_t dc;
-	int max;
-	int rc;
-
-	dc = devclass_find("ena");
-	if (unlikely(dc == NULL)) {
-		ena_log_raw(ERR, "SYSINIT: %s: No devclass ena\n", __func__);
-		return;
-	}
-
-	max = devclass_get_maxunit(dc);
-	while (max-- >= 0) {
-		adapter = devclass_get_softc(dc, max);
-		if (adapter != NULL) {
-			rc = ena_rss_init_default(adapter);
-			ENA_FLAG_SET_ATOMIC(ENA_FLAG_RSS_ACTIVE, adapter);
-			if (unlikely(rc != 0)) {
-				ena_log(adapter->pdev, WARN,
-				    "WARNING: RSS was not properly initialized,"
-				    " it will affect bandwidth\n");
-				ENA_FLAG_CLEAR_ATOMIC(ENA_FLAG_RSS_ACTIVE,
-				    adapter);
-			}
-		}
-	}
-}
-SYSINIT(ena_rss_init, SI_SUB_KICK_SCHEDULER, SI_ORDER_SECOND,
-    ena_rss_init_default_deferred, NULL);
-
 int
 ena_rss_indir_get(struct ena_adapter *adapter, uint32_t *table)
 {
diff --git a/sys/dev/ena/ena_sysctl.c b/sys/dev/ena/ena_sysctl.c
index d244b015df41..62fded932025 100644
--- a/sys/dev/ena/ena_sysctl.c
+++ b/sys/dev/ena/ena_sysctl.c
@@ -1245,7 +1245,7 @@ ena_sysctl_rss_indir_table_size(SYSCTL_HANDLER_ARGS)
 	int actual_size;
 
 	actual_size = ena_get_rss_indirection_table_size(adapter);
-	if (actual_size == 0)
+	if (!ENA_FLAG_ISSET(ENA_FLAG_RSS_ACTIVE, adapter) || actual_size == 0)
 		return (EOPNOTSUPP);
 
 	return sysctl_handle_int(oidp, &actual_size, 0, req);