git: b272b2a94d98 - main - ice: Use sleepable locks in shared code

From: Kevin Bowling <kbowling_at_FreeBSD.org>
Date: Thu, 17 Sep 2026 00:02:39 UTC
The branch main has been updated by kbowling:

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

commit b272b2a94d983900c94168c5f41256869b0371b1
Author:     Kevin Bowling <kbowling@FreeBSD.org>
AuthorDate: 2026-09-03 11:31:42 +0000
Commit:     Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-09-17 00:01:22 +0000

    ice: Use sleepable locks in shared code
    
    The Intel shared code can wait for firmware resources while holding its
    OS abstraction locks.  FreeBSD mapped these locks to mutexes, which
    cannot be held across a voluntary sleep.  Concurrent PF rebuilds
    therefore trigger WITNESS when RSS profile updates contend for the
    firmware change lock.
    
    Map the shared-code lock abstraction to exclusive sx locks.  This also
    covers tunnel and flow-profile operations which can reach the same
    firmware wait while serialized.
    
    Validated with WITNESS on a dual port Intel E835.  Sixteen CORE resets
    rebuilt both PFs without lock warnings, reset failures, or watchdogs.
    Ten interface down/up cycles and twenty promiscuous-filter cycles also
    completed cleanly.
    
    Reviewed by:    erj
    MFC after:      2 weeks
    Sponsored by:   BBOX.io
    Differential Revision:  https://reviews.freebsd.org/D59339
---
 sys/dev/ice/ice_osdep.h | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/sys/dev/ice/ice_osdep.h b/sys/dev/ice/ice_osdep.h
index ea355ddb31f4..a428defb14bd 100644
--- a/sys/dev/ice/ice_osdep.h
+++ b/sys/dev/ice/ice_osdep.h
@@ -47,6 +47,7 @@
 #include <sys/systm.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
+#include <sys/sx.h>
 #include <sys/bus.h>
 #include <machine/bus.h>
 #include <sys/bus_dma.h>
@@ -408,7 +409,7 @@ void ice_free_dma_mem(struct ice_hw __unused *hw, struct ice_dma_mem *mem);
  * Contains a simple lock implementation used to lock various resources.
  */
 struct ice_lock {
-	struct mtx mutex;
+	struct sx sx;
 	char name[ICE_STR_BUF_LEN];
 };
 
@@ -418,8 +419,9 @@ extern u16 ice_lock_count;
  * ice_init_lock - Initialize a lock for use
  * @lock: the lock memory to initialize
  *
- * OS compatibility layer to provide a simple locking mechanism. We use
- * a mutex for this purpose.
+ * OS compatibility layer to provide a simple locking mechanism.  Shared-code
+ * operations can wait for firmware while holding these locks, so use a
+ * sleepable exclusive lock.
  */
 static inline void
 ice_init_lock(struct ice_lock *lock)
@@ -431,45 +433,45 @@ ice_init_lock(struct ice_lock *lock)
 	 */
 	memset(lock->name, 0, sizeof(lock->name));
 	snprintf(lock->name, ICE_STR_BUF_LEN, "ice_lock_%u", ice_lock_count++);
-	mtx_init(&lock->mutex, lock->name, NULL, MTX_DEF);
+	sx_init(&lock->sx, lock->name);
 }
 
 /**
  * ice_acquire_lock - Acquire the lock
  * @lock: the lock to acquire
  *
- * Acquires the mutex specified by the lock pointer.
+ * Acquires the exclusive lock specified by the lock pointer.
  */
 static inline void
 ice_acquire_lock(struct ice_lock *lock)
 {
-	mtx_lock(&lock->mutex);
+	sx_xlock(&lock->sx);
 }
 
 /**
  * ice_release_lock - Release the lock
  * @lock: the lock to release
  *
- * Releases the mutex specified by the lock pointer.
+ * Releases the exclusive lock specified by the lock pointer.
  */
 static inline void
 ice_release_lock(struct ice_lock *lock)
 {
-	mtx_unlock(&lock->mutex);
+	sx_xunlock(&lock->sx);
 }
 
 /**
  * ice_destroy_lock - Destroy the lock to de-allocate it
  * @lock: the lock to destroy
  *
- * Destroys a previously initialized lock. We only do this if the mutex was
+ * Destroys a previously initialized lock. We only do this if the lock was
  * previously initialized.
  */
 static inline void
 ice_destroy_lock(struct ice_lock *lock)
 {
-	if (mtx_initialized(&lock->mutex))
-		mtx_destroy(&lock->mutex);
+	if (lock_initialized(&lock->sx.lock_object))
+		sx_destroy(&lock->sx);
 	memset(lock->name, 0, sizeof(lock->name));
 }