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>