The branch main has been updated by jhb:

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

commit d869395ac4bd248da7c5bdc67afb19ca89fbeeee
Author:     John Baldwin <j...@freebsd.org>
AuthorDate: 2025-09-11 21:10:40 +0000
Commit:     John Baldwin <j...@freebsd.org>
CommitDate: 2025-09-11 21:10:40 +0000

    cxgbe tom: Send auxiliary TLS work requests as raw WR mbufs
    
    In particular, the work request to update the TCB state when switching
    from plain TCP to TLS is now queued on the connection's offload
    transmit queue rather than over the per-port control queue.
    
    This also handles an unlikely edge case that a connection does not
    have sufficient credits to transmit other work requests synchronously
    such as programming the key in on-card memory or altering TCB fields.
    
    Reviewed by:    np
    Sponsored by:   Chelsio Communications
    Differential Revision:  https://reviews.freebsd.org/D47763
---
 sys/dev/cxgbe/tom/t4_cpl_io.c | 36 +++++++++++++++++-----------
 sys/dev/cxgbe/tom/t4_tls.c    | 56 +++++++++++++++++++++----------------------
 sys/dev/cxgbe/tom/t4_tom.h    |  2 ++
 3 files changed, 51 insertions(+), 43 deletions(-)

diff --git a/sys/dev/cxgbe/tom/t4_cpl_io.c b/sys/dev/cxgbe/tom/t4_cpl_io.c
index a7b4162db3b5..be20ea42474e 100644
--- a/sys/dev/cxgbe/tom/t4_cpl_io.c
+++ b/sys/dev/cxgbe/tom/t4_cpl_io.c
@@ -2039,25 +2039,16 @@ do_fw4_ack(struct sge_iq *iq, const struct rss_header 
*rss, struct mbuf *m)
 }
 
 void
