git: 5dfe6f23d388 - stable/13 - cxgbei: Restructure how PDU limits are managed.

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Fri, 29 Oct 2021 23:58:33 UTC
The branch stable/13 has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=5dfe6f23d388c93d868257b76c2c3eff4dc1d12d

commit 5dfe6f23d388c93d868257b76c2c3eff4dc1d12d
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2021-08-17 18:14:11 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2021-10-29 23:29:08 +0000

    cxgbei: Restructure how PDU limits are managed.
    
    - Compute data segment limits in read_pdu_limits() rather than PDU
      length limits.
    
    - Add back connection-specific PDU overhead lengths to compute PDU
      length limits in icl_cxgbei_conn_handoff().
    
    Reviewed by:    np
    Sponsored by:   Chelsio Communications
    Differential Revision:  https://reviews.freebsd.org/D31574
    
    (cherry picked from commit cbc186360c658eda884ed97f37cdc2d1b6512b91)
---
 sys/dev/cxgbe/cxgbei/cxgbei.c     | 19 ++++++++++++++-----
 sys/dev/cxgbe/cxgbei/cxgbei.h     |  4 ++--
 sys/dev/cxgbe/cxgbei/icl_cxgbei.c | 30 ++++++++++++++++++------------
 3 files changed, 34 insertions(+), 19 deletions(-)

diff --git a/sys/dev/cxgbe/cxgbei/cxgbei.c b/sys/dev/cxgbe/cxgbei/cxgbei.c
index 5cce7d3fce05..24187c862fe6 100644
--- a/sys/dev/cxgbe/cxgbei/cxgbei.c
+++ b/sys/dev/cxgbe/cxgbei/cxgbei.c
@@ -97,8 +97,8 @@ static struct cxgbei_worker_thread_softc *cwt_softc;
 static struct proc *cxgbei_proc;
 
 static void
