Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 11 Nov 2019 17:36:52 +0000 (UTC)
From:      Warner Losh <imp@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r354622 - head/sys/cam/scsi
Message-ID:  <201911111736.xABHaq30099045@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: imp
Date: Mon Nov 11 17:36:52 2019
New Revision: 354622
URL: https://svnweb.freebsd.org/changeset/base/354622

Log:
  Update the softc state of the da driver before releasing the CCB.
  
  There are contexts where releasing the ccb triggers dastart() to be run
  inline. When da was written, there was always a deferral, so it didn't matter
  much. Now, with direct dispatch, we can call dastart from the dadone*
  routines. If the probe state isn't updated, then dastart will redo things with
  stale information. This normally isn't a problem, because we run the probe state
  machine once at boot... Except that we also run it for each open of the device,
  which means we can have multiple threads racing each other to try to kick off
  the probe. However, if we update the state before we release the CCB, we can
  avoid the race. While it's needed only for the probewp and proberc* states, do
  it everywhere because it won't hurt the other places.
  
  The race here happens because we reprobe dozens of times on boot when drives
  have lots of partitions.  We should consider caching this info for 1-2 seconds
  to avoid this thundering hurd.
  
  Reviewed by: scottl, ken
  Differential Revision: https://reviews.freebsd.org/D22295

Modified:
  head/sys/cam/scsi/scsi_da.c

Modified: head/sys/cam/scsi/scsi_da.c
==============================================================================
--- head/sys/cam/scsi/scsi_da.c	Mon Nov 11 17:36:47 2019	(r354621)
+++ head/sys/cam/scsi/scsi_da.c	Mon Nov 11 17:36:52 2019	(r354622)
@@ -4645,11 +4645,11 @@ dadone_probewp(struct cam_periph *periph, union ccb *d
 	}
 
 	free(csio->data_ptr, M_SCSIDA);
-	xpt_release_ccb(done_ccb);
 	if ((softc->flags & DA_FLAG_CAN_RC16) != 0)
 		softc->state = DA_STATE_PROBE_RC16;
 	else
 		softc->state = DA_STATE_PROBE_RC;
+	xpt_release_ccb(done_ccb);
 	xpt_schedule(periph, priority);
 	return;
 }
@@ -4709,8 +4709,8 @@ dadone_proberc(struct cam_periph *periph, union ccb *d
 			 */
 			if (maxsector == 0xffffffff) {
 				free(rdcap, M_SCSIDA);
-				xpt_release_ccb(done_ccb);
 				softc->state = DA_STATE_PROBE_RC16;
+				xpt_release_ccb(done_ccb);
 				xpt_schedule(periph, priority);
 				return;
 			}
@@ -4816,8 +4816,8 @@ dadone_proberc(struct cam_periph *periph, union ccb *d
 				cam_periph_assert(periph, MA_OWNED);
 				softc->flags &= ~DA_FLAG_CAN_RC16;
 				free(rdcap, M_SCSIDA);
-				xpt_release_ccb(done_ccb);
 				softc->state = DA_STATE_PROBE_RC;
+				xpt_release_ccb(done_ccb);
 				xpt_schedule(periph, priority);
 				return;
 			}
@@ -4924,14 +4924,14 @@ dadone_proberc(struct cam_periph *periph, union ccb *d
 		dadeleteflag(softc, DA_DELETE_WS10, 1);
 		dadeleteflag(softc, DA_DELETE_UNMAP, 1);
 
-		xpt_release_ccb(done_ccb);
 		softc->state = DA_STATE_PROBE_LBP;
+		xpt_release_ccb(done_ccb);
 		xpt_schedule(periph, priority);
 		return;
 	}
 
-	xpt_release_ccb(done_ccb);
 	softc->state = DA_STATE_PROBE_BDC;
+	xpt_release_ccb(done_ccb);
 	xpt_schedule(periph, priority);
 	return;
 }
@@ -4988,8 +4988,8 @@ dadone_probelbp(struct cam_periph *periph, union ccb *
 	}
 
 	free(lbp, M_SCSIDA);
-	xpt_release_ccb(done_ccb);
 	softc->state = DA_STATE_PROBE_BLK_LIMITS;
+	xpt_release_ccb(done_ccb);
 	xpt_schedule(periph, priority);
 	return;
 }
@@ -5082,8 +5082,8 @@ dadone_probeblklimits(struct cam_periph *periph, union
 	}
 
 	free(block_limits, M_SCSIDA);
-	xpt_release_ccb(done_ccb);
 	softc->state = DA_STATE_PROBE_BDC;
+	xpt_release_ccb(done_ccb);
 	xpt_schedule(periph, priority);
 	return;
 }
@@ -5183,8 +5183,8 @@ dadone_probebdc(struct cam_periph *periph, union ccb *
 	}
 
 	free(bdc, M_SCSIDA);
-	xpt_release_ccb(done_ccb);
 	softc->state = DA_STATE_PROBE_ATA;
+	xpt_release_ccb(done_ccb);
 	xpt_schedule(periph, priority);
 	return;
 }
@@ -5323,8 +5323,8 @@ dadone_probeata(struct cam_periph *periph, union ccb *
 		continue_probe = 1;
 	}
 	if (continue_probe != 0) {
-		xpt_release_ccb(done_ccb);
 		xpt_schedule(periph, priority);
+		xpt_release_ccb(done_ccb);
 		return;
 	} else
 		daprobedone(periph, done_ccb);
@@ -5813,8 +5813,8 @@ dadone_tur(struct cam_periph *periph, union ccb *done_
 					 /*timeout*/0,
 					 /*getcount_only*/0);
 	}
-	xpt_release_ccb(done_ccb);
 	softc->flags &= ~DA_FLAG_TUR_PENDING;
+	xpt_release_ccb(done_ccb);
 	da_periph_release_locked(periph, DA_REF_TUR);
 	return;
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201911111736.xABHaq30099045>