Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 9 Dec 2012 19:53:21 +0000 (UTC)
From:      "Kenneth D. Merry" <ken@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r244052 - head/sys/cam/ctl
Message-ID:  <201212091953.qB9JrL34016535@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ken
Date: Sun Dec  9 19:53:21 2012
New Revision: 244052
URL: http://svnweb.freebsd.org/changeset/base/244052

Log:
  Fix a couple of CTL locking issues and clean up some duplicated code.
  
  ctl_frontend_cam_sim.c:	Coalesce cfcs_online() and cfcs_offline()
  			into a single function since these were
  			identical except for one line.
  
  			Make sure we hold the SIM lock around path
  			creation, and calling xpt_rescan().
  
  scsi_ctl.c:		In ctlfe_onoffline(), make sure we hold the
  			SIM lock around path creation and free
  			calls, as well as xpt_action().
  
  			In ctlfe_lun_enable(), hold the SIM lock
  			around path and peripheral operations that
  			require it.
  
  Sponsored by:	Spectra Logic Corporation
  MFC after:	1 week

Modified:
  head/sys/cam/ctl/ctl_frontend_cam_sim.c
  head/sys/cam/ctl/scsi_ctl.c

Modified: head/sys/cam/ctl/ctl_frontend_cam_sim.c
==============================================================================
--- head/sys/cam/ctl/ctl_frontend_cam_sim.c	Sun Dec  9 19:20:28 2012	(r244051)
+++ head/sys/cam/ctl/ctl_frontend_cam_sim.c	Sun Dec  9 19:53:21 2012	(r244052)
@@ -275,7 +275,7 @@ cfcs_shutdown(void)
 }
 
 static void
-cfcs_online(void *arg)
+cfcs_onoffline(void *arg, int online)
 {
 	struct cfcs_softc *softc;
 	union ccb *ccb;
@@ -283,13 +283,12 @@ cfcs_online(void *arg)
 	softc = (struct cfcs_softc *)arg;
 
 	mtx_lock(&softc->lock);
-	softc->online = 1;
-	mtx_unlock(&softc->lock);
+	softc->online = online;
 
 	ccb = xpt_alloc_ccb_nowait();
 	if (ccb == NULL) {
 		printf("%s: unable to allocate CCB for rescan\n", __func__);
-		return;
+		goto bailout;
 	}
 
 	if (xpt_create_path(&ccb->ccb_h.path, xpt_periph,
@@ -297,37 +296,24 @@ cfcs_online(void *arg)
 			    CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
 		printf("%s: can't allocate path for rescan\n", __func__);
 		xpt_free_ccb(ccb);
-		return;
+		goto bailout;
 	}
 	xpt_rescan(ccb);
+
+bailout:
+	mtx_unlock(&softc->lock);
 }
 
 static void
-cfcs_offline(void *arg)
+cfcs_online(void *arg)
 {
-	struct cfcs_softc *softc;
-	union ccb *ccb;
-
-	softc = (struct cfcs_softc *)arg;
-
-	mtx_lock(&softc->lock);
-	softc->online = 0;
-	mtx_unlock(&softc->lock);
-
-	ccb = xpt_alloc_ccb_nowait();
-	if (ccb == NULL) {
-		printf("%s: unable to allocate CCB for rescan\n", __func__);
-		return;
-	}
+	cfcs_onoffline(arg, /*online*/ 1);
+}
 
-	if (xpt_create_path(&ccb->ccb_h.path, xpt_periph,
-			    cam_sim_path(softc->sim), CAM_TARGET_WILDCARD,
-			    CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
-		printf("%s: can't allocate path for rescan\n", __func__);
-		xpt_free_ccb(ccb);
-		return;
-	}
-	xpt_rescan(ccb);
+static void
+cfcs_offline(void *arg)
+{
+	cfcs_onoffline(arg, /*online*/ 0);
 }
 
 static int

Modified: head/sys/cam/ctl/scsi_ctl.c
==============================================================================
--- head/sys/cam/ctl/scsi_ctl.c	Sun Dec  9 19:20:28 2012	(r244051)
+++ head/sys/cam/ctl/scsi_ctl.c	Sun Dec  9 19:53:21 2012	(r244052)
@@ -1687,16 +1687,21 @@ ctlfe_onoffline(void *arg, int online)
 
 	set_wwnn = 0;
 
+	sim = bus_softc->sim;
+
+	CAM_SIM_LOCK(sim);
 	status = xpt_create_path(&path, /*periph*/ NULL, bus_softc->path_id,
 		CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
 	if (status != CAM_REQ_CMP) {
 		printf("%s: unable to create path!\n", __func__);
+		CAM_SIM_UNLOCK(sim);
 		return;
 	}
+	CAM_SIM_UNLOCK(sim);
+
 	ccb = (union ccb *)malloc(sizeof(*ccb), M_TEMP, M_WAITOK | M_ZERO);
 	xpt_setup_ccb(&ccb->ccb_h, path, CAM_PRIORITY_NONE);
 
-	sim = xpt_path_sim(path);
 
 	/*
 	 * Copan WWN format:
@@ -1883,27 +1888,30 @@ ctlfe_lun_enable(void *arg, struct ctl_i
 
 	
 	bus_softc = (struct ctlfe_softc *)arg;
+	sim = bus_softc->sim;
+
+	CAM_SIM_LOCK(sim);
 
-	status = xpt_create_path_unlocked(&path, /*periph*/ NULL,
-					  bus_softc->path_id,
-					  targ_id.id,
-					  lun_id);
+	status = xpt_create_path(&path, /*periph*/ NULL, bus_softc->path_id,
+				 targ_id.id, lun_id);
 	/* XXX KDM need some way to return status to CTL here? */
 	if (status != CAM_REQ_CMP) {
 		printf("%s: could not create path, status %#x\n", __func__,
 		       status);
+		CAM_SIM_UNLOCK(sim);
 		return (1);
 	}
+	CAM_SIM_UNLOCK(sim);
 
 	softc = malloc(sizeof(*softc), M_CTLFE, M_WAITOK | M_ZERO);
-	sim = xpt_path_sim(path);
-	mtx_lock(sim->mtx);
+
+	CAM_SIM_LOCK(sim);
 	periph = cam_periph_find(path, "ctl");
 	if (periph != NULL) {
 		/* We've already got a periph, no need to alloc a new one. */
 		xpt_free_path(path);
 		free(softc, M_CTLFE);
-		mtx_unlock(sim->mtx);
+		CAM_SIM_UNLOCK(sim);
 		return (0);
 	}
 
@@ -1923,7 +1931,7 @@ ctlfe_lun_enable(void *arg, struct ctl_i
 
 	xpt_free_path(path);
 
-	mtx_unlock(sim->mtx);
+	CAM_SIM_UNLOCK(sim);
 
 	return (0);
 }



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