svn commit: r236228 - in head/sys/cam: ata scsi

Alexander Motin mav at FreeBSD.org
Tue May 29 11:22:41 UTC 2012


Author: mav
Date: Tue May 29 11:22:40 2012
New Revision: 236228
URL: http://svn.freebsd.org/changeset/base/236228

Log:
  Plug request and references leak caused by race between invalidated
  ond probe periph destruction and new incoming probe request.
  
  This at least caused problems with SATA Port Multipliers hot-plug.
  
  MFC after:	2 weeks

Modified:
  head/sys/cam/ata/ata_xpt.c
  head/sys/cam/scsi/scsi_xpt.c

Modified: head/sys/cam/ata/ata_xpt.c
==============================================================================
--- head/sys/cam/ata/ata_xpt.c	Tue May 29 10:35:56 2012	(r236227)
+++ head/sys/cam/ata/ata_xpt.c	Tue May 29 11:22:40 2012	(r236228)
@@ -1327,9 +1327,9 @@ done:
 		done_ccb->ccb_h.status = found ? CAM_REQ_CMP : CAM_REQ_CMP_ERR;
 		xpt_done(done_ccb);
 	}
+	cam_periph_invalidate(periph);
 	cam_release_devq(periph->path,
 	    RELSIM_RELEASE_RUNLEVEL, 0, CAM_RL_XPT + 1, FALSE);
-	cam_periph_invalidate(periph);
 	cam_periph_release_locked(periph);
 }
 
@@ -1580,12 +1580,17 @@ ata_scan_lun(struct cam_periph *periph, 
 	}
 
 	if ((old_periph = cam_periph_find(path, "aprobe")) != NULL) {
-		probe_softc *softc;
+		if ((old_periph->flags & CAM_PERIPH_INVALID) == 0) {
+			probe_softc *softc;
 
-		softc = (probe_softc *)old_periph->softc;
-		TAILQ_INSERT_TAIL(&softc->request_ccbs, &request_ccb->ccb_h,
-				  periph_links.tqe);
-		softc->restart = 1;
+			softc = (probe_softc *)old_periph->softc;
+			TAILQ_INSERT_TAIL(&softc->request_ccbs,
+				&request_ccb->ccb_h, periph_links.tqe);
+			softc->restart = 1;
+		} else {
+			request_ccb->ccb_h.status = CAM_REQ_CMP_ERR;
+			xpt_done(request_ccb);
+		}
 	} else {
 		status = cam_periph_alloc(proberegister, NULL, probecleanup,
 					  probestart, "aprobe",

Modified: head/sys/cam/scsi/scsi_xpt.c
==============================================================================
--- head/sys/cam/scsi/scsi_xpt.c	Tue May 29 10:35:56 2012	(r236227)
+++ head/sys/cam/scsi/scsi_xpt.c	Tue May 29 11:22:40 2012	(r236228)
@@ -1706,9 +1706,9 @@ probe_device_check:
 	done_ccb->ccb_h.status = CAM_REQ_CMP;
 	xpt_done(done_ccb);
 	if (TAILQ_FIRST(&softc->request_ccbs) == NULL) {
+		cam_periph_invalidate(periph);
 		cam_release_devq(periph->path,
 		    RELSIM_RELEASE_RUNLEVEL, 0, CAM_RL_XPT + 1, FALSE);
-		cam_periph_invalidate(periph);
 		cam_periph_release_locked(periph);
 	} else {
 		probeschedule(periph);
@@ -2274,11 +2274,16 @@ scsi_scan_lun(struct cam_periph *periph,
 	}
 
 	if ((old_periph = cam_periph_find(path, "probe")) != NULL) {
-		probe_softc *softc;
+		if ((old_periph->flags & CAM_PERIPH_INVALID) == 0) {
+			probe_softc *softc;
 
-		softc = (probe_softc *)old_periph->softc;
-		TAILQ_INSERT_TAIL(&softc->request_ccbs, &request_ccb->ccb_h,
-				  periph_links.tqe);
+			softc = (probe_softc *)old_periph->softc;
+			TAILQ_INSERT_TAIL(&softc->request_ccbs,
+			    &request_ccb->ccb_h, periph_links.tqe);
+		} else {
+			request_ccb->ccb_h.status = CAM_REQ_CMP_ERR;
+			xpt_done(request_ccb);
+		}
 	} else {
 		status = cam_periph_alloc(proberegister, NULL, probecleanup,
 					  probestart, "probe",


More information about the svn-src-head mailing list