Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 4 May 2012 14:10:55 +0000 (UTC)
From:      Kip Macy <kmacy@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r234999 - projects/iscsi_opt/sys/dev/iscsi/initiator
Message-ID:  <201205041410.q44EAtpc006889@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kmacy
Date: Fri May  4 14:10:54 2012
New Revision: 234999
URL: http://svn.freebsd.org/changeset/base/234999

Log:
  checkpoint current iscsi changes

Added:
  projects/iscsi_opt/sys/dev/iscsi/initiator/iscsiopt.h
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/isc_soc.c
  projects/iscsi_opt/sys/dev/iscsi/initiator/isc_subr.c
  projects/iscsi_opt/sys/dev/iscsi/initiator/iscsi.c
  projects/iscsi_opt/sys/dev/iscsi/initiator/iscsi_subr.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 13:47:42 2012	(r234998)
+++ projects/iscsi_opt/sys/dev/iscsi/initiator/isc_cam.c	Fri May  4 14:10:54 2012	(r234999)
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
 
 #include "opt_iscsi_initiator.h"
 
+
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/callout.h>
@@ -45,6 +46,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/mbuf.h>
 #include <sys/uio.h>
 #include <sys/sysctl.h>
+#include <sys/socketvar.h>
 #include <sys/sx.h>
 
 #include <cam/cam.h>
@@ -54,6 +56,7 @@ __FBSDID("$FreeBSD$");
 #include <cam/cam_periph.h>
 
 #include <dev/iscsi/initiator/iscsi.h>
+#include <dev/iscsi/initiator/iscsiopt.h>
 #include <dev/iscsi/initiator/iscsivar.h>
 
 static void
