svn commit: r235018 - projects/iscsi_opt/sys/dev/iscsi/initiator

Kip Macy kmacy at FreeBSD.org
Fri May 4 16:53:44 UTC 2012


Author: kmacy
Date: Fri May  4 16:53:43 2012
New Revision: 235018
URL: http://svn.freebsd.org/changeset/base/235018

Log:
  change serialization on the cam freeze queue to avoid losing
  races with the socket upcall

Modified:
  projects/iscsi_opt/sys/dev/iscsi/initiator/isc_cam.c
  projects/iscsi_opt/sys/dev/iscsi/initiator/isc_sm.c
  projects/iscsi_opt/sys/dev/iscsi/initiator/iscsivar.h

Modified: projects/iscsi_opt/sys/dev/iscsi/initiator/isc_cam.c
==============================================================================
--- projects/iscsi_opt/sys/dev/iscsi/initiator/isc_cam.c	Fri May  4 16:25:35 2012	(r235017)
+++ projects/iscsi_opt/sys/dev/iscsi/initiator/isc_cam.c	Fri May  4 16:53:43 2012	(r235018)
@@ -250,13 +250,19 @@ ic_action(struct cam_sim *sim, union ccb
 		  return;
 
 	  if (rc == EWOULDBLOCK) {
-		  if (sim->devq->send_queue.qfrozen_cnt[0] == 0) {
+		  if ((sp->cam_flags & ISC_QFROZEN) == 0) {
 			  xpt_freeze_simq(sim, 1);
+			  sp->cam_flags |= ISC_QFROZEN;
 			  CAM_UNLOCK(sp);
 			  SOCKBUF_LOCK(&sp->soc->so_snd);
+			  CAM_LOCK(sp);
+			  if (sp->cam_sim->devq->send_queue.qfrozen_cnt[0] != 1) {
+				  printf("lost race when acquiring socket buffer lock qfrozen_cnt=%d\n", sp->cam_sim->devq->send_queue.qfrozen_cnt[0]);
+				  sp->cam_sim->devq->send_queue.qfrozen_cnt[0] = 1;
+			  }
 			  soupcall_set(sp->soc, SO_SND, isc_so_snd_upcall, sp);
 			  SOCKBUF_UNLOCK(&sp->soc->so_snd);
-			  CAM_LOCK(sp);
+
 		  }
 		  status = ccb->ccb_h.status &= ~CAM_STATUS_MASK;
 		  csio->ccb_h.status = status | CAM_REQUEUE_REQ;
@@ -331,6 +337,9 @@ ic_action(struct cam_sim *sim, union ccb
 	  ccb_h->status = CAM_REQ_INVALID;
 	  break;
      }
+     if (ccb_h->status != CAM_REQ_CMP) 
+       debug(2, "command %d status %d", ccb_h->func_code, ccb_h->status); 
+
 #if __FreeBSD_version < 700000
      XPT_DONE(sp, ccb);
 #else

Modified: projects/iscsi_opt/sys/dev/iscsi/initiator/isc_sm.c
==============================================================================
--- projects/iscsi_opt/sys/dev/iscsi/initiator/isc_sm.c	Fri May  4 16:25:35 2012	(r235017)
+++ projects/iscsi_opt/sys/dev/iscsi/initiator/isc_sm.c	Fri May  4 16:53:43 2012	(r235018)
@@ -363,8 +363,23 @@ isc_so_snd_upcall(struct socket *so, voi
 	sp->space_needed = 0;
 
 	mtx_lock(sp->cam_sim->mtx);
-	xpt_release_simq(sp->cam_sim, 0);
+
+	if (sp->cam_sim->devq->send_queue.qfrozen_cnt[0] != 1) {
+
+
+		if (sp->cam_sim->devq->send_queue.qfrozen_cnt[0] != 0) 
+			printf("qfrozen_cnt went to bad value %d\n",
+			    sp->cam_sim->devq->send_queue.qfrozen_cnt[0]);
+		sp->cam_sim->devq->send_queue.qfrozen_cnt[0] = 1;
+	}
+	if (sp->cam_sim->devq->send_queue.qfrozen_cnt[0] > 0)
+		xpt_release_simq(sp->cam_sim, 0);
+	else
+		printf("queue already released !!! %d\n",
+		    sp->cam_sim->devq->send_queue.qfrozen_cnt[0]);
+	sp->cam_flags &= ~ISC_QFROZEN;
 	mtx_unlock(sp->cam_sim->mtx);
+
 	return (SU_OK);
 }
 

Modified: projects/iscsi_opt/sys/dev/iscsi/initiator/iscsivar.h
==============================================================================
--- projects/iscsi_opt/sys/dev/iscsi/initiator/iscsivar.h	Fri May  4 16:25:35 2012	(r235017)
+++ projects/iscsi_opt/sys/dev/iscsi/initiator/iscsivar.h	Fri May  4 16:53:43 2012	(r235018)
@@ -199,6 +199,8 @@ typedef struct isc_session {
      struct cam_sim	*cam_sim;
      struct cam_path	*cam_path;
      struct mtx		cam_mtx;
+#define ISC_QFROZEN   0x1
+     int cam_flags;
      /*
       | sysctl stuff
       */


More information about the svn-src-projects mailing list