Date: Thu, 5 Sep 2024 21:15:06 GMT From: John Baldwin <jhb@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: bedfac1f026f - main - nvmf_tcp: Fully honor kern.nvmf.tcp.max_transmit_data for C2H_DATA PDUs Message-ID: <202409052115.485LF6cE032532@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=bedfac1f026fa8e2e6572ca380d89d74a01d5def commit bedfac1f026fa8e2e6572ca380d89d74a01d5def Author: John Baldwin <jhb@FreeBSD.org> AuthorDate: 2024-09-05 21:14:36 +0000 Commit: John Baldwin <jhb@FreeBSD.org> CommitDate: 2024-09-05 21:14:36 +0000 nvmf_tcp: Fully honor kern.nvmf.tcp.max_transmit_data for C2H_DATA PDUs The previous version of tcp_send_controller_data avoided sending a chain of multiple mbufs that exceeded the limit, but if an individual mbuf was larger than the limit it was sent as a single, over-sized PDU. Fix by using m_split() to split individual mbufs larger than the limit. Note that this is not a protocol error, per se, as there is no limit on C2H_DATA PDU lengths (unlike the MAXH2CDATA parameter). This fix just honors the administrative limit more faithfully. This case is also very unlikely with the default limit of 256k. Sponsored by: Chelsio Communications --- sys/dev/nvmf/nvmf_tcp.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/sys/dev/nvmf/nvmf_tcp.c b/sys/dev/nvmf/nvmf_tcp.c index 67d239b63faf..22275aaa835b 100644 --- a/sys/dev/nvmf/nvmf_tcp.c +++ b/sys/dev/nvmf/nvmf_tcp.c @@ -1784,7 +1784,6 @@ tcp_send_controller_data(struct nvmf_capsule *nc, uint32_t data_offset, { struct nvmf_tcp_qpair *qp = TQP(nc->nc_qpair); struct nvme_sgl_descriptor *sgl; - struct mbuf *n, *p; uint32_t data_len; bool last_pdu, last_xfer; @@ -1813,21 +1812,29 @@ tcp_send_controller_data(struct nvmf_capsule *nc, uint32_t data_offset, /* Queue one more C2H_DATA PDUs containing the data from 'm'. */ while (m != NULL) { + struct mbuf *n; uint32_t todo; - todo = m->m_len; - p = m; - n = p->m_next; - while (n != NULL) { - if (todo + n->m_len > qp->max_tx_data) { - p->m_next = NULL; - break; - } - todo += n->m_len; - p = n; + if (m->m_len > qp->max_tx_data) { + n = m_split(m, qp->max_tx_data, M_WAITOK); + todo = m->m_len; + } else { + struct mbuf *p; + + todo = m->m_len; + p = m; n = p->m_next; + while (n != NULL) { + if (todo + n->m_len > qp->max_tx_data) { + p->m_next = NULL; + break; + } + todo += n->m_len; + p = n; + n = p->m_next; + } + MPASS(m_length(m, NULL) == todo); } - MPASS(m_length(m, NULL) == todo); last_pdu = (n == NULL && last_xfer); tcp_send_c2h_pdu(qp, nc->nc_sqe.cid, data_offset, m, todo,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202409052115.485LF6cE032532>