@@ -74,7 +77,7 @@ _inq(struct cam_sim *sim, union ccb *ccb
      cpi->initiator_id = ISCSI_MAX_TARGETS;
      cpi->max_lun = sp->opt.maxluns - 1;
      cpi->bus_id = cam_sim_bus(sim);
-     cpi->base_transfer_speed = 3300; // 40000; // XXX:
+     cpi->base_transfer_speed = 3300000; // 40000; // XXX:
      strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
      strncpy(cpi->hba_vid, "iSCSI", HBA_IDLEN);
      strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
@@ -197,10 +200,25 @@ ic_action(struct cam_sim *sim, union ccb
 	  return;
      }	  
      switch(ccb_h->func_code) {
-     case XPT_PATH_INQ:
-	  _inq(sim, ccb);
-	  break;
+     case XPT_PATH_INQ:       
+     {
+	     struct ccb_pathinq *cpi = &ccb->cpi;
 
+	     _inq(sim, ccb);
+	     cpi->version_num = 1;
+	     cpi->target_sprt = 0;
+	     cpi->hba_misc = 0;
+	     cpi->unit_number = cam_sim_unit(sim);
+	     cpi->bus_id = cam_sim_bus(sim);
+	     cpi->base_transfer_speed = 132 * 1024;	/* XXX what to set this to? */
+	     cpi->transport = XPORT_SPI;
+	     cpi->transport_version = 2;
+	     cpi->protocol = PROTO_SCSI;
+	     cpi->protocol_version = SCSI_REV_2;
+	     cpi->maxio = 128*PAGE_SIZE;
+	     ccb->ccb_h.status = CAM_REQ_CMP;
+	     break;
+     }
      case XPT_RESET_BUS: // (can just be a stub that does nothing and completes)
      {
 	  struct ccb_pathinq *cpi = &ccb->cpi;
@@ -213,6 +231,7 @@ ic_action(struct cam_sim *sim, union ccb
      case XPT_SCSI_IO: 
      {
 	  struct ccb_scsiio* csio = &ccb->csio;
+	  int status, rc;
 
 	  debug(4, "XPT_SCSI_IO cmd=0x%x", csio->cdb_io.cdb_bytes[0]);
 	  if(sp == NULL) {
@@ -225,8 +244,24 @@ ic_action(struct cam_sim *sim, union ccb
 	       ccb_h->status = CAM_LUN_INVALID;
 	       break;
 	  }
-	  if(_scsi_encap(sim, ccb) != 0)
-	       return;
+
+	  rc = _scsi_encap(sim, ccb);
+	  if (rc == 0)
+		  return;
+
+	  if (rc == EWOULDBLOCK) {
+		  if (sim->devq->send_queue.qfrozen_cnt[0] == 0) {
+			  xpt_freeze_simq(sim, 1);
+			  CAM_UNLOCK(sp);
+			  SOCKBUF_LOCK(&sp->soc->so_snd);
+			  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;
+		  break;
+	  } 
 	  break;
      }
  
@@ -268,6 +303,30 @@ ic_action(struct cam_sim *sim, union ccb
      }
 
      case XPT_GET_TRAN_SETTINGS:
+     {
+	       struct ccb_trans_settings	*cts = &ccb->cts;
+	       int				bus, target;
+	       struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi;
+	       struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi;
+	       
+	       bus = cam_sim_bus(sim);
+	       target = cts->ccb_h.target_id;
+	       
+	       debug(1, "XPT_GET_TRAN_SETTINGS %d:%d", bus, target);
+	       /* disconnect always OK */
+	       cts->protocol = PROTO_SCSI;
+	       cts->protocol_version = SCSI_REV_2;
+	       cts->transport = XPORT_SPI;
+	       cts->transport_version = 2;
+	       spi->valid = CTS_SPI_VALID_DISC;
+	       spi->flags = CTS_SPI_FLAGS_DISC_ENB;
+	       
+	       scsi->valid = CTS_SCSI_VALID_TQ;
+	       scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
+	       
+	       cts->ccb_h.status = CAM_REQ_CMP;
+	       break;
+     }
      default:
 	  ccb_h->status = CAM_REQ_INVALID;
 	  break;
@@ -348,8 +407,8 @@ ic_init(isc_session_t *sp)
 #if __FreeBSD_version >= 700000
 			 &sp->cam_mtx,
 #endif
-			 1,		// max_dev_transactions
-			 0,		// max_tagged_dev_transactions
+			 256,		// max_dev_transactions
+			 256,		// max_tagged_dev_transactions
 			 devq);
      if(sim == NULL) {
 	  cam_simq_free(devq);

Modified: projects/iscsi_opt/sys/dev/iscsi/initiator/isc_sm.c
==============================================================================
--- projects/iscsi_opt/sys/dev/iscsi/initiator/isc_sm.c	Fri May  4 13:47:42 2012	(r234998)
+++ projects/iscsi_opt/sys/dev/iscsi/initiator/isc_sm.c	Fri May  4 14:10:54 2012	(r234999)
@@ -49,7 +49,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/protosw.h>
 #include <sys/proc.h>
 #include <sys/ioccom.h>
-#include <sys/queue.h>
 #include <sys/kthread.h>
 #include <sys/syslog.h>
 #include <sys/mbuf.h>
@@ -63,8 +62,35 @@ __FBSDID("$FreeBSD$");
 #include <cam/cam_periph.h>
 
 #include <dev/iscsi/initiator/iscsi.h>
+#include <dev/iscsi/initiator/iscsiopt.h>
 #include <dev/iscsi/initiator/iscsivar.h>
 
+static int proc_out(isc_session_t *sp);
+
+void
+pdu_free(struct isc_softc *isc, pduq_t *pq)
+{
+	KASSERT(pq->pq_link.tqe_next == NULL ||
+	    pq->pq_link.tqe_next == (void *) -1,
+		("tqe_next still set %p", pq->pq_link.tqe_next));
+	KASSERT(pq->pq_link.tqe_prev == NULL ||
+	    pq->pq_link.tqe_prev == (void *) -1,
+		("tqe_prev still set %p", pq->pq_link.tqe_prev));
+     if(pq->mp)
+	  m_freem(pq->mp);
+#ifdef NO_USE_MBUF
+     if(pq->buf != NULL)
+	  free(pq->buf, M_ISCSIBUF);
+#endif
+     uma_zfree(isc->pdu_zone, pq);
+#ifdef ISCSI_INITIATOR_DEBUG
+     mtx_lock(&iscsi_dbg_mtx);
+     isc->npdu_alloc--;
+     mtx_unlock(&iscsi_dbg_mtx);
+#endif
+}
+
+
 static void
 _async(isc_session_t *sp, pduq_t *pq)
 {
@@ -112,7 +138,7 @@ _r2t(isc_session_t *sp, pduq_t *pq)
      debug_called(8);
      opq = i_search_hld(sp, pq->pdu.ipdu.bhs.itt, 1);
      if(opq != NULL) {
-	  iscsi_r2t(sp, opq, pq);
+	 iscsi_r2t(sp, opq, pq);
      } 
      else {
 	  r2t_t		*r2t = &pq->pdu.ipdu.r2t;
@@ -188,7 +214,6 @@ _nop_out(isc_session_t *sp)
 	  nop_out->F = 1;
 	  if(isc_qout(sp, pq) != 0) {
 	       sdebug(1, "failed");
-	       pdu_free(sp->isc, pq);
 	  }
      }
 }
@@ -302,15 +327,67 @@ i_prepPDU(isc_session_t *sp, pduq_t *pq)
 }
 
 int
-isc_qout(isc_session_t *sp, pduq_t *pq)
+isc_sowouldblock(isc_session_t *sp, union ccb *ccb)
 {
-     int error = 0;
+	struct ccb_scsiio *csio = &ccb->csio;
+	int space_needed;
 
-     debug_called(8);
+	if (ccb == NULL) 
+		return (0);
+
+	space_needed = 256 + csio->cdb_len;
+	if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
+		space_needed += csio->dxfer_len;
+	if (space_needed > sp->soc->so_snd.sb_mbmax)
+		sp->soc->so_snd.sb_mbmax = space_needed + PAGE_SIZE;
+	if (space_needed > sp->soc->so_snd.sb_hiwat)
+		sp->soc->so_snd.sb_hiwat = space_needed + PAGE_SIZE;
+	debug(4, "space_needed=%d sbspace=%ld", 
+	    space_needed, sbspace(&sp->soc->so_snd));
+	if ((space_needed > sbspace(&sp->soc->so_snd)) &&
+	    (space_needed > sp->space_needed))
+		sp->space_needed = space_needed;
+	return (space_needed > sbspace(&sp->soc->so_snd));
+}
 
-     if(pq->len == 0 && (error = i_prepPDU(sp, pq)))
-	  return error;
 
+int
+isc_so_snd_upcall(struct socket *so, void *arg, int flags)
+{
+	isc_session_t *sp = arg;
+
+	if (sbspace(&so->so_snd) < sp->space_needed) 
+		return (SU_OK);
+
+	soupcall_clear(so, SO_SND);
+	sp->space_needed = 0;
+
+	mtx_lock(sp->cam_sim->mtx);
+	xpt_release_simq(sp->cam_sim, 0);
+	mtx_unlock(sp->cam_sim->mtx);
+	return (SU_OK);
+}
+
+int
+isc_qout(isc_session_t *sp, pduq_t *pq)
+{
+     int txed = 0, error = 0;
+
+     debug_called(8);
+	
+     if(pq->len == 0 && (error = i_prepPDU(sp, pq))) {
+	     pdu_free(sp->isc, pq);
+	     return (error);
+     }
+     if ((sp->flags & ISC_HOLD) || (sp->soc == NULL)) {
+	     pdu_free(sp->isc, pq);
+	     return (EWOULDBLOCK);
+     }
+     if (isc_sowouldblock(sp, pq->ccb)) {
+	     pdu_free(sp->isc, pq);
+	     return (EWOULDBLOCK);
+     }
+	     
      if(pq->pdu.ipdu.bhs.I)
 	  i_nqueue_isnd(sp, pq);
      else
@@ -321,12 +398,16 @@ isc_qout(isc_session_t *sp, pduq_t *pq)
 
      sdebug(5, "enqued: pq=%p", pq);
 
-     mtx_lock(&sp->io_mtx);
-     sp->flags |= ISC_OQNOTEMPTY;
-     if(sp->flags & ISC_OWAITING)
-	  wakeup(&sp->flags);
-     mtx_unlock(&sp->io_mtx);
-
+     if (sx_try_xlock(&sp->tx_sx)) {
+	     error = proc_out(sp);
+	     txed = 1;
+	     sx_xunlock(&sp->tx_sx);
+     }
+     if (txed == 0) {
+	     mtx_lock(&sp->io_mtx);
+	     sp->flags |= ISC_OQNOTEMPTY;
+	     mtx_unlock(&sp->io_mtx);
+     }
      return error;
 }
 /*
@@ -425,11 +506,12 @@ proc_out(isc_session_t *sp)
 {
      sn_t	*sn = &sp->sn;
      pduq_t	*pq;
-     int	error, which;
+     int	error, which, flags;
 
      debug_called(8);
      error = 0;
 
+restart:
      while(sp->flags & ISC_LINK_UP) {
 	  pdu_t *pp;
 	  bhs_t	*bhs;
@@ -509,15 +591,26 @@ proc_out(isc_session_t *sp)
 	       default:
 		    if(pq->ccb) {
 			 xdebug("back to cam");
-			 pq->ccb->ccb_h.status |= CAM_REQUEUE_REQ; // some better error?
-			 XPT_DONE(sp, pq->ccb);
-			 pdu_free(sp->isc, pq);
+			 if (error == ENOBUFS || error == EHOSTUNREACH || 
+			     error == EPIPE || error == ENETDOWN)
+			   error = EWOULDBLOCK;
+			 return (error);
 		    }
 		    else
 			 xdebug("we lost it!");
 	       }
 	  }
      }
+     if (error == 0) {
+	     mtx_lock(&sp->io_mtx);
+	     flags = sp->flags;
+	     sp->flags &= ~ISC_OQNOTEMPTY;
+	     mtx_unlock(&sp->io_mtx);
+	     if ((flags & (ISC_LINK_UP|ISC_OQNOTEMPTY)) == 
+		 (ISC_LINK_UP|ISC_OQNOTEMPTY))
+		     goto restart;
+     }  
+
      return error;
 }
 
@@ -535,12 +628,16 @@ ism_out(void *vp)
      sp->flags |= ISC_SM_RUNNING;
      sdebug(3, "started sp->flags=%x", sp->flags);
      do {
-	  if((sp->flags & ISC_HOLD) == 0) {
-	       error = proc_out(sp);
-	       if(error) {
-		    sdebug(3, "error=%d", error);
-	       }
-	  }
+         if((sp->flags & ISC_HOLD) == 0) {
+		 error = 0;
+		 if (sx_try_xlock(&sp->tx_sx)) {
+			 error = proc_out(sp);
+			 sx_xunlock(&sp->tx_sx);
+		 }
+	      if(error) {
+		   sdebug(3, "error=%d", error);
+	      }
+	 }
 	  mtx_lock(&sp->io_mtx);
 	  if((sp->flags & ISC_LINK_UP) == 0) {
 	       sdebug(3, "ISC_LINK_UP==0, sp->flags=%x ", sp->flags);
@@ -548,7 +645,6 @@ ism_out(void *vp)
 		    sdebug(3, "so_state=%x", sp->soc->so_state);
 	       wakeup(&sp->soc);
 	  }
-
 	  if(!(sp->flags & ISC_OQNOTEMPTY)) {
 	       sp->flags |= ISC_OWAITING;
 	       if(msleep(&sp->flags, &sp->io_mtx, PRIBIO, "isc_proc", hz*30) == EWOULDBLOCK) {
@@ -743,6 +839,7 @@ ism_stop(isc_session_t *sp)
      mtx_destroy(&sp->hld_mtx);
      mtx_destroy(&sp->snd_mtx);
      mtx_destroy(&sp->io_mtx);
+     sx_destroy(&sp->tx_sx);
 
      i_freeopt(&sp->opt);
 
@@ -771,6 +868,7 @@ ism_start(isc_session_t *sp)
      mtx_init(&sp->snd_mtx, "iscsi-snd", NULL, MTX_DEF);
      mtx_init(&sp->hld_mtx, "iscsi-hld", NULL, MTX_DEF);
      mtx_init(&sp->io_mtx, "iscsi-io", NULL, MTX_DEF);
+     sx_init(&sp->tx_sx, "iscsi-tx");
 
      isc_add_sysctls(sp);
 

Modified: projects/iscsi_opt/sys/dev/iscsi/initiator/isc_soc.c
==============================================================================
--- projects/iscsi_opt/sys/dev/iscsi/initiator/isc_soc.c	Fri May  4 13:47:42 2012	(r234998)
+++ projects/iscsi_opt/sys/dev/iscsi/initiator/isc_soc.c	Fri May  4 14:10:54 2012	(r234999)
@@ -47,7 +47,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/protosw.h>
 #include <sys/proc.h>
 #include <sys/ioccom.h>
-#include <sys/queue.h>
 #include <sys/kthread.h>
 #include <sys/syslog.h>
 #include <sys/mbuf.h>
@@ -57,6 +56,7 @@ __FBSDID("$FreeBSD$");
 #include <cam/cam_ccb.h>
 
 #include <dev/iscsi/initiator/iscsi.h>
+#include <dev/iscsi/initiator/iscsiopt.h>
 #include <dev/iscsi/initiator/iscsivar.h>
 
 #ifndef NO_USE_MBUF
@@ -64,7 +64,6 @@ __FBSDID("$FreeBSD$");
 #endif
 
 #ifdef USE_MBUF
-static int ou_refcnt = 0;
 /*
  | function for freeing external storage for mbuf
  */
@@ -74,7 +73,7 @@ ext_free(void *a, void *b)
      pduq_t *pq = b;
 
      if(pq->buf != NULL) {
-	  debug(3, "ou_refcnt=%d a=%p b=%p", ou_refcnt, a, pq->buf);
+	  debug(3, "ext_free a=%p b=%p", a, pq->buf);
 	  free(pq->buf, M_ISCSIBUF);
 	  pq->buf = NULL;
      }
@@ -91,7 +90,9 @@ isc_sendPDU(isc_session_t *sp, pduq_t *p
      /* 
       | mbuf for the iSCSI header
       */
-     MGETHDR(mh, M_TRYWAIT, MT_DATA);
+     MGETHDR(mh, M_NOWAIT, MT_DATA);
+     if (mh == NULL) 
+       return (EAGAIN);
      mh->m_pkthdr.rcvif = NULL;
      mh->m_next = NULL;
      mh->m_len = sizeof(union ipdu_u);
@@ -126,31 +127,31 @@ isc_sendPDU(isc_session_t *sp, pduq_t *p
      mp = &mh->m_next;
      if(pp->ds_len && pq->pdu.ds_addr) {
           struct mbuf *md;
-          int	off = 0;
 
           len = pp->ds_len;
-          while(len > 0) {
-	       int l;
-
-	       MGET(md, M_TRYWAIT, MT_DATA);
-	       md->m_ext.ref_cnt = &ou_refcnt;
-	       l = min(MCLBYTES, len);
-	       debug(4, "setting ext_free(arg=%p len/l=%d/%d)", pq->buf, len, l);
-	       MEXTADD(md, pp->ds_addr + off, l, ext_free, 
+	  MGET(md, M_NOWAIT, MT_DATA);
+	  if (md == NULL) {
+		  m_freem(mh);
+		  return (EAGAIN);
+	  }
+	  debug(4, "setting ext_free(arg=%p len/l=%d/%d)", pq->buf, len, len);
+	  MEXTADD(md, pp->ds_addr, len, ext_free, 
 #if __FreeBSD_version >= 800000
-		       pp->ds_addr + off,
+		  pp->ds_addr,
 #endif
-		       pq, 0, EXT_EXTREF);
-	       md->m_len = l;
-	       md->m_next = NULL;
-	       mh->m_pkthdr.len += l;
-	       *mp = md;
-	       mp = &md->m_next;
-	       len -= l;
-	       off += l;
-          }
+		  pq, 0, EXT_MOD_TYPE);
+	  md->m_len = len;
+	  mh->m_pkthdr.len += len;
+	  md->m_next = NULL;
+	  *mp = md;
+	  mp = &md->m_next;
+
 	  if(((pp->ds_len & 03) != 0) || ISOK2DIG(sp->dataDigest, pp)) {
-	       MGET(md, M_TRYWAIT, MT_DATA);
+	       MGET(md, M_NOWAIT, MT_DATA);
+	       if (md == NULL) {
+		       m_freem(mh);
+		       return (EAGAIN);
+	       }
 	       if(pp->ds_len & 03)
 		    len = 4 - (pp->ds_len & 03);
 	       else
@@ -619,6 +620,7 @@ isc_in(void *vp)
 	       break;
 	  }
 	  else if(error == EAGAIN) {
+	    isc_in_sleep++;
 	       if(so->so_state & SS_ISCONNECTED) 
 		    // there seems to be a problem in 6.0 ...
 		    tsleep(sp, PRIBIO, "isc_soc", 2*hz);

Modified: projects/iscsi_opt/sys/dev/iscsi/initiator/isc_subr.c
==============================================================================
--- projects/iscsi_opt/sys/dev/iscsi/initiator/isc_subr.c	Fri May  4 13:47:42 2012	(r234998)
+++ projects/iscsi_opt/sys/dev/iscsi/initiator/isc_subr.c	Fri May  4 14:10:54 2012	(r234999)
@@ -49,7 +49,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/protosw.h>
 #include <sys/proc.h>
 #include <sys/ioccom.h>
-#include <sys/queue.h>
 #include <sys/kthread.h>
 #include <sys/syslog.h>
 #include <sys/mbuf.h>

Modified: projects/iscsi_opt/sys/dev/iscsi/initiator/iscsi.c
==============================================================================
--- projects/iscsi_opt/sys/dev/iscsi/initiator/iscsi.c	Fri May  4 13:47:42 2012	(r234998)
+++ projects/iscsi_opt/sys/dev/iscsi/initiator/iscsi.c	Fri May  4 14:10:54 2012	(r234999)
@@ -51,7 +51,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/protosw.h>
 #include <sys/proc.h>
 #include <sys/ioccom.h>
-#include <sys/queue.h>
 #include <sys/kthread.h>
 #include <sys/mbuf.h>
 #include <sys/syslog.h>
@@ -59,6 +58,8 @@ __FBSDID("$FreeBSD$");
 #include <sys/sx.h>
 
 #include <dev/iscsi/initiator/iscsi.h>
+
+#include <dev/iscsi/initiator/iscsiopt.h>
 #include <dev/iscsi/initiator/iscsivar.h>
 static char *iscsi_driver_version = "2.3.1";
 
@@ -83,6 +84,32 @@ static int max_pdus = MAX_PDUS;
 SYSCTL_INT(_net, OID_AUTO, iscsi_initiator_max_pdus, CTLFLAG_RDTUN, &max_pdus, MAX_PDUS,
 	   "Max pdu pool");
 
+
+static int malloc_failures = 0;
+SYSCTL_INT(_net, OID_AUTO, iscsi_malloc_failures, CTLFLAG_RD, &malloc_failures, 0,
+	   "malloc failures");
+
+int pdu_alloc_failures = 0;
+SYSCTL_INT(_net, OID_AUTO, iscsi_pdu_alloc_failures, CTLFLAG_RD, &pdu_alloc_failures, 0,
+	   "pdu allocation failures");
+
+int rx_sleep = 0;
+SYSCTL_INT(_net, OID_AUTO, iscsi_rx_sleep, CTLFLAG_RD, &rx_sleep, 0,
+	   "sleeps in rx");
+
+int isc_encap_sleep = 0;
+SYSCTL_INT(_net, OID_AUTO, iscsi_encap_sleep, CTLFLAG_RD, &isc_encap_sleep, 0,
+	   "isc_encap sleeps");
+
+int isc_r2t_sleep = 0;
+SYSCTL_INT(_net, OID_AUTO, iscsi_r2t_sleep, CTLFLAG_RD, &isc_r2t_sleep, 0,
+	   "isc_r2t sleeps");
+
+int isc_in_sleep = 0;
+SYSCTL_INT(_net, OID_AUTO, iscsi_in_sleep, CTLFLAG_RD, &isc_in_sleep, 0,
+	   "isc_in sleeps");
+
+
 static char isid[6+1] = {
      0x80,
      'D',
@@ -389,7 +416,7 @@ i_setsoc(isc_session_t *sp, int fd, stru
 
      error = fget(td, fd, CAP_SOCK_ALL, &sp->fp);
      if(error)
-	  return error;
+         return (error);
 
      if((error = fgetsock(td, fd, CAP_SOCK_ALL, &sp->soc, 0)) == 0) {
 	  sp->td = td;
@@ -400,7 +427,10 @@ i_setsoc(isc_session_t *sp, int fd, stru
 	  sp->fp = NULL;
      }
 
-     return error;
+     if (error == 0 && (sp->soc->so_snd.sb_mbmax < MINSNDBUF))
+	     sp->soc->so_snd.sb_mbmax = MINSNDBUF;
+
+     return (error);
 }
 
 static int
@@ -422,12 +452,13 @@ i_send(struct cdev *dev, caddr_t arg, st
      pp = &pq->pdu;
      pq->pdu = *(pdu_t *)arg;
      if((error = i_prepPDU(sp, pq)) != 0)
-	  goto out;
+	     goto out;
 
      bp = NULL;
      if((pq->len - sizeof(union ipdu_u)) > 0) {
 	  pq->buf = bp = malloc(pq->len - sizeof(union ipdu_u), M_ISCSIBUF, M_NOWAIT);
 	  if(pq->buf == NULL) {
+	    malloc_failures++;
 	       error = EAGAIN;
 	       goto out;
 	  }
@@ -465,12 +496,10 @@ i_send(struct cdev *dev, caddr_t arg, st
      }
 
      error = isc_qout(sp, pq);
-     if(error == 0)
-	  wakeup(&sp->flags); // XXX: to 'push' proc_out ...
+     return (error);
 out:
-     if(error)
-	  pdu_free(sp->isc, pq);
-
+     if (pq != NULL)
+	     pdu_free(sp->isc, pq);
      return error;
 }
 
@@ -494,7 +523,8 @@ i_recv(struct cdev *dev, caddr_t arg, st
      cnt = 6;     // XXX: maybe the user can request a time out?
      mtx_lock(&sp->rsp_mtx);
      while((pq = TAILQ_FIRST(&sp->rsp)) == NULL) {
-	  msleep(&sp->rsp, &sp->rsp_mtx, PRIBIO, "isc_rsp", hz*10);
+       rx_sleep++;
+	  msleep(&sp->rsp, &sp->rsp_mtx, PRIBIO, "isc_rsp", hz >> 2);
 	  if(cnt-- == 0) break; // XXX: for now, needs work
      }
      if(pq != NULL) {

Modified: projects/iscsi_opt/sys/dev/iscsi/initiator/iscsi_subr.c
==============================================================================
--- projects/iscsi_opt/sys/dev/iscsi/initiator/iscsi_subr.c	Fri May  4 13:47:42 2012	(r234998)
+++ projects/iscsi_opt/sys/dev/iscsi/initiator/iscsi_subr.c	Fri May  4 14:10:54 2012	(r234999)
@@ -52,8 +52,10 @@ __FBSDID("$FreeBSD$");
 #include <cam/cam_periph.h>
 #include <cam/scsi/scsi_message.h>
 #include <sys/eventhandler.h>
+#include <sys/socketvar.h>
 
 #include <dev/iscsi/initiator/iscsi.h>
+#include <dev/iscsi/initiator/iscsiopt.h>
 #include <dev/iscsi/initiator/iscsivar.h>
 
 /*
@@ -103,8 +105,9 @@ iscsi_r2t(isc_session_t *sp, pduq_t *opq
 
 			 while((wpq = pdu_alloc(sp->isc, M_NOWAIT)) == NULL) {
 			      sdebug(2, "waiting...");
+			      isc_r2t_sleep++;
 #if __FreeBSD_version >= 700000
-			      pause("isc_r2t", 5*hz);
+			      pause("isc_r2t", hz >> 1);
 #else
 			      tsleep(sp->isc, 0, "isc_r2t", 5*hz);
 #endif
@@ -456,12 +459,21 @@ scsi_encap(struct cam_sim *sim, union cc
      struct ccb_hdr	*ccb_h = &ccb->ccb_h;
      pduq_t		*pq;
      scsi_req_t		*cmd;
+     struct socket      *so = sp->soc;
+     int error = EINVAL;
 
      debug_called(8);
 
      debug(4, "ccb->sp=%p", ccb_h->spriv_ptr0);
      sp = ccb_h->spriv_ptr0;
 
+     if (isc_sowouldblock(sp, ccb)) {
+	     SOCKBUF_LOCK(&so->so_snd);
+	     soupcall_set(so, SO_SND, isc_so_snd_upcall, sp);
+	     SOCKBUF_UNLOCK(&so->so_snd);
+	     return (EWOULDBLOCK);
+     }
+
      if((pq = pdu_alloc(sp->isc, M_NOWAIT)) == NULL) {
 	  debug(2, "ccb->sp=%p", ccb_h->spriv_ptr0);
 	  sdebug(1, "pdu_alloc failed sc->npdu_max=%d npdu_alloc=%d",
@@ -469,6 +481,7 @@ scsi_encap(struct cam_sim *sim, union cc
 	  while((pq = pdu_alloc(sp->isc, M_NOWAIT)) == NULL) {
 	       sdebug(2, "waiting...");
 #if __FreeBSD_version >= 700000
+	       isc_encap_sleep++;
 	       pause("isc_encap", 5*hz);
 #else
 	       tsleep(sp->isc, 0, "isc_encap", 5*hz);
@@ -478,20 +491,16 @@ scsi_encap(struct cam_sim *sim, union cc
      cmd = &pq->pdu.ipdu.scsi_req;
      cmd->opcode = ISCSI_SCSI_CMD;
      cmd->F = 1;
-#if 0
-// this breaks at least Isilon's iscsi target.
-     /*
-      | map tag option, default is UNTAGGED
-      */
-     switch(csio->tag_action) {
-     case MSG_SIMPLE_Q_TAG:	cmd->attr = iSCSI_TASK_SIMPLE;	break;
-     case MSG_HEAD_OF_Q_TAG:	cmd->attr = iSCSI_TASK_HOFQ;	break;
-     case MSG_ORDERED_Q_TAG:	cmd->attr = iSCSI_TASK_ORDER;	break;
-     case MSG_ACA_TASK:		cmd->attr = iSCSI_TASK_ACA;	break;
-     }
-#else
-     cmd->attr = iSCSI_TASK_SIMPLE;
-#endif
+
+     if (ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) {
+	     switch(csio->tag_action) {
+	     case MSG_SIMPLE_Q_TAG:	cmd->attr = iSCSI_TASK_SIMPLE;	break;
+	     case MSG_HEAD_OF_Q_TAG:	cmd->attr = iSCSI_TASK_HOFQ;	break;
+	     case MSG_ORDERED_Q_TAG:	cmd->attr = iSCSI_TASK_ORDER;	break;
+	     case MSG_ACA_TASK:	        cmd->attr = iSCSI_TASK_ACA;	break;
+	     }
+     } else 
+	     cmd->attr = iSCSI_TASK_SIMPLE;
 
      dwl(sp, ccb_h->target_lun, (u_char *)&cmd->lun);
 
@@ -523,13 +532,13 @@ scsi_encap(struct cam_sim *sim, union cc
      /*
       | place it in the out queue
       */
-     if(isc_qout(sp, pq) == 0)
-	  return 1; 
+     return (isc_qout(sp, pq));
+
  invalid:
      ccb->ccb_h.status = CAM_REQ_INVALID;
      pdu_free(sp->isc, pq);
 
-     return 0;
+     return (error);
 }
 
 int

Added: projects/iscsi_opt/sys/dev/iscsi/initiator/iscsiopt.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/iscsi_opt/sys/dev/iscsi/initiator/iscsiopt.h	Fri May  4 14:10:54 2012	(r234999)
@@ -0,0 +1,4 @@
+#if 1 || defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
+#define QUEUE_MACRO_DEBUG
+#endif
+

Modified: projects/iscsi_opt/sys/dev/iscsi/initiator/iscsivar.h
==============================================================================
--- projects/iscsi_opt/sys/dev/iscsi/initiator/iscsivar.h	Fri May  4 13:47:42 2012	(r234998)
+++ projects/iscsi_opt/sys/dev/iscsi/initiator/iscsivar.h	Fri May  4 14:10:54 2012	(r234999)
@@ -26,6 +26,35 @@
  * $FreeBSD$
  */
 
+#ifndef __ISCSIVAR__H_
+#define __ISCSIVAR__H_
+
+
+#include <sys/queue.h> 
+#undef TRASHIT
+#define	TRASHIT(x)	do {(x) = (void *)-1;} while (0)
+#undef QMD_SAVELINK
+#define	QMD_SAVELINK(name, link)	void **name = (void *)&(link)
+
+#undef TAILQ_REMOVE
+#define	TAILQ_REMOVE(head, elm, field) do {				\
+	QMD_SAVELINK(oldnext, (elm)->field.tqe_next);			\
+	QMD_SAVELINK(oldprev, (elm)->field.tqe_prev);			\
+	QMD_TAILQ_CHECK_NEXT(elm, field);				\
+	QMD_TAILQ_CHECK_PREV(elm, field);				\
+	if ((TAILQ_NEXT((elm), field)) != NULL)				\
+		TAILQ_NEXT((elm), field)->field.tqe_prev = 		\
+		    (elm)->field.tqe_prev;				\
+	else {								\
+		(head)->tqh_last = (elm)->field.tqe_prev;		\
+		QMD_TRACE_HEAD(head);					\
+	}								\
+	*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);		\
+	TRASHIT(*oldnext);						\
+	TRASHIT(*oldprev);						\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+} while (0)
+
 /*
  | $Id: iscsivar.h 743 2009-08-08 10:54:53Z danny $
  */
@@ -150,6 +179,7 @@ typedef struct isc_session {
      struct mtx		snd_mtx;
      struct mtx		hld_mtx;
      struct mtx		io_mtx;
+     struct sx          tx_sx;
      queue_t		rsp;
      queue_t		rsv;
      queue_t		csnd;
@@ -175,6 +205,7 @@ typedef struct isc_session {
      struct sysctl_ctx_list	clist;
      struct sysctl_oid	*oid;
      int	douio;	//XXX: turn on/off uio on read
+	int        space_needed;
 } isc_session_t;
 
 typedef struct pduq {
@@ -218,6 +249,8 @@ struct isc_softc {
      struct sysctl_oid		*oid;
 };
 
+#define MINSNDBUF  DFLTPHYS + 8*1024
+
 #ifdef  ISCSI_INITIATOR_DEBUG
 extern struct mtx iscsi_dbg_mtx;
 #endif
@@ -225,6 +258,10 @@ extern struct mtx iscsi_dbg_mtx;
 void	isc_start_receiver(isc_session_t *sp);
 void	isc_stop_receiver(isc_session_t *sp);
 
+
+int     isc_sowouldblock(isc_session_t *sp, union ccb *ccb);
+int     isc_so_snd_upcall(struct socket *so, void *arg, int flags);
+
 int	isc_sendPDU(isc_session_t *sp, pduq_t *pq);
 int	isc_qout(isc_session_t *sp, pduq_t *pq);
 int	i_prepPDU(isc_session_t *sp, pduq_t *pq);
@@ -283,9 +320,19 @@ XPT_DONE(isc_session_t *sp, union ccb *c
 static __inline void
 XPT_DONE(isc_session_t *sp, union ccb *ccb)
 {
-     CAM_LOCK(sp);
-     xpt_done(ccb);
-     CAM_UNLOCK(sp);
+	struct ccb_scsiio* csio = &ccb->csio;
+	uint8_t *cdb;
+
+	cdb = (csio->ccb_h.flags & CAM_CDB_POINTER) ?
+		(uint8_t *)csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes;
+	if (cdb[0] == INQUIRY &&  (cdb[1] & SI_EVPD) == 0) {
+		struct scsi_inquiry_data *inq = 
+			(struct scsi_inquiry_data *)csio->data_ptr;
+		inq->flags |= SID_CmdQue;
+	}
+	CAM_LOCK(sp);
+	xpt_done(ccb);
+	CAM_UNLOCK(sp);
 }
 #else
 //__FreeBSD_version >= 600000
@@ -296,6 +343,12 @@ XPT_DONE(isc_session_t *sp, union ccb *c
 
 #endif /* _CAM_CAM_XPT_SIM_H */
 
+extern int pdu_alloc_failures;
+extern int rx_sleep;
+extern int isc_encap_sleep;
+extern int isc_r2t_sleep;
+extern int isc_in_sleep;
+
 static __inline pduq_t *
 pdu_alloc(struct isc_softc *isc, int wait)
 {
@@ -303,6 +356,7 @@ pdu_alloc(struct isc_softc *isc, int wai
 
      pq = (pduq_t *)uma_zalloc(isc->pdu_zone, wait /* M_WAITOK or M_NOWAIT*/);
      if(pq == NULL) {
+       pdu_alloc_failures++;
 	  debug(7, "out of mem");
 	  return NULL;
      }
@@ -318,22 +372,7 @@ pdu_alloc(struct isc_softc *isc, int wai
      return pq;
 }
 
-static __inline void
-pdu_free(struct isc_softc *isc, pduq_t *pq)
-{
-     if(pq->mp)
-	  m_freem(pq->mp);
-#ifdef NO_USE_MBUF
-     if(pq->buf != NULL)
-	  free(pq->buf, M_ISCSIBUF);
-#endif
-     uma_zfree(isc->pdu_zone, pq);
-#ifdef ISCSI_INITIATOR_DEBUG
-     mtx_lock(&iscsi_dbg_mtx);
-     isc->npdu_alloc--;
-     mtx_unlock(&iscsi_dbg_mtx);
-#endif
-}
+void pdu_free(struct isc_softc *isc, pduq_t *pq);
 
 static __inline void
 i_nqueue_rsp(isc_session_t *sp, pduq_t *pq)
@@ -597,3 +636,5 @@ i_mbufcopy(struct mbuf *mp, caddr_t dp, 
 	       break;
      }
 }
+
+#endif /* __ISCSIVAR__H_ */



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