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);
 }
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to