svn commit: r278397 - in head/sys: cam/ctl dev/iscsi
Edward Tomasz Napierala
trasz at FreeBSD.org
Sun Feb 8 19:15:16 UTC 2015
Author: trasz
Date: Sun Feb 8 19:15:14 2015
New Revision: 278397
URL: https://svnweb.freebsd.org/changeset/base/278397
Log:
Extend ICL to add receive offload methods. For software ICL backend
they are no-ops.
MFC after: 1 month
Sponsored by: The FreeBSD Foundation
Modified:
head/sys/cam/ctl/ctl_frontend_iscsi.c
head/sys/cam/ctl/ctl_frontend_iscsi.h
head/sys/dev/iscsi/icl_conn_if.m
head/sys/dev/iscsi/icl_soft.c
head/sys/dev/iscsi/icl_wrappers.h
head/sys/dev/iscsi/iscsi.c
head/sys/dev/iscsi/iscsi.h
Modified: head/sys/cam/ctl/ctl_frontend_iscsi.c
==============================================================================
--- head/sys/cam/ctl/ctl_frontend_iscsi.c Sun Feb 8 19:12:38 2015 (r278396)
+++ head/sys/cam/ctl/ctl_frontend_iscsi.c Sun Feb 8 19:15:14 2015 (r278397)
@@ -164,6 +164,12 @@ static void cfiscsi_pdu_handle_task_requ
static void cfiscsi_pdu_handle_data_out(struct icl_pdu *request);
static void cfiscsi_pdu_handle_logout_request(struct icl_pdu *request);
static void cfiscsi_session_terminate(struct cfiscsi_session *cs);
+static struct cfiscsi_data_wait *cfiscsi_data_wait_new(
+ struct cfiscsi_session *cs, union ctl_io *io,
+ uint32_t initiator_task_tag,
+ uint32_t *target_transfer_tagp);
+static void cfiscsi_data_wait_free(struct cfiscsi_session *cs,
+ struct cfiscsi_data_wait *cdw);
static struct cfiscsi_target *cfiscsi_target_find(struct cfiscsi_softc
*softc, const char *name, uint16_t tag);
static struct cfiscsi_target *cfiscsi_target_find_or_create(
@@ -929,7 +935,7 @@ cfiscsi_pdu_handle_data_out(struct icl_p
CFISCSI_SESSION_UNLOCK(cs);
done = (io->scsiio.ext_data_filled != cdw->cdw_r2t_end ||
io->scsiio.ext_data_filled == io->scsiio.kern_data_len);
- uma_zfree(cfiscsi_data_wait_zone, cdw);
+ cfiscsi_data_wait_free(cs, cdw);
if (done)
io->scsiio.be_move_done(io);
else
@@ -1067,6 +1073,45 @@ cfiscsi_callout(void *context)
cfiscsi_pdu_queue(cp);
}
+static struct cfiscsi_data_wait *
+cfiscsi_data_wait_new(struct cfiscsi_session *cs, union ctl_io *io,
+ uint32_t initiator_task_tag, uint32_t *target_transfer_tagp)
+{
+ struct cfiscsi_data_wait *cdw;
+ int error;
+
+ cdw = uma_zalloc(cfiscsi_data_wait_zone, M_NOWAIT | M_ZERO);
+ if (cdw == NULL) {
+ CFISCSI_SESSION_WARN(cs,
+ "failed to allocate %zd bytes", sizeof(*cdw));
+ return (NULL);
+ }
+
+ error = icl_conn_transfer_setup(cs->cs_conn, io, target_transfer_tagp,
+ &cdw->cdw_icl_prv);
+ if (error != 0) {
+ CFISCSI_SESSION_WARN(cs,
+ "icl_conn_transfer_setup() failed with error %d", error);
+ uma_zfree(cfiscsi_data_wait_zone, cdw);
+ return (NULL);
+ }
+
+ cdw->cdw_ctl_io = io;
+ cdw->cdw_target_transfer_tag = *target_transfer_tagp;
+ cdw->cdw_initiator_task_tag = initiator_task_tag;
+
+ return (cdw);
+}
+
+static void
+cfiscsi_data_wait_free(struct cfiscsi_session *cs,
+ struct cfiscsi_data_wait *cdw)
+{
+
+ icl_conn_transfer_done(cs->cs_conn, cdw->cdw_icl_prv);
+ uma_zfree(cfiscsi_data_wait_zone, cdw);
+}
+
static void
cfiscsi_session_terminate_tasks(struct cfiscsi_session *cs)
{
@@ -1106,7 +1151,7 @@ cfiscsi_session_terminate_tasks(struct c
*/
cdw->cdw_ctl_io->scsiio.io_hdr.port_status = 42;
cdw->cdw_ctl_io->scsiio.be_move_done(cdw->cdw_ctl_io);
- uma_zfree(cfiscsi_data_wait_zone, cdw);
+ cfiscsi_data_wait_free(cs, cdw);
CFISCSI_SESSION_LOCK(cs);
}
CFISCSI_SESSION_UNLOCK(cs);
@@ -2600,13 +2645,8 @@ cfiscsi_datamove_out(union ctl_io *io)
target_transfer_tag =
atomic_fetchadd_32(&cs->cs_target_transfer_tag, 1);
-
-#if 0
- CFISCSI_SESSION_DEBUG(cs, "expecting Data-Out with initiator "
- "task tag 0x%x, target transfer tag 0x%x",
- bhssc->bhssc_initiator_task_tag, target_transfer_tag);
-#endif
- cdw = uma_zalloc(cfiscsi_data_wait_zone, M_NOWAIT | M_ZERO);
+ cdw = cfiscsi_data_wait_new(cs, io, bhssc->bhssc_initiator_task_tag,
+ &target_transfer_tag);
if (cdw == NULL) {
CFISCSI_SESSION_WARN(cs, "failed to "
"allocate memory; dropping connection");
@@ -2615,6 +2655,12 @@ cfiscsi_datamove_out(union ctl_io *io)
cfiscsi_session_terminate(cs);
return;
}
+#if 0
+ CFISCSI_SESSION_DEBUG(cs, "expecting Data-Out with initiator "
+ "task tag 0x%x, target transfer tag 0x%x",
+ bhssc->bhssc_initiator_task_tag, target_transfer_tag);
+#endif
+
cdw->cdw_ctl_io = io;
cdw->cdw_target_transfer_tag = target_transfer_tag;
cdw->cdw_initiator_task_tag = bhssc->bhssc_initiator_task_tag;
@@ -2651,7 +2697,7 @@ cfiscsi_datamove_out(union ctl_io *io)
icl_pdu_data_segment_length(request)) {
done = cfiscsi_handle_data_segment(request, cdw);
if (done) {
- uma_zfree(cfiscsi_data_wait_zone, cdw);
+ cfiscsi_data_wait_free(cs, cdw);
io->scsiio.be_move_done(io);
return;
}
@@ -2854,7 +2900,7 @@ cfiscsi_task_management_done(union ctl_i
TAILQ_REMOVE(&cs->cs_waiting_for_data_out,
cdw, cdw_next);
cdw->cdw_ctl_io->scsiio.be_move_done(cdw->cdw_ctl_io);
- uma_zfree(cfiscsi_data_wait_zone, cdw);
+ cfiscsi_data_wait_free(cs, cdw);
}
CFISCSI_SESSION_UNLOCK(cs);
}
Modified: head/sys/cam/ctl/ctl_frontend_iscsi.h
==============================================================================
--- head/sys/cam/ctl/ctl_frontend_iscsi.h Sun Feb 8 19:12:38 2015 (r278396)
+++ head/sys/cam/ctl/ctl_frontend_iscsi.h Sun Feb 8 19:15:14 2015 (r278397)
@@ -59,6 +59,7 @@ struct cfiscsi_data_wait {
size_t cdw_sg_len;
uint32_t cdw_r2t_end;
uint32_t cdw_datasn;
+ void *cdw_icl_prv;
};
#define CFISCSI_SESSION_STATE_INVALID 0
Modified: head/sys/dev/iscsi/icl_conn_if.m
==============================================================================
--- head/sys/dev/iscsi/icl_conn_if.m Sun Feb 8 19:12:38 2015 (r278396)
+++ head/sys/dev/iscsi/icl_conn_if.m Sun Feb 8 19:15:14 2015 (r278397)
@@ -85,3 +85,27 @@ METHOD void close {
METHOD bool connected {
struct icl_conn *_ic;
};
+
+METHOD int task_setup {
+ struct icl_conn *_ic;
+ struct ccb_scsiio *_csio;
+ uint32_t *_task_tag;
+ void **_prvp;
+};
+
+METHOD void task_done {
+ struct icl_conn *_ic;
+ void *_prv;
+};
+
+METHOD int transfer_setup {
+ struct icl_conn *_ic;
+ union ctl_io *_io;
+ uint32_t *_transfer_tag;
+ void **_prvp;
+};
+
+METHOD void transfer_done {
+ struct icl_conn *_ic;
+ void *_prv;
+};
Modified: head/sys/dev/iscsi/icl_soft.c
==============================================================================
--- head/sys/dev/iscsi/icl_soft.c Sun Feb 8 19:12:38 2015 (r278396)
+++ head/sys/dev/iscsi/icl_soft.c Sun Feb 8 19:15:14 2015 (r278397)
@@ -98,6 +98,10 @@ static icl_conn_handoff_t icl_soft_conn_
static icl_conn_free_t icl_soft_conn_free;
static icl_conn_close_t icl_soft_conn_close;
static icl_conn_connected_t icl_soft_conn_connected;
+static icl_conn_task_setup_t icl_soft_conn_task_setup;
+static icl_conn_task_done_t icl_soft_conn_task_done;
+static icl_conn_transfer_setup_t icl_soft_conn_transfer_setup;
+static icl_conn_transfer_done_t icl_soft_conn_transfer_done;
static kobj_method_t icl_soft_methods[] = {
KOBJMETHOD(icl_conn_new_pdu, icl_soft_conn_new_pdu),
@@ -111,6 +115,10 @@ static kobj_method_t icl_soft_methods[]
KOBJMETHOD(icl_conn_free, icl_soft_conn_free),
KOBJMETHOD(icl_conn_close, icl_soft_conn_close),
KOBJMETHOD(icl_conn_connected, icl_soft_conn_connected),
+ KOBJMETHOD(icl_conn_task_setup, icl_soft_conn_task_setup),
+ KOBJMETHOD(icl_conn_task_done, icl_soft_conn_task_done),
+ KOBJMETHOD(icl_conn_transfer_setup, icl_soft_conn_transfer_setup),
+ KOBJMETHOD(icl_conn_transfer_done, icl_soft_conn_transfer_done),
{ 0, 0 }
};
@@ -1435,6 +1443,32 @@ icl_soft_conn_connected(struct icl_conn
return (true);
}
+int
+icl_soft_conn_task_setup(struct icl_conn *ic, struct ccb_scsiio *csio,
+ uint32_t *task_tagp, void **prvp)
+{
+
+ return (0);
+}
+
+void
+icl_soft_conn_task_done(struct icl_conn *ic, void *prv)
+{
+}
+
+int
+icl_soft_conn_transfer_setup(struct icl_conn *ic, union ctl_io *io,
+ uint32_t *transfer_tag, void **prvp)
+{
+
+ return (0);
+}
+
+void
+icl_soft_conn_transfer_done(struct icl_conn *ic, void *prv)
+{
+}
+
static int
icl_soft_limits(size_t *limitp)
{
Modified: head/sys/dev/iscsi/icl_wrappers.h
==============================================================================
--- head/sys/dev/iscsi/icl_wrappers.h Sun Feb 8 19:12:38 2015 (r278396)
+++ head/sys/dev/iscsi/icl_wrappers.h Sun Feb 8 19:15:14 2015 (r278397)
@@ -112,4 +112,34 @@ icl_conn_connected(struct icl_conn *ic)
return (ICL_CONN_CONNECTED(ic));
}
+static inline int
+icl_conn_task_setup(struct icl_conn *ic, struct ccb_scsiio *csio,
+ uint32_t *task_tagp, void **prvp)
+{
+
+ return (ICL_CONN_TASK_SETUP(ic, csio, task_tagp, prvp));
+}
+
+static inline void
+icl_conn_task_done(struct icl_conn *ic, void *prv)
+{
+
+ ICL_CONN_TASK_DONE(ic, prv);
+}
+
+static inline int
+icl_conn_transfer_setup(struct icl_conn *ic, union ctl_io *io,
+ uint32_t *transfer_tagp, void **prvp)
+{
+
+ return (ICL_CONN_TRANSFER_SETUP(ic, io, transfer_tagp, prvp));
+}
+
+static inline void
+icl_conn_transfer_done(struct icl_conn *ic, void *prv)
+{
+
+ ICL_CONN_TRANSFER_DONE(ic, prv);
+}
+
#endif /* !ICL_WRAPPERS_H */
Modified: head/sys/dev/iscsi/iscsi.c
==============================================================================
--- head/sys/dev/iscsi/iscsi.c Sun Feb 8 19:12:38 2015 (r278396)
+++ head/sys/dev/iscsi/iscsi.c Sun Feb 8 19:15:14 2015 (r278397)
@@ -169,7 +169,7 @@ static void iscsi_poll(struct cam_sim *s
static struct iscsi_outstanding *iscsi_outstanding_find(struct iscsi_session *is,
uint32_t initiator_task_tag);
static struct iscsi_outstanding *iscsi_outstanding_add(struct iscsi_session *is,
- uint32_t initiator_task_tag, union ccb *ccb);
+ union ccb *ccb, uint32_t *initiator_task_tagp);
static void iscsi_outstanding_remove(struct iscsi_session *is,
struct iscsi_outstanding *io);
@@ -1993,21 +1993,33 @@ iscsi_outstanding_find_ccb(struct iscsi_
static struct iscsi_outstanding *
iscsi_outstanding_add(struct iscsi_session *is,
- uint32_t initiator_task_tag, union ccb *ccb)
+ union ccb *ccb, uint32_t *initiator_task_tagp)
{
struct iscsi_outstanding *io;
+ int error;
ISCSI_SESSION_LOCK_ASSERT(is);
- KASSERT(iscsi_outstanding_find(is, initiator_task_tag) == NULL,
- ("initiator_task_tag 0x%x already added", initiator_task_tag));
-
io = uma_zalloc(iscsi_outstanding_zone, M_NOWAIT | M_ZERO);
if (io == NULL) {
- ISCSI_SESSION_WARN(is, "failed to allocate %zd bytes", sizeof(*io));
+ ISCSI_SESSION_WARN(is, "failed to allocate %zd bytes",
+ sizeof(*io));
+ return (NULL);
+ }
+
+ error = icl_conn_task_setup(is->is_conn, &ccb->csio,
+ initiator_task_tagp, &io->io_icl_prv);
+ if (error != 0) {
+ ISCSI_SESSION_WARN(is,
+ "icl_conn_task_setup() failed with error %d", error);
+ uma_zfree(iscsi_outstanding_zone, io);
return (NULL);
}
- io->io_initiator_task_tag = initiator_task_tag;
+
+ KASSERT(iscsi_outstanding_find(is, *initiator_task_tagp) == NULL,
+ ("initiator_task_tag 0x%x already added", *initiator_task_tagp));
+
+ io->io_initiator_task_tag = *initiator_task_tagp;
io->io_ccb = ccb;
TAILQ_INSERT_TAIL(&is->is_outstanding, io, io_next);
return (io);
@@ -2019,6 +2031,7 @@ iscsi_outstanding_remove(struct iscsi_se
ISCSI_SESSION_LOCK_ASSERT(is);
+ icl_conn_task_done(is->is_conn, io->io_icl_prv);
TAILQ_REMOVE(&is->is_outstanding, io, io_next);
uma_zfree(iscsi_outstanding_zone, io);
}
@@ -2030,6 +2043,7 @@ iscsi_action_abort(struct iscsi_session
struct iscsi_bhs_task_management_request *bhstmr;
struct ccb_abort *cab = &ccb->cab;
struct iscsi_outstanding *io, *aio;
+ uint32_t initiator_task_tag;
ISCSI_SESSION_LOCK_ASSERT(is);
@@ -2057,16 +2071,9 @@ iscsi_action_abort(struct iscsi_session
return;
}
- bhstmr = (struct iscsi_bhs_task_management_request *)request->ip_bhs;
- bhstmr->bhstmr_opcode = ISCSI_BHS_OPCODE_TASK_REQUEST;
- bhstmr->bhstmr_function = 0x80 | BHSTMR_FUNCTION_ABORT_TASK;
-
- bhstmr->bhstmr_lun = htobe64(CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun));
- bhstmr->bhstmr_initiator_task_tag = is->is_initiator_task_tag;
- is->is_initiator_task_tag++;
- bhstmr->bhstmr_referenced_task_tag = aio->io_initiator_task_tag;
+ initiator_task_tag = is->is_initiator_task_tag++;
- io = iscsi_outstanding_add(is, bhstmr->bhstmr_initiator_task_tag, NULL);
+ io = iscsi_outstanding_add(is, NULL, &initiator_task_tag);
if (io == NULL) {
icl_pdu_free(request);
ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
@@ -2074,6 +2081,14 @@ iscsi_action_abort(struct iscsi_session
return;
}
io->io_datasn = aio->io_initiator_task_tag;
+
+ bhstmr = (struct iscsi_bhs_task_management_request *)request->ip_bhs;
+ bhstmr->bhstmr_opcode = ISCSI_BHS_OPCODE_TASK_REQUEST;
+ bhstmr->bhstmr_function = 0x80 | BHSTMR_FUNCTION_ABORT_TASK;
+ bhstmr->bhstmr_lun = htobe64(CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun));
+ bhstmr->bhstmr_initiator_task_tag = initiator_task_tag;
+ bhstmr->bhstmr_referenced_task_tag = aio->io_initiator_task_tag;
+
iscsi_pdu_queue_locked(request);
}
@@ -2085,6 +2100,7 @@ iscsi_action_scsiio(struct iscsi_session
struct ccb_scsiio *csio;
struct iscsi_outstanding *io;
size_t len;
+ uint32_t initiator_task_tag;
int error;
ISCSI_SESSION_LOCK_ASSERT(is);
@@ -2115,6 +2131,19 @@ iscsi_action_scsiio(struct iscsi_session
return;
}
+ initiator_task_tag = is->is_initiator_task_tag++;
+ io = iscsi_outstanding_add(is, ccb, &initiator_task_tag);
+ if (io == NULL) {
+ icl_pdu_free(request);
+ if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
+ xpt_freeze_devq(ccb->ccb_h.path, 1);
+ ISCSI_SESSION_DEBUG(is, "freezing devq");
+ }
+ ccb->ccb_h.status = CAM_RESRC_UNAVAIL | CAM_DEV_QFRZN;
+ xpt_done(ccb);
+ return;
+ }
+
csio = &ccb->csio;
bhssc = (struct iscsi_bhs_scsi_command *)request->ip_bhs;
bhssc->bhssc_opcode = ISCSI_BHS_OPCODE_SCSI_COMMAND;
@@ -2148,8 +2177,7 @@ iscsi_action_scsiio(struct iscsi_session
bhssc->bhssc_flags |= BHSSC_FLAGS_ATTR_UNTAGGED;
bhssc->bhssc_lun = htobe64(CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun));
- bhssc->bhssc_initiator_task_tag = is->is_initiator_task_tag;
- is->is_initiator_task_tag++;
+ bhssc->bhssc_initiator_task_tag = initiator_task_tag;
bhssc->bhssc_expected_data_transfer_length = htonl(csio->dxfer_len);
KASSERT(csio->cdb_len <= sizeof(bhssc->bhssc_cdb),
("unsupported CDB size %zd", (size_t)csio->cdb_len));
@@ -2159,18 +2187,6 @@ iscsi_action_scsiio(struct iscsi_session
else
memcpy(&bhssc->bhssc_cdb, csio->cdb_io.cdb_bytes, csio->cdb_len);
- io = iscsi_outstanding_add(is, bhssc->bhssc_initiator_task_tag, ccb);
- if (io == NULL) {
- icl_pdu_free(request);
- if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
- xpt_freeze_devq(ccb->ccb_h.path, 1);
- ISCSI_SESSION_DEBUG(is, "freezing devq");
- }
- ccb->ccb_h.status = CAM_RESRC_UNAVAIL | CAM_DEV_QFRZN;
- xpt_done(ccb);
- return;
- }
-
if (is->is_immediate_data &&
(csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) {
len = csio->dxfer_len;
Modified: head/sys/dev/iscsi/iscsi.h
==============================================================================
--- head/sys/dev/iscsi/iscsi.h Sun Feb 8 19:12:38 2015 (r278396)
+++ head/sys/dev/iscsi/iscsi.h Sun Feb 8 19:15:14 2015 (r278397)
@@ -45,6 +45,7 @@ struct iscsi_outstanding {
size_t io_received;
uint32_t io_initiator_task_tag;
uint32_t io_datasn;
+ void *io_icl_prv;
};
struct iscsi_session {
More information about the svn-src-all
mailing list