Index: sys/dev/cxgbe/cxgbei/icl_cxgbei.c =================================================================== --- sys/dev/cxgbe/cxgbei/icl_cxgbei.c +++ sys/dev/cxgbe/cxgbei/icl_cxgbei.c @@ -1776,6 +1776,38 @@ } #endif +static int +cxgbei_mss_rx_limit(struct socket *so) +{ + struct inpcb *inp; + struct tcpcb *tp; + u_int limit, mss, overhead; + + inp = sotoinpcb(so); + INP_RLOCK(inp); + tp = intotcpcb(inp); + if (inp->inp_flags & (INP_DROPPED | INP_TIMEWAIT)) { + INP_RUNLOCK(inp); + return (-1); + } + + /* + * Receive cut-through in the TOE requires PDUs to fit in one + * MSS. However, we also can't request a limit lower than 512 + * per RFC 7143. Note that since this is pre-negotiation, we + * don't know if we will be using digests or not. + */ + mss = tcp_maxseg(tp); + INP_RUNLOCK(inp); + overhead = ISCSI_BHS_SIZE + ISCSI_HEADER_DIGEST_SIZE + + ISCSI_DATA_DIGEST_SIZE; + if (overhead + 512 > mss) + limit = 512; + else + limit = mss - overhead; + return (limit); +} + static int cxgbei_limits_fd(struct icl_drv_limits *idl, int fd) { @@ -1785,6 +1817,7 @@ struct adapter *sc; struct cxgbei_data *ci; cap_rights_t rights; + u_int mss_rx_limit; int error; error = fget(curthread, fd, @@ -1810,6 +1843,11 @@ fdrop(fp, curthread); return (ENXIO); } + mss_rx_limit = cxgbei_mss_rx_limit(so); + if (mss_rx_limit <= 0) { + fdrop(fp, curthread); + return (ECONNRESET); + } fdrop(fp, curthread); sc = fa.sc; @@ -1821,7 +1859,12 @@ ci = sc->iscsi_ulp_softc; MPASS(ci != NULL); - idl->idl_max_recv_data_segment_length = ci->max_rx_data_len; + if (sc->tt.iscsi_mss_dsl) + idl->idl_max_recv_data_segment_length = + min(mss_rx_limit, ci->max_rx_data_len); + else + idl->idl_max_recv_data_segment_length = + ci->max_rx_data_len; idl->idl_max_send_data_segment_length = ci->max_tx_data_len; } else error = ENXIO; Index: sys/dev/cxgbe/offload.h =================================================================== --- sys/dev/cxgbe/offload.h +++ sys/dev/cxgbe/offload.h @@ -234,6 +234,7 @@ int autorcvbuf_inc; int update_hc_on_pmtu_change; int iso; + int iscsi_mss_dsl; }; /* iWARP driver tunables */ Index: sys/dev/cxgbe/t4_main.c =================================================================== --- sys/dev/cxgbe/t4_main.c +++ sys/dev/cxgbe/t4_main.c @@ -7624,6 +7624,11 @@ SYSCTL_ADD_INT(ctx, children, OID_AUTO, "iso", CTLFLAG_RW, &sc->tt.iso, 0, "Enable iSCSI segmentation offload"); + sc->tt.iscsi_mss_dsl = 1; + SYSCTL_ADD_INT(ctx, children, OID_AUTO, "iscsi_mss_dsl", + CTLFLAG_RW, &sc->tt.iscsi_mss_dsl, 0, + "Use MSS to compute iSCSI MaxRecvDataSegmentLength"); + SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "timer_tick", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0, sysctl_tp_tick, "A", "TP timer tick (us)");