Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 25 Jan 2018 21:38:10 +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: r328414 - head/sys/cam
Message-ID:  <201801252138.w0PLcA7t098274@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: imp
Date: Thu Jan 25 21:38:09 2018
New Revision: 328414
URL: https://svnweb.freebsd.org/changeset/base/328414

Log:
  When devices are invalidated, there's some cases where ccbs for that
  device still wind up in xpt_done after the path has been
  invalidated. Since we don't always need sim or devq, add some guard
  rails to only fail if we have to use them.
  
  Sponsored by: Netflix
  Differential Revision: https://reviews.freebsd.org/D14040

Modified:
  head/sys/cam/cam_xpt.c

Modified: head/sys/cam/cam_xpt.c
==============================================================================
--- head/sys/cam/cam_xpt.c	Thu Jan 25 21:36:26 2018	(r328413)
+++ head/sys/cam/cam_xpt.c	Thu Jan 25 21:38:09 2018	(r328414)
@@ -5374,8 +5374,8 @@ xpt_path_mtx(struct cam_path *path)
 static void
 xpt_done_process(struct ccb_hdr *ccb_h)
 {
-	struct cam_sim *sim;
-	struct cam_devq *devq;
+	struct cam_sim *sim = NULL;
+	struct cam_devq *devq = NULL;
 	struct mtx *mtx = NULL;
 
 #if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
@@ -5418,9 +5418,15 @@ xpt_done_process(struct ccb_hdr *ccb_h)
 			mtx_unlock(&xsoftc.xpt_highpower_lock);
 	}
 
-	sim = ccb_h->path->bus->sim;
+	/*
+	 * Insulate against a race where the periph is destroyed
+	 * but CCBs are still not all processed.
+	 */
+	if (ccb_h->path->bus)
+		sim = ccb_h->path->bus->sim;
 
 	if (ccb_h->status & CAM_RELEASE_SIMQ) {
+		KASSERT(sim, ("sim missing for CAM_RELEASE_SIMQ request"));
 		xpt_release_simq(sim, /*run_queue*/FALSE);
 		ccb_h->status &= ~CAM_RELEASE_SIMQ;
 	}
@@ -5431,9 +5437,12 @@ xpt_done_process(struct ccb_hdr *ccb_h)
 		ccb_h->status &= ~CAM_DEV_QFRZN;
 	}
 
-	devq = sim->devq;
 	if ((ccb_h->func_code & XPT_FC_USER_CCB) == 0) {
 		struct cam_ed *dev = ccb_h->path->device;
+
+		if (sim)
+			devq = sim->devq;
+		KASSERT(devq, ("sim missing for XPT_FC_USER_CCB request"));
 
 		mtx_lock(&devq->send_mtx);
 		devq->send_active--;



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