Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 8 Feb 2015 19:15:14 +0000 (UTC)
From:      Edward Tomasz Napierala <trasz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r278397 - in head/sys: cam/ctl dev/iscsi
Message-ID:  <201502081915.t18JFECa049956@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 {



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