svn commit: r256671 - in projects/camlock/sys: cam/ctl dev/aic7xxx dev/firewire dev/isp dev/mpt

Alexander Motin mav at FreeBSD.org
Thu Oct 17 09:45:05 UTC 2013


Author: mav
Date: Thu Oct 17 09:45:03 2013
New Revision: 256671
URL: http://svnweb.freebsd.org/changeset/base/256671

Log:
  Make CTL CAM target frontend to drop periph lock while calling CTL or SIM
  methods. This radically reduces congestion on that lock.
  
  To make it possible, fix several target mode SIMs to not blindly clear
  ccb_h.flags field of ATIO CCBs.  Not all CCB flags there belong to them.

Modified:
  projects/camlock/sys/cam/ctl/scsi_ctl.c
  projects/camlock/sys/dev/aic7xxx/aic79xx.c
  projects/camlock/sys/dev/aic7xxx/aic7xxx.c
  projects/camlock/sys/dev/firewire/sbp_targ.c
  projects/camlock/sys/dev/isp/isp_freebsd.c
  projects/camlock/sys/dev/mpt/mpt_cam.c

Modified: projects/camlock/sys/cam/ctl/scsi_ctl.c
==============================================================================
--- projects/camlock/sys/cam/ctl/scsi_ctl.c	Thu Oct 17 07:57:58 2013	(r256670)
+++ projects/camlock/sys/cam/ctl/scsi_ctl.c	Thu Oct 17 09:45:03 2013	(r256671)
@@ -576,6 +576,7 @@ ctlferegister(struct cam_periph *periph,
 		xpt_setup_ccb(&new_ccb->ccb_h, periph->path, /*priority*/ 1);
 		new_ccb->ccb_h.func_code = XPT_ACCEPT_TARGET_IO;
 		new_ccb->ccb_h.cbfcnp = ctlfedone;
+		new_ccb->ccb_h.flags |= CAM_UNLOCKED;
 		xpt_action(new_ccb);
 		softc->atios_sent++;
 		status = new_ccb->ccb_h.status;
@@ -611,6 +612,7 @@ ctlferegister(struct cam_periph *periph,
 		xpt_setup_ccb(&new_ccb->ccb_h, periph->path, /*priority*/ 1);
 		new_ccb->ccb_h.func_code = XPT_IMMEDIATE_NOTIFY;
 		new_ccb->ccb_h.cbfcnp = ctlfedone;
+		new_ccb->ccb_h.flags |= CAM_UNLOCKED;
 		xpt_action(new_ccb);
 		softc->inots_sent++;
 		status = new_ccb->ccb_h.status;
@@ -782,7 +784,6 @@ ctlfestart(struct cam_periph *periph, un
 				}
 				start_ccb->ccb_h.func_code = XPT_ABORT;
 				start_ccb->cab.abort_ccb = (union ccb *)atio;
-				start_ccb->ccb_h.cbfcnp = ctlfedone;
 
 				/* Tell the SIM that we've aborted this ATIO */
 				xpt_action(start_ccb);
@@ -995,6 +996,7 @@ ctlfestart(struct cam_periph *periph, un
 			      /*data_ptr*/ data_ptr,
 			      /*dxfer_len*/ dxfer_len,
 			      /*timeout*/ 5 * 1000);
+		start_ccb->ccb_h.flags |= CAM_UNLOCKED;
 		start_ccb->ccb_h.ccb_atio = atio;
 		if (((flags & CAM_SEND_STATUS) == 0)
 		 && (io != NULL))
@@ -1002,7 +1004,9 @@ ctlfestart(struct cam_periph *periph, un
 
 		softc->ctios_sent++;
 
+		cam_periph_unlock(periph);
 		xpt_action(start_ccb);
+		cam_periph_lock(periph);
 
 		if ((atio->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 			cam_release_devq(periph->path,
@@ -1139,7 +1143,10 @@ ctlfedone(struct cam_periph *periph, uni
 	struct ctlfe_softc *bus_softc;
 	struct ccb_accept_tio *atio = NULL;
 	union ctl_io *io = NULL;
+	struct mtx *mtx;
 
+	KASSERT((done_ccb->ccb_h.flags & CAM_UNLOCKED) != 0,
+	    ("CCB in ctlfedone() without CAM_UNLOCKED flag"));
 #ifdef CTLFE_DEBUG
 	printf("%s: entered, func_code = %#x, type = %#lx\n", __func__,
 	       done_ccb->ccb_h.func_code, done_ccb->ccb_h.ccb_type);
@@ -1147,6 +1154,8 @@ ctlfedone(struct cam_periph *periph, uni
 
 	softc = (struct ctlfe_lun_softc *)periph->softc;
 	bus_softc = softc->parent_softc;
+	mtx = cam_periph_mtx(periph);
+	mtx_lock(mtx);
 
 	/*
 	 * If the peripheral is invalid, ATIOs and immediate notify CCBs
@@ -1162,7 +1171,7 @@ ctlfedone(struct cam_periph *periph, uni
 		case XPT_IMMEDIATE_NOTIFY:
 		case XPT_NOTIFY_ACKNOWLEDGE:
 			ctlfe_free_ccb(periph, done_ccb);
-			return;
+			goto out;
 		default:
 			break;
 		}
@@ -1200,6 +1209,7 @@ ctlfedone(struct cam_periph *periph, uni
 			xpt_schedule(periph, /*priority*/ 1);
 			break;
 		}
+		mtx_unlock(mtx);
 		ctl_zero_io(io);
 
 		/* Save pointers on both sides */
@@ -1256,7 +1266,7 @@ ctlfedone(struct cam_periph *periph, uni
 #endif
 
 		ctl_queue(io);
-		break;
+		return;
 	}
 	case XPT_CONT_TARGET_IO: {
 		int srr = 0;
@@ -1318,7 +1328,7 @@ ctlfedone(struct cam_periph *periph, uni
 			TAILQ_INSERT_HEAD(&softc->work_queue, &atio->ccb_h,
 					  periph_links.tqe);
 			xpt_schedule(periph, /*priority*/ 1);
-			return;
+			break;
 		}
 
 		/*
@@ -1344,10 +1354,11 @@ ctlfedone(struct cam_periph *periph, uni
 			}
 			if (periph->flags & CAM_PERIPH_INVALID) {
 				ctlfe_free_ccb(periph, (union ccb *)atio);
-				return;
 			} else {
-				xpt_action((union ccb *)atio);
 				softc->atios_sent++;
+				mtx_unlock(mtx);
+				xpt_action((union ccb *)atio);
+				return;
 			}
 		} else {
 			struct ctlfe_lun_cmd_info *cmd_info;
@@ -1463,10 +1474,12 @@ ctlfedone(struct cam_periph *periph, uni
 					      /*dxfer_len*/ dxfer_len,
 					      /*timeout*/ 5 * 1000);
 
+				csio->ccb_h.flags |= CAM_UNLOCKED;
 				csio->resid = 0;
 				csio->ccb_h.ccb_atio = atio;
 				io->io_hdr.flags |= CTL_FLAG_DMA_INPROG;
 				softc->ctios_sent++;
+				mtx_unlock(mtx);
 				xpt_action((union ccb *)csio);
 			} else {
 				/*
@@ -1475,10 +1488,12 @@ ctlfedone(struct cam_periph *periph, uni
 				 */
 				softc->ccbs_freed++;
 				xpt_release_ccb(done_ccb);
+				mtx_unlock(mtx);
 
 				/* Call the backend move done callback */
 				io->scsiio.be_move_done(io);
 			}
+			return;
 		}
 		break;
 	}
@@ -1599,7 +1614,7 @@ ctlfedone(struct cam_periph *periph, uni
 				ctl_free_io(io);
 				ctlfe_free_ccb(periph, done_ccb);
 
-				return;
+				goto out;
 			}
 			if (send_ctl_io != 0) {
 				ctl_queue(io);
@@ -1636,12 +1651,6 @@ ctlfedone(struct cam_periph *periph, uni
 		xpt_action(done_ccb);
 		softc->inots_sent++;
 		break;
-	case XPT_ABORT:
-		/*
-		 * XPT_ABORT is an immediate CCB, we shouldn't get here.
-		 */
-		panic("%s: XPT_ABORT CCB returned!", __func__);
-		break;
 	case XPT_SET_SIM_KNOB:
 	case XPT_GET_SIM_KNOB:
 		break;
@@ -1650,6 +1659,9 @@ ctlfedone(struct cam_periph *periph, uni
 		      done_ccb->ccb_h.func_code);
 		break;
 	}
+
+out:
+	mtx_unlock(mtx);
 }
 
 static void

Modified: projects/camlock/sys/dev/aic7xxx/aic79xx.c
==============================================================================
--- projects/camlock/sys/dev/aic7xxx/aic79xx.c	Thu Oct 17 07:57:58 2013	(r256670)
+++ projects/camlock/sys/dev/aic7xxx/aic79xx.c	Thu Oct 17 09:45:03 2013	(r256671)
@@ -10343,9 +10343,9 @@ ahd_handle_target_cmd(struct ahd_softc *
 		/* Tag was included */
 		atio->tag_action = *byte++;
 		atio->tag_id = *byte++;
-		atio->ccb_h.flags = CAM_TAG_ACTION_VALID;
+		atio->ccb_h.flags |= CAM_TAG_ACTION_VALID;
 	} else {
-		atio->ccb_h.flags = 0;
+		atio->ccb_h.flags &= ~CAM_TAG_ACTION_VALID;
 	}
 	byte++;
 

Modified: projects/camlock/sys/dev/aic7xxx/aic7xxx.c
==============================================================================
--- projects/camlock/sys/dev/aic7xxx/aic7xxx.c	Thu Oct 17 07:57:58 2013	(r256670)
+++ projects/camlock/sys/dev/aic7xxx/aic7xxx.c	Thu Oct 17 09:45:03 2013	(r256671)
@@ -7843,9 +7843,9 @@ ahc_handle_target_cmd(struct ahc_softc *
 		/* Tag was included */
 		atio->tag_action = *byte++;
 		atio->tag_id = *byte++;
-		atio->ccb_h.flags = CAM_TAG_ACTION_VALID;
+		atio->ccb_h.flags |= CAM_TAG_ACTION_VALID;
 	} else {
-		atio->ccb_h.flags = 0;
+		atio->ccb_h.flags &= ~CAM_TAG_ACTION_VALID;
 	}
 	byte++;
 

Modified: projects/camlock/sys/dev/firewire/sbp_targ.c
==============================================================================
--- projects/camlock/sys/dev/firewire/sbp_targ.c	Thu Oct 17 07:57:58 2013	(r256670)
+++ projects/camlock/sys/dev/firewire/sbp_targ.c	Thu Oct 17 09:45:03 2013	(r256671)
@@ -1483,7 +1483,7 @@ sbp_targ_cmd_handler(struct fw_xfer *xfe
 	atio->tag_id = orbi->orb_lo;
 	atio->init_id = orbi->login->id;
 
-	atio->ccb_h.flags = CAM_TAG_ACTION_VALID;
+	atio->ccb_h.flags |= CAM_TAG_ACTION_VALID;
 	bytes = (u_char *)&orb[5];
 	if (debug)
 		printf("%s: %p %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",

Modified: projects/camlock/sys/dev/isp/isp_freebsd.c
==============================================================================
--- projects/camlock/sys/dev/isp/isp_freebsd.c	Thu Oct 17 07:57:58 2013	(r256670)
+++ projects/camlock/sys/dev/isp/isp_freebsd.c	Thu Oct 17 09:45:03 2013	(r256671)
@@ -2281,9 +2281,9 @@ isp_handle_platform_atio(ispsoftc_t *isp
 	atiop->ccb_h.target_id = aep->at_tgt;
 	atiop->ccb_h.target_lun = aep->at_lun;
 	if (aep->at_flags & AT_NODISC) {
-		atiop->ccb_h.flags = CAM_DIS_DISCONNECT;
+		atiop->ccb_h.flags |= CAM_DIS_DISCONNECT;
 	} else {
-		atiop->ccb_h.flags = 0;
+		atiop->ccb_h.flags &= ~CAM_DIS_DISCONNECT;
 	}
 
 	if (status & QLTM_SVALID) {
@@ -2452,15 +2452,15 @@ isp_handle_platform_atio2(ispsoftc_t *is
 	atiop->tag_id = atp->tag;
 	switch (aep->at_taskflags & ATIO2_TC_ATTR_MASK) {
 	case ATIO2_TC_ATTR_SIMPLEQ:
-		atiop->ccb_h.flags = CAM_TAG_ACTION_VALID;
+		atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
 		atiop->tag_action = MSG_SIMPLE_Q_TAG;
 		break;
 	case ATIO2_TC_ATTR_HEADOFQ:
-		atiop->ccb_h.flags = CAM_TAG_ACTION_VALID;
+		atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
 		atiop->tag_action = MSG_HEAD_OF_Q_TAG;
 		break;
 	case ATIO2_TC_ATTR_ORDERED:
-		atiop->ccb_h.flags = CAM_TAG_ACTION_VALID;
+		atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
 		atiop->tag_action = MSG_ORDERED_Q_TAG;
 		break;
 	case ATIO2_TC_ATTR_ACAQ:		/* ?? */
@@ -2673,15 +2673,15 @@ isp_handle_platform_atio7(ispsoftc_t *is
 	atiop->tag_id = atp->tag;
 	switch (aep->at_cmnd.fcp_cmnd_task_attribute & FCP_CMND_TASK_ATTR_MASK) {
 	case FCP_CMND_TASK_ATTR_SIMPLE:
-		atiop->ccb_h.flags = CAM_TAG_ACTION_VALID;
+		atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
 		atiop->tag_action = MSG_SIMPLE_Q_TAG;
 		break;
 	case FCP_CMND_TASK_ATTR_HEAD:
-		atiop->ccb_h.flags = CAM_TAG_ACTION_VALID;
+		atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
 		atiop->tag_action = MSG_HEAD_OF_Q_TAG;
 		break;
 	case FCP_CMND_TASK_ATTR_ORDERED:
-		atiop->ccb_h.flags = CAM_TAG_ACTION_VALID;
+		atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
 		atiop->tag_action = MSG_ORDERED_Q_TAG;
 		break;
 	default:
@@ -5001,7 +5001,6 @@ isp_action(struct cam_sim *sim, union cc
 		}
 		ccb->ccb_h.spriv_field0 = 0;
 		ccb->ccb_h.spriv_ptr1 = isp;
-		ccb->ccb_h.flags = 0;
 
 		if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
 			if (ccb->atio.tag_id) {

Modified: projects/camlock/sys/dev/mpt/mpt_cam.c
==============================================================================
--- projects/camlock/sys/dev/mpt/mpt_cam.c	Thu Oct 17 07:57:58 2013	(r256670)
+++ projects/camlock/sys/dev/mpt/mpt_cam.c	Thu Oct 17 09:45:03 2013	(r256671)
@@ -3683,7 +3683,6 @@ mpt_action(struct cam_sim *sim, union cc
 		lun_id_t lun = ccb->ccb_h.target_lun;
 		ccb->ccb_h.sim_priv.entries[0].field = 0;
 		ccb->ccb_h.sim_priv.entries[1].ptr = mpt;
-		ccb->ccb_h.flags = 0;
 
 		if (lun == CAM_LUN_WILDCARD) {
 			if (ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
@@ -5156,7 +5155,7 @@ mpt_scsi_tgt_atio(struct mpt_softc *mpt,
 	tgt->tag_id = atiop->tag_id;
 	if (tag_action) {
 		atiop->tag_action = tag_action;
-		atiop->ccb_h.flags = CAM_TAG_ACTION_VALID;
+		atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID;
 	}
 	if (mpt->verbose >= MPT_PRT_DEBUG) {
 		int i;


More information about the svn-src-projects mailing list