-read_pdu_limits(struct adapter *sc, uint32_t *max_tx_pdu_len,
-    uint32_t *max_rx_pdu_len)
+read_pdu_limits(struct adapter *sc, uint32_t *max_tx_data_len,
+    uint32_t *max_rx_data_len)
 {
 	uint32_t tx_len, rx_len, r, v;
 
@@ -114,8 +114,17 @@ read_pdu_limits(struct adapter *sc, uint32_t *max_tx_pdu_len,
 	rx_len = min(rx_len, v);
 	tx_len = min(tx_len, v);
 
-	*max_tx_pdu_len = rounddown2(tx_len, 512);
-	*max_rx_pdu_len = rounddown2(rx_len, 512);
+	/*
+	 * AHS is not supported by the kernel so we'll not account for
+	 * it either in our PDU len -> data segment len conversions.
+	 */
+	rx_len -= ISCSI_BHS_SIZE + ISCSI_HEADER_DIGEST_SIZE +
+	    ISCSI_DATA_DIGEST_SIZE;
+	tx_len -= ISCSI_BHS_SIZE + ISCSI_HEADER_DIGEST_SIZE +
+	    ISCSI_DATA_DIGEST_SIZE;
+
+	*max_tx_data_len = rounddown2(tx_len, 512);
+	*max_rx_data_len = rounddown2(rx_len, 512);
 }
 
 /*
@@ -135,7 +144,7 @@ cxgbei_init(struct adapter *sc, struct cxgbei_data *ci)
 	MPASS(sc->vres.iscsi.size > 0);
 	MPASS(ci != NULL);
 
-	read_pdu_limits(sc, &ci->max_tx_pdu_len, &ci->max_rx_pdu_len);
+	read_pdu_limits(sc, &ci->max_tx_data_len, &ci->max_rx_data_len);
 
 	pr = &ci->pr;
 	r = t4_read_reg(sc, A_ULP_RX_ISCSI_PSZ);
diff --git a/sys/dev/cxgbe/cxgbei/cxgbei.h b/sys/dev/cxgbe/cxgbei/cxgbei.h
index 433f15b743fe..20754fa893a8 100644
--- a/sys/dev/cxgbe/cxgbei/cxgbei.h
+++ b/sys/dev/cxgbe/cxgbei/cxgbei.h
@@ -125,8 +125,8 @@ ip_to_icp(struct icl_pdu *ip)
 }
 
 struct cxgbei_data {
-	u_int max_tx_pdu_len;
-	u_int max_rx_pdu_len;
+	u_int max_tx_data_len;
+	u_int max_rx_data_len;
 
 	u_int ddp_threshold;
 	struct ppod_region pr;
diff --git a/sys/dev/cxgbe/cxgbei/icl_cxgbei.c b/sys/dev/cxgbe/cxgbei/icl_cxgbei.c
index 5526388915f7..a6e7f8b95815 100644
--- a/sys/dev/cxgbe/cxgbei/icl_cxgbei.c
+++ b/sys/dev/cxgbe/cxgbei/icl_cxgbei.c
@@ -783,6 +783,7 @@ icl_cxgbei_conn_handoff(struct icl_conn *ic, int fd)
 	struct tcpcb *tp;
 	struct toepcb *toep;
 	cap_rights_t rights;
+	u_int max_rx_pdu_len, max_tx_pdu_len;
 	int error, max_iso_pdus;
 
 	MPASS(icc->icc_signature == CXGBEI_CONN_SIGNATURE);
@@ -828,6 +829,17 @@ icl_cxgbei_conn_handoff(struct icl_conn *ic, int fd)
 	icc->sc = fa.sc;
 	ci = icc->sc->iscsi_ulp_softc;
 
+	max_rx_pdu_len = ISCSI_BHS_SIZE + ic->ic_max_recv_data_segment_length;
+	max_tx_pdu_len = ISCSI_BHS_SIZE + ic->ic_max_send_data_segment_length;
+	if (ic->ic_header_crc32c) {
+		max_rx_pdu_len += ISCSI_HEADER_DIGEST_SIZE;
+		max_tx_pdu_len += ISCSI_HEADER_DIGEST_SIZE;
+	}
+	if (ic->ic_data_crc32c) {
+		max_rx_pdu_len += ISCSI_DATA_DIGEST_SIZE;
+		max_tx_pdu_len += ISCSI_DATA_DIGEST_SIZE;
+	}
+
 	inp = sotoinpcb(so);
 	INP_WLOCK(inp);
 	tp = intotcpcb(inp);
@@ -853,7 +865,7 @@ icl_cxgbei_conn_handoff(struct icl_conn *ic, int fd)
 
 		if (icc->sc->tt.iso && chip_id(icc->sc) >= CHELSIO_T5) {
 			max_iso_pdus = CXGBEI_MAX_ISO_PAYLOAD /
-			    ci->max_tx_pdu_len;
+			    max_tx_pdu_len;
 			ic->ic_hw_isomax = max_iso_pdus *
 			    ic->ic_max_send_data_segment_length;
 		} else
@@ -864,15 +876,15 @@ icl_cxgbei_conn_handoff(struct icl_conn *ic, int fd)
 		toep->ulpcb = icc;
 
 		send_iscsi_flowc_wr(icc->sc, toep,
-		    roundup(max_iso_pdus * ci->max_tx_pdu_len, tp->t_maxseg));
+		    roundup(max_iso_pdus * max_tx_pdu_len, tp->t_maxseg));
 		set_ulp_mode_iscsi(icc->sc, toep, icc->ulp_submode);
 		error = 0;
 	}
 	INP_WUNLOCK(inp);
 
 	if (error == 0) {
-		error = icl_cxgbei_setsockopt(ic, so, ci->max_tx_pdu_len,
-		    ci->max_rx_pdu_len);
+		error = icl_cxgbei_setsockopt(ic, so, max_tx_pdu_len,
+		    max_rx_pdu_len);
 	}
 
 	return (error);
@@ -1378,18 +1390,12 @@ cxgbei_limits(struct adapter *sc, void *arg)
 		ci = sc->iscsi_ulp_softc;
 		MPASS(ci != NULL);
 
-		/*
-		 * AHS is not supported by the kernel so we'll not account for
-		 * it either in our PDU len -> data segment len conversions.
-		 */
 
-		max_dsl = ci->max_rx_pdu_len - ISCSI_BHS_SIZE -
-		    ISCSI_HEADER_DIGEST_SIZE - ISCSI_DATA_DIGEST_SIZE;
+		max_dsl = ci->max_rx_data_len;
 		if (idl->idl_max_recv_data_segment_length > max_dsl)
 			idl->idl_max_recv_data_segment_length = max_dsl;
 
-		max_dsl = ci->max_tx_pdu_len - ISCSI_BHS_SIZE -
-		    ISCSI_HEADER_DIGEST_SIZE - ISCSI_DATA_DIGEST_SIZE;
+		max_dsl = ci->max_tx_data_len;
 		if (idl->idl_max_send_data_segment_length > max_dsl)
 			idl->idl_max_send_data_segment_length = max_dsl;
 	}