svn commit: r234999 - projects/iscsi_opt/sys/dev/iscsi/initiator
Kip Macy
kmacy at FreeBSD.org
Fri May 4 14:10:55 UTC 2012
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_ */
More information about the svn-src-projects
mailing list