The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=01dd6a83b5ffce7a99ab8a7c2c9dcb82088357cd
commit 01dd6a83b5ffce7a99ab8a7c2c9dcb82088357cd Author: John Baldwin <[email protected]> AuthorDate: 2025-11-10 15:50:47 +0000 Commit: John Baldwin <[email protected]> CommitDate: 2025-11-10 15:50:47 +0000 nvmf: Add a transport hook to limit the size of host data transfers Smart NIC offload transports may have a cap on the size of the largest data PDU that can be received. Allow these transports to enforce a cap on the size of an I/O request submitted by the nvmf(4) host. NB: The controller is able to advertise a maximum-supported PDU size during TCP negotiation, but there is no way in the protocol to advertise a maximum size that the host can receive. Sponsored by: Chelsio Communications --- sys/dev/nvmf/nvmf_tcp.c | 7 +++++++ sys/dev/nvmf/nvmf_transport.c | 6 ++++++ sys/dev/nvmf/nvmf_transport.h | 8 ++++++++ sys/dev/nvmf/nvmf_transport_internal.h | 3 +++ 4 files changed, 24 insertions(+) diff --git a/sys/dev/nvmf/nvmf_tcp.c b/sys/dev/nvmf/nvmf_tcp.c index e50d7ff48d2b..0e31c0495775 100644 --- a/sys/dev/nvmf/nvmf_tcp.c +++ b/sys/dev/nvmf/nvmf_tcp.c @@ -1602,6 +1602,12 @@ tcp_free_qpair(struct nvmf_qpair *nq) tcp_release_qpair(qp); } +static uint64_t +tcp_max_xfer_size(struct nvmf_qpair *nq) +{ + return (0); +} + static struct nvmf_capsule * tcp_allocate_capsule(struct nvmf_qpair *nq, int how) { @@ -1872,6 +1878,7 @@ tcp_send_controller_data(struct nvmf_capsule *nc, uint32_t data_offset, struct nvmf_transport_ops tcp_ops = { .allocate_qpair = tcp_allocate_qpair, .free_qpair = tcp_free_qpair, + .max_xfer_size = tcp_max_xfer_size, .allocate_capsule = tcp_allocate_capsule, .free_capsule = tcp_free_capsule, .transmit_capsule = tcp_transmit_capsule, diff --git a/sys/dev/nvmf/nvmf_transport.c b/sys/dev/nvmf/nvmf_transport.c index 1d3f5ea4cf69..d552393f7adf 100644 --- a/sys/dev/nvmf/nvmf_transport.c +++ b/sys/dev/nvmf/nvmf_transport.c @@ -188,6 +188,12 @@ nvmf_sqhd_valid(struct nvmf_capsule *nc) return (nc->nc_sqhd_valid); } +uint64_t +nvmf_max_xfer_size(struct nvmf_qpair *qp) +{ + return (qp->nq_ops->max_xfer_size(qp)); +} + uint8_t nvmf_validate_command_capsule(struct nvmf_capsule *nc) { diff --git a/sys/dev/nvmf/nvmf_transport.h b/sys/dev/nvmf/nvmf_transport.h index b192baeaccc1..38b661ab3c91 100644 --- a/sys/dev/nvmf/nvmf_transport.h +++ b/sys/dev/nvmf/nvmf_transport.h @@ -81,6 +81,14 @@ void *nvmf_capsule_sqe(struct nvmf_capsule *nc); void *nvmf_capsule_cqe(struct nvmf_capsule *nc); bool nvmf_sqhd_valid(struct nvmf_capsule *nc); +/* Host-specific APIs. */ + +/* + * Largest I/O request size for a single command supported by the + * transport. If the transport does not have a limit, returns 0. + */ +uint64_t nvmf_max_xfer_size(struct nvmf_qpair *qp); + /* Controller-specific APIs. */ /* diff --git a/sys/dev/nvmf/nvmf_transport_internal.h b/sys/dev/nvmf/nvmf_transport_internal.h index eb819a5c83b9..511aac120fdc 100644 --- a/sys/dev/nvmf/nvmf_transport_internal.h +++ b/sys/dev/nvmf/nvmf_transport_internal.h @@ -25,6 +25,9 @@ struct nvmf_transport_ops { const nvlist_t *nvl); void (*free_qpair)(struct nvmf_qpair *qp); + /* Limit on transfer size. */ + uint64_t (*max_xfer_size)(struct nvmf_qpair *qp); + /* Capsule operations. */ struct nvmf_capsule *(*allocate_capsule)(struct nvmf_qpair *qp, int how);
