Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 15 Aug 2013 19:00:36 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r254375 - in projects/camlock/sys/cam: . scsi
Message-ID:  <201308151900.r7FJ0aeN065284@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Thu Aug 15 19:00:36 2013
New Revision: 254375
URL: http://svnweb.freebsd.org/changeset/base/254375

Log:
  Introduce new per-target lock to protect list of LUNs reported by device.

Modified:
  projects/camlock/sys/cam/cam_xpt.c
  projects/camlock/sys/cam/cam_xpt_internal.h
  projects/camlock/sys/cam/scsi/scsi_xpt.c

Modified: projects/camlock/sys/cam/cam_xpt.c
==============================================================================
--- projects/camlock/sys/cam/cam_xpt.c	Thu Aug 15 17:44:44 2013	(r254374)
+++ projects/camlock/sys/cam/cam_xpt.c	Thu Aug 15 19:00:36 2013	(r254375)
@@ -4526,6 +4526,7 @@ xpt_alloc_target(struct cam_eb *bus, tar
 	target->refcount = 1;
 	target->generation = 0;
 	target->luns = NULL;
+	mtx_init(&target->luns_mtx, "CAM LUNs lock", NULL, MTX_DEF);
 	timevalclear(&target->last_reset);
 	/*
 	 * Hold a reference to our parent bus so it
@@ -4572,6 +4573,7 @@ xpt_release_target(struct cam_et *target
 	KASSERT(TAILQ_EMPTY(&target->ed_entries),
 	    ("destroying target, but device list is not empty"));
 	xpt_release_bus(bus);
+	mtx_destroy(&target->luns_mtx);
 	if (target->luns)
 		free(target->luns, M_CAMXPT);
 	free(target, M_CAMXPT);

Modified: projects/camlock/sys/cam/cam_xpt_internal.h
==============================================================================
--- projects/camlock/sys/cam/cam_xpt_internal.h	Thu Aug 15 17:44:44 2013	(r254374)
+++ projects/camlock/sys/cam/cam_xpt_internal.h	Thu Aug 15 19:00:36 2013	(r254375)
@@ -147,6 +147,7 @@ struct cam_et {
 	struct		timeval last_reset;
 	u_int		rpl_size;
 	struct scsi_report_luns_data *luns;
+	struct mtx	luns_mtx;	/* Protection for luns field. */
 };
 
 /*

Modified: projects/camlock/sys/cam/scsi/scsi_xpt.c
==============================================================================
--- projects/camlock/sys/cam/scsi/scsi_xpt.c	Thu Aug 15 17:44:44 2013	(r254374)
+++ projects/camlock/sys/cam/scsi/scsi_xpt.c	Thu Aug 15 19:00:36 2013	(r254375)
@@ -1728,11 +1728,12 @@ probe_purge_old(struct cam_path *path, s
 	if (path->target == NULL) {
 		return;
 	}
-	if (path->target->luns == NULL) {
-		path->target->luns = new;
-		return;
-	}
+	mtx_lock(&path->target->luns_mtx);
 	old = path->target->luns;
+	path->target->luns = new;
+	mtx_unlock(&path->target->luns_mtx);
+	if (old == NULL)
+		return;
 	nlun_old = scsi_4btoul(old->length) / 8;
 	nlun_new = scsi_4btoul(new->length) / 8;
 
@@ -1774,7 +1775,6 @@ probe_purge_old(struct cam_path *path, s
 		}
 	}
 	free(old, M_CAMXPT);
-	path->target->luns = new;
 }
 
 static void
@@ -2011,6 +2011,7 @@ scsi_scan_bus(struct cam_periph *periph,
 
 		mtx = xpt_path_mtx(scan_info->request_ccb->ccb_h.path);
 		mtx_lock(mtx);
+		mtx_lock(&target->luns_mtx);
 		if (target->luns) {
 			uint32_t first;
 			u_int nluns = scsi_4btoul(target->luns->length) / 8;
@@ -2028,6 +2029,7 @@ scsi_scan_bus(struct cam_periph *periph,
 			if (scan_info->lunindex[target_id] < nluns) {
 				CAM_GET_SIMPLE_LUN(target->luns,
 				    scan_info->lunindex[target_id], lun_id);
+				mtx_unlock(&target->luns_mtx);
 				next_target = 0;
 				CAM_DEBUG(request_ccb->ccb_h.path,
 				    CAM_DEBUG_PROBE,
@@ -2035,6 +2037,7 @@ scsi_scan_bus(struct cam_periph *periph,
 				   scan_info->lunindex[target_id], lun_id));
 				scan_info->lunindex[target_id]++;
 			} else {
+				mtx_unlock(&target->luns_mtx);
 				/*
 				 * We're done with scanning all luns.
 				 *
@@ -2053,7 +2056,9 @@ scsi_scan_bus(struct cam_periph *periph,
 					}
 				}
 			}
-		} else if (request_ccb->ccb_h.status != CAM_REQ_CMP) {
+		} else {
+		    mtx_unlock(&target->luns_mtx);
+		    if (request_ccb->ccb_h.status != CAM_REQ_CMP) {
 			int phl;
 
 			/*
@@ -2085,7 +2090,7 @@ scsi_scan_bus(struct cam_periph *periph,
 			if (lun_id == request_ccb->ccb_h.target_lun
 			    || lun_id > scan_info->cpi->max_lun)
 				next_target = 1;
-		} else {
+		    } else {
 
 			device = request_ccb->ccb_h.path->device;
 
@@ -2101,6 +2106,7 @@ scsi_scan_bus(struct cam_periph *periph,
 			if (lun_id == request_ccb->ccb_h.target_lun
 			    || lun_id > scan_info->cpi->max_lun)
 				next_target = 1;
+		    }
 		}
 
 		/*



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