Author: mav
Date: Sat Jun  9 07:18:13 2012
New Revision: 236779
URL: http://svn.freebsd.org/changeset/base/236779

Log:
  MFC r236228:
  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.

Modified:
  stable/9/sys/cam/ata/ata_xpt.c
  stable/9/sys/cam/scsi/scsi_xpt.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/cam/ata/ata_xpt.c
==============================================================================
--- stable/9/sys/cam/ata/ata_xpt.c      Sat Jun  9 06:43:26 2012        
(r236778)
+++ stable/9/sys/cam/ata/ata_xpt.c      Sat Jun  9 07:18:13 2012        
(r236779)
@@ -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: stable/9/sys/cam/scsi/scsi_xpt.c
==============================================================================
--- stable/9/sys/cam/scsi/scsi_xpt.c    Sat Jun  9 06:43:26 2012        
(r236778)
+++ stable/9/sys/cam/scsi/scsi_xpt.c    Sat Jun  9 07:18:13 2012        
(r236779)
@@ -1710,9 +1710,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);
@@ -2278,11 +2278,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",
_______________________________________________
svn-src-stable-9@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-stable-9
To unsubscribe, send any mail to "svn-src-stable-9-unsubscr...@freebsd.org"

Reply via email to