Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 10 Jun 2011 09:51:16 +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-8@freebsd.org
Subject:   svn commit: r222922 - stable/8/sys/cam/scsi
Message-ID:  <201106100951.p5A9pG4e020281@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Fri Jun 10 09:51:15 2011
New Revision: 222922
URL: http://svn.freebsd.org/changeset/base/222922

Log:
  MFC r206112, r208928 (by mjacob):
  Rearrange how things are done to avoid dereferencing stale pointers in
  the case of immediate unconfigure after configure. Hold the periph an
  extra count while we have the task to create sysctl context outstanding
  so that the periph doesn't go away unexpectedly.

Modified:
  stable/8/sys/cam/scsi/scsi_da.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/cam/scsi/scsi_da.c
==============================================================================
--- stable/8/sys/cam/scsi/scsi_da.c	Fri Jun 10 09:18:43 2011	(r222921)
+++ stable/8/sys/cam/scsi/scsi_da.c	Fri Jun 10 09:51:15 2011	(r222922)
@@ -1075,8 +1075,13 @@ dasysctlinit(void *context, int pending)
 	char tmpstr[80], tmpstr2[80];
 
 	periph = (struct cam_periph *)context;
-	if (cam_periph_acquire(periph) != CAM_REQ_CMP)
+	/*
+	 * periph was held for us when this task was enqueued
+	 */
+	if (periph->flags & CAM_PERIPH_INVALID) {
+		cam_periph_release(periph);
 		return;
+	}
 
 	softc = (struct da_softc *)periph->softc;
 	snprintf(tmpstr, sizeof(tmpstr), "CAM DA unit %d", periph->unit_number);
@@ -1232,29 +1237,6 @@ daregister(struct cam_periph *periph, vo
 	 * Register this media as a disk
 	 */
 
-	mtx_unlock(periph->sim->mtx);
-	softc->disk = disk_alloc();
-	softc->disk->d_open = daopen;
-	softc->disk->d_close = daclose;
-	softc->disk->d_strategy = dastrategy;
-	softc->disk->d_dump = dadump;
-	softc->disk->d_name = "da";
-	softc->disk->d_drv1 = periph;
-	if (cpi.maxio == 0)
-		softc->disk->d_maxsize = DFLTPHYS;	/* traditional default */
-	else if (cpi.maxio > MAXPHYS)
-		softc->disk->d_maxsize = MAXPHYS;	/* for safety */
-	else
-		softc->disk->d_maxsize = cpi.maxio;
-	softc->disk->d_unit = periph->unit_number;
-	softc->disk->d_flags = 0;
-	if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0)
-		softc->disk->d_flags |= DISKFLAG_CANFLUSHCACHE;
-	strlcpy(softc->disk->d_ident, cgd->serial_num,
-	    MIN(sizeof(softc->disk->d_ident), cgd->serial_num_len + 1));
-	disk_create(softc->disk, DISK_VERSION);
-	mtx_lock(periph->sim->mtx);
-
 	/*
 	 * Add async callbacks for bus reset and
 	 * bus device reset calls.  I don't bother
@@ -1272,7 +1254,6 @@ daregister(struct cam_periph *periph, vo
 	 * the end of probe.
 	 */
 	(void)cam_periph_hold(periph, PRIBIO);
-	xpt_schedule(periph, CAM_PRIORITY_DEV);
 
 	/*
 	 * Schedule a periodic event to occasionally send an
@@ -1283,6 +1264,31 @@ daregister(struct cam_periph *periph, vo
 	    (DA_DEFAULT_TIMEOUT * hz) / DA_ORDEREDTAG_INTERVAL,
 	    dasendorderedtag, softc);
 
+	mtx_unlock(periph->sim->mtx);
+	softc->disk = disk_alloc();
+	softc->disk->d_open = daopen;
+	softc->disk->d_close = daclose;
+	softc->disk->d_strategy = dastrategy;
+	softc->disk->d_dump = dadump;
+	softc->disk->d_name = "da";
+	softc->disk->d_drv1 = periph;
+	if (cpi.maxio == 0)
+		softc->disk->d_maxsize = DFLTPHYS;	/* traditional default */
+	else if (cpi.maxio > MAXPHYS)
+		softc->disk->d_maxsize = MAXPHYS;	/* for safety */
+	else
+		softc->disk->d_maxsize = cpi.maxio;
+	softc->disk->d_unit = periph->unit_number;
+	softc->disk->d_flags = 0;
+	if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0)
+		softc->disk->d_flags |= DISKFLAG_CANFLUSHCACHE;
+	strlcpy(softc->disk->d_ident, cgd->serial_num,
+	    MIN(sizeof(softc->disk->d_ident), cgd->serial_num_len + 1));
+	disk_create(softc->disk, DISK_VERSION);
+	mtx_lock(periph->sim->mtx);
+
+	xpt_schedule(periph, CAM_PRIORITY_DEV);
+
 	return(CAM_REQ_CMP);
 }
 
@@ -1754,6 +1760,7 @@ dadone(struct cam_periph *periph, union 
 			 * Create our sysctl variables, now that we know
 			 * we have successfully attached.
 			 */
+			(void) cam_periph_acquire(periph);	/* increase the refcount */
 			taskqueue_enqueue(taskqueue_thread,&softc->sysctl_task);
 		}
 		softc->state = DA_STATE_NORMAL;	



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