git: 125ec0e30785 - main - nvme: limit namespace character-device I/O size

From: Abdelkader Boudih <seuros_at_FreeBSD.org>
Date: Thu, 03 Sep 2026 15:34:31 UTC
The branch main has been updated by seuros:

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

commit 125ec0e30785bb0cbca7aa6c0b1a34b75e53078d
Author:     Abdelkader Boudih <seuros@FreeBSD.org>
AuthorDate: 2026-09-03 15:34:11 +0000
Commit:     Abdelkader Boudih <seuros@FreeBSD.org>
CommitDate: 2026-09-03 15:34:11 +0000

    nvme: limit namespace character-device I/O size
    
    The namespace character device does not initialize si_iosize_max, so
    physio falls back to DFLTPHYS and can produce a bio larger than the
    qpair payload DMA tag on a controller whose maximum transfer size is
    below 64KB. Such a bio fails DMA mapping and is never submitted.
    
    Approved by: ngie (co-mentor)
    MFC after:      1 week
    
    Reviewed by:    ngie, imp
    Differential Revision:  https://reviews.freebsd.org/D59152
---
 sys/dev/nvme/nvme_ns.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/sys/dev/nvme/nvme_ns.c b/sys/dev/nvme/nvme_ns.c
index 4f2ff826e184..0082d5cb6299 100644
--- a/sys/dev/nvme/nvme_ns.c
+++ b/sys/dev/nvme/nvme_ns.c
@@ -602,8 +602,10 @@ nvme_ns_construct(struct nvme_namespace *ns, uint32_t id,
 	 * cdev may have already been created, if we are reconstructing the
 	 *  namespace after a controller-level reset.
 	 */
-	if (ns->cdev != NULL)
+	if (ns->cdev != NULL) {
+		ns->cdev->si_iosize_max = ctrlr->max_xfer_size;
 		return (0);
+	}
 
 	/*
 	 * Namespace IDs start at 1, so we need to subtract 1 to create a
@@ -623,6 +625,11 @@ nvme_ns_construct(struct nvme_namespace *ns, uint32_t id,
 	ns->cdev->si_drv2 = make_dev_alias(ns->cdev, "%sns%d",
 	    device_get_nameunit(ctrlr->dev), ns->id);
 	ns->cdev->si_flags |= SI_UNMAPPED;
+	/*
+	 * Limit physio requests to the controller's maximum transfer size.
+	 * The qpair payload DMA tag is constructed with the same limit.
+	 */
+	ns->cdev->si_iosize_max = ctrlr->max_xfer_size;
 	ns->flags |= NVME_NS_ALIVE;
 
 	return (0);