-t4_set_tcb_field(struct adapter *sc, struct sge_wrq *wrq, struct toepcb *toep,
+write_set_tcb_field(struct adapter *sc, void *dst, struct toepcb *toep,
     uint16_t word, uint64_t mask, uint64_t val, int reply, int cookie)
 {
-       struct wrqe *wr;
-       struct cpl_set_tcb_field *req;
-       struct ofld_tx_sdesc *txsd;
+       struct cpl_set_tcb_field *req = dst;
 
        MPASS((cookie & ~M_COOKIE) == 0);
        if (reply) {
                MPASS(cookie != CPL_COOKIE_RESERVED);
        }
 
-       wr = alloc_wrqe(sizeof(*req), wrq);
-       if (wr == NULL) {
-               /* XXX */
-               panic("%s: allocation failure.", __func__);
-       }
-       req = wrtod(wr);
-
        INIT_TP_WR_MIT_CPL(req, CPL_SET_TCB_FIELD, toep->tid);
        req->reply_ctrl = htobe16(V_QUEUENO(toep->ofld_rxq->iq.abs_id));
        if (reply == 0)
@@ -2065,12 +2056,29 @@ t4_set_tcb_field(struct adapter *sc, struct sge_wrq 
*wrq, struct toepcb *toep,
        req->word_cookie = htobe16(V_WORD(word) | V_COOKIE(cookie));
        req->mask = htobe64(mask);
        req->val = htobe64(val);
+}
+
+void
+t4_set_tcb_field(struct adapter *sc, struct sge_wrq *wrq, struct toepcb *toep,
+    uint16_t word, uint64_t mask, uint64_t val, int reply, int cookie)
+{
+       struct wrqe *wr;
+       struct ofld_tx_sdesc *txsd;
+       const u_int len = sizeof(struct cpl_set_tcb_field);
+
+       wr = alloc_wrqe(len, wrq);
+       if (wr == NULL) {
+               /* XXX */
+               panic("%s: allocation failure.", __func__);
+       }
+       write_set_tcb_field(sc, wrtod(wr), toep, word, mask, val, reply,
+           cookie);
+
        if (wrq->eq.type == EQ_OFLD) {
                txsd = &toep->txsd[toep->txsd_pidx];
-               _Static_assert(howmany(sizeof(*req), 16) <=
-                   MAX_OFLD_TX_SDESC_CREDITS,
+               _Static_assert(howmany(len, 16) <= MAX_OFLD_TX_SDESC_CREDITS,
                    "MAX_OFLD_TX_SDESC_CREDITS too small");
-               txsd->tx_credits = howmany(sizeof(*req), 16);
+               txsd->tx_credits = howmany(len, 16);
                txsd->plen = 0;
                KASSERT(toep->tx_credits >= txsd->tx_credits &&
                    toep->txsd_avail > 0,
diff --git a/sys/dev/cxgbe/tom/t4_tls.c b/sys/dev/cxgbe/tom/t4_tls.c
index 3dd3c28e3a86..ad72c6a6b025 100644
--- a/sys/dev/cxgbe/tom/t4_tls.c
+++ b/sys/dev/cxgbe/tom/t4_tls.c
@@ -61,11 +61,21 @@
 
 static void
 t4_set_tls_tcb_field(struct toepcb *toep, uint16_t word, uint64_t mask,
-    uint64_t val)
+    uint64_t val, int reply, int cookie)
 {
        struct adapter *sc = td_adapter(toep->td);
+       struct mbuf *m;
 
-       t4_set_tcb_field(sc, &toep->ofld_txq->wrq, toep, word, mask, val, 0, 0);
+       m = alloc_raw_wr_mbuf(sizeof(struct cpl_set_tcb_field));
+       if (m == NULL) {
+               /* XXX */
+               panic("%s: out of memory", __func__);
+       }
+
+       write_set_tcb_field(sc, mtod(m, void *), toep, word, mask, val, reply,
+           cookie);
+
+       t4_raw_wr_tx(sc, toep, m);
 }
 
 /* TLS and DTLS common routines */
@@ -88,10 +98,9 @@ tls_tx_key(struct toepcb *toep)
 static void
 t4_set_rx_quiesce(struct toepcb *toep)
 {
-       struct adapter *sc = td_adapter(toep->td);
 
-       t4_set_tcb_field(sc, &toep->ofld_txq->wrq, toep, W_TCB_T_FLAGS,
-           V_TF_RX_QUIESCE(1), V_TF_RX_QUIESCE(1), 1, CPL_COOKIE_TOM);
+       t4_set_tls_tcb_field(toep, W_TCB_T_FLAGS, V_TF_RX_QUIESCE(1),
+           V_TF_RX_QUIESCE(1), 1, CPL_COOKIE_TOM);
 }
 
 /* Clear TF_RX_QUIESCE to re-enable receive. */
@@ -99,7 +108,7 @@ static void
 t4_clear_rx_quiesce(struct toepcb *toep)
 {
 
-       t4_set_tls_tcb_field(toep, W_TCB_T_FLAGS, V_TF_RX_QUIESCE(1), 0);
+       t4_set_tls_tcb_field(toep, W_TCB_T_FLAGS, V_TF_RX_QUIESCE(1), 0, 0, 0);
 }
 
 /* TLS/DTLS content type  for CPL SFO */
@@ -145,16 +154,15 @@ get_tp_plen_max(struct ktls_session *tls)
        return (tls->params.max_frame_len <= 8192 ? plen : FC_TP_PLEN_MAX);
 }
 
-/* Send request to get the key-id */
+/* Send request to save the key in on-card memory. */
 static int
 tls_program_key_id(struct toepcb *toep, struct ktls_session *tls,
     int direction)
 {
        struct tls_ofld_info *tls_ofld = &toep->tls;
        struct adapter *sc = td_adapter(toep->td);
-       struct ofld_tx_sdesc *txsd;
        int keyid;
-       struct wrqe *wr;
+       struct mbuf *m;
        struct tls_key_req *kwr;
        struct tls_keyctx *kctx;
 
@@ -173,12 +181,12 @@ tls_program_key_id(struct toepcb *toep, struct 
ktls_session *tls,
                return (ENOSPC);
        }
 
-       wr = alloc_wrqe(TLS_KEY_WR_SZ, &toep->ofld_txq->wrq);
-       if (wr == NULL) {
+       m = alloc_raw_wr_mbuf(TLS_KEY_WR_SZ);
+       if (m == NULL) {
                t4_free_tls_keyid(sc, keyid);
                return (ENOMEM);
        }
-       kwr = wrtod(wr);
+       kwr = mtod(m, struct tls_key_req *);
        memset(kwr, 0, TLS_KEY_WR_SZ);
 
        t4_write_tlskey_wr(tls, direction, toep->tid, F_FW_WR_COMPL, keyid,
@@ -190,17 +198,7 @@ tls_program_key_id(struct toepcb *toep, struct 
ktls_session *tls,
                tls_ofld->rx_key_addr = keyid;
        t4_tls_key_ctx(tls, direction, kctx);
 
-       txsd = &toep->txsd[toep->txsd_pidx];
-       _Static_assert(DIV_ROUND_UP(TLS_KEY_WR_SZ, 16) <=
-           MAX_OFLD_TX_SDESC_CREDITS, "MAX_OFLD_TX_SDESC_CREDITS too small");
-       txsd->tx_credits = DIV_ROUND_UP(TLS_KEY_WR_SZ, 16);
-       txsd->plen = 0;
-       toep->tx_credits -= txsd->tx_credits;
-       if (__predict_false(++toep->txsd_pidx == toep->txsd_total))
-               toep->txsd_pidx = 0;
-       toep->txsd_avail--;
-
-       t4_wrq_tx(sc, wr);
+       t4_raw_wr_tx(sc, toep, m);
 
        return (0);
 }
@@ -1099,7 +1097,7 @@ out:
 static void
 tls_update_tcb(struct adapter *sc, struct toepcb *toep, uint64_t seqno)
 {
-       struct wrqe *wr;
+       struct mbuf *m;
        struct work_request_hdr *wrh;
        struct ulp_txpkt *ulpmc;
        int fields, key_offset, len;
@@ -1128,14 +1126,14 @@ tls_update_tcb(struct adapter *sc, struct toepcb *toep, 
uint64_t seqno)
        KASSERT(len <= SGE_MAX_WR_LEN,
            ("%s: WR with %d TCB field updates too large", __func__, fields));
 
-       wr = alloc_wrqe(len, toep->ctrlq);
-       if (wr == NULL) {
+       m = alloc_raw_wr_mbuf(len);
+       if (m == NULL) {
                /* XXX */
                panic("%s: out of memory", __func__);
        }
 
-       wrh = wrtod(wr);
-       INIT_ULPTX_WRH(wrh, len, 1, 0); /* atomic */
+       wrh = mtod(m, struct work_request_hdr *);
+       INIT_ULPTX_WRH(wrh, len, 1, toep->tid); /* atomic */
        ulpmc = (struct ulp_txpkt *)(wrh + 1);
 
        /*
@@ -1180,7 +1178,7 @@ tls_update_tcb(struct adapter *sc, struct toepcb *toep, 
uint64_t seqno)
        ulpmc = mk_set_tcb_field_ulp(sc, ulpmc, toep->tid, W_TCB_T_FLAGS,
            V_TF_RX_QUIESCE(1), 0);
 
-       t4_wrq_tx(sc, wr);
+       t4_raw_wr_tx(sc, toep, m);
 }
 
 /*
diff --git a/sys/dev/cxgbe/tom/t4_tom.h b/sys/dev/cxgbe/tom/t4_tom.h
index af6d37931b2e..4fb87d92d91e 100644
--- a/sys/dev/cxgbe/tom/t4_tom.h
+++ b/sys/dev/cxgbe/tom/t4_tom.h
@@ -531,6 +531,8 @@ void t4_set_tcb_field(struct adapter *, struct sge_wrq *, 
struct toepcb *,
 void t4_push_pdus(struct adapter *, struct toepcb *, int);
 bool t4_push_raw_wr(struct adapter *, struct toepcb *, struct mbuf *);
 void t4_raw_wr_tx(struct adapter *, struct toepcb *, struct mbuf *);
+void write_set_tcb_field(struct adapter *, void *, struct toepcb *, uint16_t,
+    uint64_t, uint64_t, int, int);
 
 /* t4_ddp.c */
 int t4_init_ppod_region(struct ppod_region *, struct t4_range *, u_int,

Reply via email to