Author: mav
Date: Mon Oct 20 07:57:07 2014
New Revision: 273317
URL: https://svnweb.freebsd.org/changeset/base/273317

Log:
  MFC r272938:  Filter out duplicate AC_PATH_REGISTERED async events.
  
  Queued async events handling in CAM opened race, that may lead to duplicate
  AC_PATH_REGISTERED events delivery during boot.  That was not happening
  before r272935 because the driver was initialized later.  After that change
  it started create duplicate ports in CTL.

Modified:
  stable/10/sys/cam/ctl/scsi_ctl.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/cam/ctl/scsi_ctl.c
==============================================================================
--- stable/10/sys/cam/ctl/scsi_ctl.c    Mon Oct 20 07:52:48 2014        
(r273316)
+++ stable/10/sys/cam/ctl/scsi_ctl.c    Mon Oct 20 07:57:07 2014        
(r273317)
@@ -271,11 +271,19 @@ ctlfeperiphinit(void)
 static void
 ctlfeasync(void *callback_arg, uint32_t code, struct cam_path *path, void *arg)
 {
+       struct ctlfe_softc *softc;
 
 #ifdef CTLFEDEBUG
        printf("%s: entered\n", __func__);
 #endif
 
+       mtx_lock(&ctlfe_list_mtx);
+       STAILQ_FOREACH(softc, &ctlfe_softc_list, links) {
+               if (softc->path_id == xpt_path_path_id(path))
+                       break;
+       }
+       mtx_unlock(&ctlfe_list_mtx);
+
        /*
         * When a new path gets registered, and it is capable of target
         * mode, go ahead and attach.  Later on, we may need to be more
@@ -284,7 +292,6 @@ ctlfeasync(void *callback_arg, uint32_t 
        switch (code) {
        case AC_PATH_REGISTERED: {
                struct ctl_port *port;
-               struct ctlfe_softc *bus_softc;
                struct ccb_pathinq *cpi;
                int retval;
 
@@ -299,6 +306,14 @@ ctlfeasync(void *callback_arg, uint32_t 
                        break;
                }
 
+               if (softc != NULL) {
+#ifdef CTLFEDEBUG
+                       printf("%s: CTL port for CAM path %u already exists\n",
+                              __func__, xpt_path_path_id(path));
+#endif
+                       break;
+               }
+
 #ifdef CTLFE_INIT_ENABLE
                if (ctlfe_num_targets >= ctlfe_max_targets) {
                        union ccb *ccb;
@@ -347,25 +362,23 @@ ctlfeasync(void *callback_arg, uint32_t 
                 * use M_NOWAIT.  Of course this means trouble if we
                 * can't allocate memory.
                 */
-               bus_softc = malloc(sizeof(*bus_softc), M_CTLFE,
-                                  M_NOWAIT | M_ZERO);
-               if (bus_softc == NULL) {
+               softc = malloc(sizeof(*softc), M_CTLFE, M_NOWAIT | M_ZERO);
+               if (softc == NULL) {
                        printf("%s: unable to malloc %zd bytes for softc\n",
-                              __func__, sizeof(*bus_softc));
+                              __func__, sizeof(*softc));
                        return;
                }
 
-               bus_softc->path_id = cpi->ccb_h.path_id;
-               bus_softc->sim = xpt_path_sim(path);
+               softc->path_id = cpi->ccb_h.path_id;
+               softc->sim = xpt_path_sim(path);
                if (cpi->maxio != 0)
-                       bus_softc->maxio = cpi->maxio;
+                       softc->maxio = cpi->maxio;
                else
-                       bus_softc->maxio = DFLTPHYS;
-               mtx_init(&bus_softc->lun_softc_mtx, "LUN softc mtx", NULL,
-                   MTX_DEF);
-               STAILQ_INIT(&bus_softc->lun_softc_list);
+                       softc->maxio = DFLTPHYS;
+               mtx_init(&softc->lun_softc_mtx, "LUN softc mtx", NULL, MTX_DEF);
+               STAILQ_INIT(&softc->lun_softc_list);
 
-               port = &bus_softc->port;
+               port = &softc->port;
                port->frontend = &ctlfe_frontend;
 
                /*
@@ -380,21 +393,21 @@ ctlfeasync(void *callback_arg, uint32_t 
 
                /* XXX KDM what should the real number be here? */
                port->num_requested_ctl_io = 4096;
-               snprintf(bus_softc->port_name, sizeof(bus_softc->port_name),
+               snprintf(softc->port_name, sizeof(softc->port_name),
                         "%s%d", cpi->dev_name, cpi->unit_number);
                /*
                 * XXX KDM it would be nice to allocate storage in the
                 * frontend structure itself.
                 */
-               port->port_name = bus_softc->port_name;
+               port->port_name = softc->port_name;
                port->physical_port = cpi->unit_number;
                port->virtual_port = cpi->bus_id;
                port->port_online = ctlfe_online;
                port->port_offline = ctlfe_offline;
-               port->onoff_arg = bus_softc;
+               port->onoff_arg = softc;
                port->lun_enable = ctlfe_lun_enable;
                port->lun_disable = ctlfe_lun_disable;
-               port->targ_lun_arg = bus_softc;
+               port->targ_lun_arg = softc;
                port->fe_datamove = ctlfe_datamove_done;
                port->fe_done = ctlfe_datamove_done;
                /*
@@ -416,35 +429,28 @@ ctlfeasync(void *callback_arg, uint32_t 
                if (retval != 0) {
                        printf("%s: ctl_port_register() failed with "
                               "error %d!\n", __func__, retval);
-                       mtx_destroy(&bus_softc->lun_softc_mtx);
-                       free(bus_softc, M_CTLFE);
+                       mtx_destroy(&softc->lun_softc_mtx);
+                       free(softc, M_CTLFE);
                        break;
                } else {
                        mtx_lock(&ctlfe_list_mtx);
-                       STAILQ_INSERT_TAIL(&ctlfe_softc_list, bus_softc, links);
+                       STAILQ_INSERT_TAIL(&ctlfe_softc_list, softc, links);
                        mtx_unlock(&ctlfe_list_mtx);
                }
 
                break;
        }
        case AC_PATH_DEREGISTERED: {
-               struct ctlfe_softc *softc = NULL;
-
-               mtx_lock(&ctlfe_list_mtx);
-               STAILQ_FOREACH(softc, &ctlfe_softc_list, links) {
-                       if (softc->path_id == xpt_path_path_id(path)) {
-                               STAILQ_REMOVE(&ctlfe_softc_list, softc,
-                                               ctlfe_softc, links);
-                               break;
-                       }
-               }
-               mtx_unlock(&ctlfe_list_mtx);
 
                if (softc != NULL) {
                        /*
                         * XXX KDM are we certain at this point that there
                         * are no outstanding commands for this frontend?
                         */
+                       mtx_lock(&ctlfe_list_mtx);
+                       STAILQ_REMOVE(&ctlfe_softc_list, softc, ctlfe_softc,
+                           links);
+                       mtx_unlock(&ctlfe_list_mtx);
                        ctl_port_deregister(&softc->port);
                        mtx_destroy(&softc->lun_softc_mtx);
                        free(softc, M_CTLFE);
@@ -459,8 +465,7 @@ ctlfeasync(void *callback_arg, uint32_t 
                switch (ac->contract_number) {
                case AC_CONTRACT_DEV_CHG: {
                        struct ac_device_changed *dev_chg;
-                       struct ctlfe_softc *softc;
-                       int retval, found;
+                       int retval;
 
                        dev_chg = (struct ac_device_changed *)ac->contract_data;
 
@@ -469,18 +474,7 @@ ctlfeasync(void *callback_arg, uint32_t 
                               xpt_path_path_id(path), dev_chg->target,
                               (dev_chg->arrived == 0) ?  "left" : "arrived");
 
-                       found = 0;
-
-                       mtx_lock(&ctlfe_list_mtx);
-                       STAILQ_FOREACH(softc, &ctlfe_softc_list, links) {
-                               if (softc->path_id == xpt_path_path_id(path)) {
-                                       found = 1;
-                                       break;
-                               }
-                       }
-                       mtx_unlock(&ctlfe_list_mtx);
-
-                       if (found == 0) {
+                       if (softc == NULL) {
                                printf("%s: CTL port for CAM path %u not "
                                       "found!\n", __func__,
                                       xpt_path_path_id(path));
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to