git: 4cb527be7a25 - main - Correctly track index of first free irq map entry

From: Colin Percival <cperciva_at_FreeBSD.org>
Date: Sat, 29 Mar 2025 20:18:06 UTC
The branch main has been updated by cperciva:

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

commit 4cb527be7a251d89fa5955532300e08eec136051
Author:     Colin Percival <cperciva@FreeBSD.org>
AuthorDate: 2025-03-27 23:17:10 +0000
Commit:     Colin Percival <cperciva@FreeBSD.org>
CommitDate: 2025-03-29 20:17:29 +0000

    Correctly track index of first free irq map entry
    
    Any time an IRQ map entry was removed, irq_map_first_free_idx was being
    set to the index of the removed entry; this caused problems when
    entries were removed in random order since irq_map_first_free_idx was
    set to a larger value than the index of the first free map entry, and
    in 9beb195fd9fd ("Continue searching for an irq map from the start")
    the IRQ map allocation code was adjusted to use irq_map_first_free_idx
    as a starting point but ultimately scan the entire map if necessary,
    including values less than irq_map_first_free_idx.
    
    Remove that workaround and instead make irq_map_first_free_idx do what
    the name suggests -- tracking the index of the first free map entry --
    by only setting to the index of a newly-freed entry if that index is
    lower than the existing irq_map_first_free_idx value.
    
    Reviewed by:    imp, mhorne
    Sponsored by:   Amazon
    Differential Revision:  https://reviews.freebsd.org/D49543
---
 sys/kern/subr_intr.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/sys/kern/subr_intr.c b/sys/kern/subr_intr.c
index b7cb088f58c7..dec40aa04e4a 100644
--- a/sys/kern/subr_intr.c
+++ b/sys/kern/subr_intr.c
@@ -1733,14 +1733,6 @@ intr_map_irq(device_t dev, intptr_t xref, struct intr_map_data *data)
 			return (i);
 		}
 	}
-	for (i = 0; i < irq_map_first_free_idx; i++) {
-		if (irq_map[i] == NULL) {
-			irq_map[i] = entry;
-			irq_map_first_free_idx = i + 1;
-			mtx_unlock(&irq_map_lock);
-			return (i);
-		}
-	}
 	mtx_unlock(&irq_map_lock);
 
 	/* XXX Expand irq_map table */
@@ -1760,7 +1752,8 @@ intr_unmap_irq(u_int res_id)
 		panic("Attempt to unmap invalid resource id: %u\n", res_id);
 	entry = irq_map[res_id];
 	irq_map[res_id] = NULL;
-	irq_map_first_free_idx = res_id;
+	if (res_id < irq_map_first_free_idx)
+		irq_map_first_free_idx = res_id;
 	mtx_unlock(&irq_map_lock);
 	intr_free_intr_map_data(entry->map_data);
 	free(entry, M_INTRNG);