git: bcc00cabdbb9 - stable/13 - mps/mpr(4): Move xpt_register_async() out of lock.

From: Alexander Motin <mav_at_FreeBSD.org>
Date: Thu, 14 Oct 2021 10:50:51 UTC
The branch stable/13 has been updated by mav:

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

commit bcc00cabdbb9e8255e347f4824838d0303afdd54
Author:     Alexander Motin <mav@FreeBSD.org>
AuthorDate: 2021-09-14 21:37:02 +0000
Commit:     Alexander Motin <mav@FreeBSD.org>
CommitDate: 2021-10-14 10:50:12 +0000

    mps/mpr(4): Move xpt_register_async() out of lock.
    
    It fixes lock ordere reversal between SIM and device locks.  Also
    remove registration for AC_FOUND_DEVICE, unused for a while now.
    
    MFC after:      1 month
    
    (cherry picked from commit 02d8194012a9a0e367a92c7f89567b808bf0e9a8)
---
 sys/dev/mpr/mpr_sas.c | 21 +++++++++++----------
 sys/dev/mps/mps_sas.c | 18 ++++++++++--------
 2 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/sys/dev/mpr/mpr_sas.c b/sys/dev/mpr/mpr_sas.c
index 043d24e82f44..09fa6ac4bc92 100644
--- a/sys/dev/mpr/mpr_sas.c
+++ b/sys/dev/mpr/mpr_sas.c
@@ -821,6 +821,8 @@ mpr_attach_sas(struct mpr_softc *sc)
 
 	callout_init(&sassc->discovery_callout, 1 /*mpsafe*/);
 
+	mpr_unlock(sc);
+
 	/*
 	 * Register for async events so we can determine the EEDP
 	 * capabilities of devices.
@@ -835,7 +837,7 @@ mpr_attach_sas(struct mpr_softc *sc)
 	} else {
 		int event;
 
-		event = AC_ADVINFO_CHANGED | AC_FOUND_DEVICE;
+		event = AC_ADVINFO_CHANGED;
 		status = xpt_register_async(event, mprsas_async, sc,
 					    sassc->path);
 
@@ -855,8 +857,6 @@ mpr_attach_sas(struct mpr_softc *sc)
 		mpr_printf(sc, "EEDP capabilities disabled.\n");
 	}
 
-	mpr_unlock(sc);
-
 	mprsas_register_events(sc);
 out:
 	if (error)
@@ -890,12 +890,6 @@ mpr_detach_sas(struct mpr_softc *sc)
 	if (sassc->ev_tq != NULL)
 		taskqueue_free(sassc->ev_tq);
 
-	/* Make sure CAM doesn't wedge if we had to bail out early. */
-	mpr_lock(sc);
-
-	while (sassc->startup_refcount != 0)
-		mprsas_startup_decrement(sassc);
-
 	/* Deregister our async handler */
 	if (sassc->path != NULL) {
 		xpt_register_async(0, mprsas_async, sc, sassc->path);
@@ -903,6 +897,12 @@ mpr_detach_sas(struct mpr_softc *sc)
 		sassc->path = NULL;
 	}
 
+	/* Make sure CAM doesn't wedge if we had to bail out early. */
+	mpr_lock(sc);
+
+	while (sassc->startup_refcount != 0)
+		mprsas_startup_decrement(sassc);
+
 	if (sassc->flags & MPRSAS_IN_STARTUP)
 		xpt_release_simq(sassc->sim, 1);
 
@@ -3326,6 +3326,7 @@ mprsas_async(void *callback_arg, uint32_t code, struct cam_path *path,
 
 	sc = (struct mpr_softc *)callback_arg;
 
+	mpr_lock(sc);
 	switch (code) {
 	case AC_ADVINFO_CHANGED: {
 		struct mprsas_target *target;
@@ -3412,10 +3413,10 @@ mprsas_async(void *callback_arg, uint32_t code, struct cam_path *path,
 		}
 		break;
 	}
-	case AC_FOUND_DEVICE:
 	default:
 		break;
 	}
+	mpr_unlock(sc);
 }
 
 /*
diff --git a/sys/dev/mps/mps_sas.c b/sys/dev/mps/mps_sas.c
index 3124384b6cbb..136e3586ef20 100644
--- a/sys/dev/mps/mps_sas.c
+++ b/sys/dev/mps/mps_sas.c
@@ -779,6 +779,8 @@ mps_attach_sas(struct mps_softc *sc)
 
 	callout_init(&sassc->discovery_callout, 1 /*mpsafe*/);
 
+	mps_unlock(sc);
+
 	/*
 	 * Register for async events so we can determine the EEDP
 	 * capabilities of devices.
@@ -812,8 +814,6 @@ mps_attach_sas(struct mps_softc *sc)
 		mps_printf(sc, "EEDP capabilities disabled.\n");
 	}
 
-	mps_unlock(sc);
-
 	mpssas_register_events(sc);
 out:
 	if (error)
@@ -847,12 +847,6 @@ mps_detach_sas(struct mps_softc *sc)
 	if (sassc->ev_tq != NULL)
 		taskqueue_free(sassc->ev_tq);
 
-	/* Make sure CAM doesn't wedge if we had to bail out early. */
-	mps_lock(sc);
-
-	while (sassc->startup_refcount != 0)
-		mpssas_startup_decrement(sassc);
-
 	/* Deregister our async handler */
 	if (sassc->path != NULL) {
 		xpt_register_async(0, mpssas_async, sc, sassc->path);
@@ -860,6 +854,12 @@ mps_detach_sas(struct mps_softc *sc)
 		sassc->path = NULL;
 	}
 
+	/* Make sure CAM doesn't wedge if we had to bail out early. */
+	mps_lock(sc);
+
+	while (sassc->startup_refcount != 0)
+		mpssas_startup_decrement(sassc);
+
 	if (sassc->flags & MPSSAS_IN_STARTUP)
 		xpt_release_simq(sassc->sim, 1);
 
@@ -3150,6 +3150,7 @@ mpssas_async(void *callback_arg, uint32_t code, struct cam_path *path,
 
 	sc = (struct mps_softc *)callback_arg;
 
+	mps_lock(sc);
 	switch (code) {
 	case AC_ADVINFO_CHANGED: {
 		struct mpssas_target *target;
@@ -3240,6 +3241,7 @@ mpssas_async(void *callback_arg, uint32_t code, struct cam_path *path,
 	default:
 		break;
 	}
+	mps_unlock(sc);
 }
 
 /*