Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 20 Oct 2014 07:57:07 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r273317 - stable/10/sys/cam/ctl
Message-ID:  <201410200757.s9K7v7f0084073@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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));



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