Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 23 Oct 2013 17:08:50 +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-9@freebsd.org
Subject:   svn commit: r256988 - stable/9/sys/cam
Message-ID:  <201310231708.r9NH8oVP061652@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Wed Oct 23 17:08:50 2013
New Revision: 256988
URL: http://svnweb.freebsd.org/changeset/base/256988

Log:
  MFC r256188:
  Close the race on path ID allocation in xpt_bus_register() if two buses are
  registered simultaneously. Due to topology unlock between the ID allocation
  and the bus registration there is a chance that two buses may get the
  same IDs. That is supposed reason of lock assertion panic in CAM during
  initial bus scanning after new iscsid initiates two sessions same time.

Modified:
  stable/9/sys/cam/cam_xpt.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/cam/cam_xpt.c
==============================================================================
--- stable/9/sys/cam/cam_xpt.c	Wed Oct 23 17:04:09 2013	(r256987)
+++ stable/9/sys/cam/cam_xpt.c	Wed Oct 23 17:08:50 2013	(r256988)
@@ -2450,7 +2450,7 @@ xptsetasyncbusfunc(struct cam_eb *bus, v
 	struct ccb_setasync *csa = (struct ccb_setasync *)arg;
 
 	xpt_compile_path(&path, /*periph*/NULL,
-			 bus->sim->path_id,
+			 bus->path_id,
 			 CAM_TARGET_WILDCARD,
 			 CAM_LUN_WILDCARD);
 	xpt_setup_ccb(&cpi.ccb_h, &path, CAM_PRIORITY_NORMAL);
@@ -3874,13 +3874,8 @@ xpt_bus_register(struct cam_sim *sim, de
 		/* Couldn't satisfy request */
 		return (CAM_RESRC_UNAVAIL);
 	}
-	if (strcmp(sim->sim_name, "xpt") != 0) {
-		sim->path_id =
-		    xptpathid(sim->sim_name, sim->unit_number, sim->bus_id);
-	}
 
 	TAILQ_INIT(&new_bus->et_entries);
-	new_bus->path_id = sim->path_id;
 	cam_sim_hold(sim);
 	new_bus->sim = sim;
 	timevalclear(&new_bus->last_reset);
@@ -3889,6 +3884,8 @@ xpt_bus_register(struct cam_sim *sim, de
 	new_bus->generation = 0;
 
 	xpt_lock_buses();
+	sim->path_id = new_bus->path_id =
+	    xptpathid(sim->sim_name, sim->unit_number, sim->bus_id);
 	old_bus = TAILQ_FIRST(&xsoftc.xpt_busses);
 	while (old_bus != NULL
 	    && old_bus->path_id < new_bus->path_id)
@@ -3991,8 +3988,8 @@ xptnextfreepathid(void)
 	path_id_t pathid;
 	const char *strval;
 
+	mtx_assert(&xsoftc.xpt_topo_lock, MA_OWNED);
 	pathid = 0;
-	xpt_lock_buses();
 	bus = TAILQ_FIRST(&xsoftc.xpt_busses);
 retry:
 	/* Find an unoccupied pathid */
@@ -4001,7 +3998,6 @@ retry:
 			pathid++;
 		bus = TAILQ_NEXT(bus, links);
 	}
-	xpt_unlock_buses();
 
 	/*
 	 * Ensure that this pathid is not reserved for
@@ -4010,7 +4006,6 @@ retry:
 	if (resource_string_value("scbus", pathid, "at", &strval) == 0) {
 		++pathid;
 		/* Start the search over */
-		xpt_lock_buses();
 		goto retry;
 	}
 	return (pathid);
@@ -4026,6 +4021,8 @@ xptpathid(const char *sim_name, int sim_
 
 	pathid = CAM_XPT_PATH_ID;
 	snprintf(buf, sizeof(buf), "%s%d", sim_name, sim_unit);
+	if (strcmp(buf, "xpt0") == 0 && sim_bus == 0)
+		return (pathid);
 	i = 0;
 	while ((resource_find_match(&i, &dname, &dunit, "at", buf)) == 0) {
 		if (strcmp(dname, "scbus")) {



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