mpt3sas: Limit NVMe request size to 2 MiB
Subsystems (3)
Ranjan Kumar
maintainerPATCH v3 1/1 mpt3sas: Limit NVMe request size to 2 MiB
The HBA firmware reports NVMe MDTS values based on the underlying drive capability. However, due to the 4K PRP page size and a limit of 512 entries, the driver supports a maximum I/O transfer size of 2 MiB.
Limit max_hw_sectors to the smaller of the reported MDTS and the 2 MiB driver limit to prevent issuing oversized I/O that may lead to a kernel oops.
--- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
drivers/scsi/mpt3sas/mpt3sas_scsih.c +13 -1
@@ -2738,8 +2738,20 @@ scsih_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim) pcie_device->enclosure_level, pcie_device->connector_name); +/* +* The HBA firmware passes the NVMe drive's MDTS +* (Maximum Data Transfer Size) up to the driver. However, +* the driver hardcodes a 4K page size for the PRP list, +* accommodating at most 512 entries. This strictly limits +* the maximum supported NVMe I/O transfer to 2 MiB. +* +* Cap max_hw_sectors to the smaller of the drive's reported +* MDTS or the 2 MiB driver limit to prevent kernel oopses. +*/ + lim->max_hw_sectors =SZ_2M >>SECTOR_SHIFT ;if (pcie_device->nvme_mdts) - lim->max_hw_sectors = pcie_device->nvme_mdts /512 ; + lim->max_hw_sectors =min_t (u32, lim->max_hw_sectors, + pcie_device->nvme_mdts >>SECTOR_SHIFT );pcie_device_put (pcie_device);spin_unlock_irqrestore (&ioc->pcie_device_lock, flags);
Signature · 1 line
2.47.3
Quoted 24 lines · On Mon, 13 Apr 2026 23:30:03 +0530 Ranjan Kumar <[email protected]>…
The HBA firmware reports NVMe MDTS values based on the underlying drive capability. However, due to the 4K PRP page size and a limit of 512 entries, the driver supports a maximum I/O transfer size of 2 MiB.
Limit
max_hw_sectorsto the smaller of the reported MDTS and the 2 MiB driver limit to prevent issuing oversized I/O that may lead to a kernel oops.Fixes 9b8b84879d4a ("block: Increase BLK_DEF_MAX_SECTORS_CAP")Reported-by Mira Limbeck <[email protected]>Suggested-by Keith Busch <[email protected]>Signed-off-by Ranjan Kumar <[email protected]>--- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)drivers/scsi/mpt3sas/mpt3sas_scsih.c +0
-0
drivers/scsi/mpt3sas/mpt3sas_scsih.c scsih_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim) · line 2744
Quoted 7 lines
drivers/scsi/mpt3sas/mpt3sas_scsih.c +4
-0@@ -2738,8 +2738,20 @@ scsih_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim) pcie_device->enclosure_level, pcie_device->connector_name); +/* +* The HBA firmware passes the NVMe drive's MDTS +* (Maximum Data Transfer Size) up to the driver. However, +* the driver hardcodes a 4K page size for the PRP list,
^ buffer ?
drivers/scsi/mpt3sas/mpt3sas_scsih.c scsih_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim) · line 2746
Quoted 2 lines
drivers/scsi/mpt3sas/mpt3sas_scsih.c +2
-0+* accommodating at most 512 entries. This strictly limits +* the maximum supported NVMe I/O transfer to 2 MiB.
Doesn't that make max_fw_entries 4096/8.
Assuming 4096 byte sectors the longest transfer is then 4096/8*4096. So none of this has anything to to with SECTOR_SHIFT.
drivers/scsi/mpt3sas/mpt3sas_scsih.c scsih_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim) · line 2754
Quoted 9 lines
drivers/scsi/mpt3sas/mpt3sas_scsih.c +7
-1+* +* Cap max_hw_sectors to the smaller of the drive's reported +* MDTS or the 2 MiB driver limit to prevent kernel oopses. +*/ + lim->max_hw_sectors =SZ_2M >>SECTOR_SHIFT ;if (pcie_device->nvme_mdts) - lim->max_hw_sectors = pcie_device->nvme_mdts /512 ; + lim->max_hw_sectors =min_t (u32, lim->max_hw_sectors, + pcie_device->nvme_mdts >>SECTOR_SHIFT );
Why min_t() ?
David
Quoted 3 lines
drivers/scsi/mpt3sas/mpt3sas_scsih.c +0
-0pcie_device_put (pcie_device);spin_unlock_irqrestore (&ioc->pcie_device_lock, flags);
Quoted 35 lines · David Laight
Quoted 24 lines · On Mon, 13 Apr 2026 23:30:03 +0530 Ranjan Kumar <[email protected]>…
The HBA firmware reports NVMe MDTS values based on the underlying drive capability. However, due to the 4K PRP page size and a limit of 512 entries, the driver supports a maximum I/O transfer size of 2 MiB.
Limit
max_hw_sectorsto the smaller of the reported MDTS and the 2 MiB driver limit to prevent issuing oversized I/O that may lead to a kernel oops.Fixes 9b8b84879d4a ("block: Increase BLK_DEF_MAX_SECTORS_CAP")Reported-by Mira Limbeck <[email protected]>Suggested-by Keith Busch <[email protected]>Signed-off-by Ranjan Kumar <[email protected]>--- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)drivers/scsi/mpt3sas/mpt3sas_scsih.c +0
-0drivers/scsi/mpt3sas/mpt3sas_scsih.c scsih_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim) · line 2744
Quoted 7 lines
drivers/scsi/mpt3sas/mpt3sas_scsih.c +4
-0@@ -2738,8 +2738,20 @@ scsih_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim) pcie_device->enclosure_level, pcie_device->connector_name); +/* +* The HBA firmware passes the NVMe drive's MDTS +* (Maximum Data Transfer Size) up to the driver. However, +* the driver hardcodes a 4K page size for the PRP list, ^ buffer ?
Quoted 4 lines
drivers/scsi/mpt3sas/mpt3sas_scsih.c scsih_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim) · line 2746
Quoted 2 lines
drivers/scsi/mpt3sas/mpt3sas_scsih.c +2
-0+* accommodating at most 512 entries. This strictly limits +* the maximum supported NVMe I/O transfer to 2 MiB. Doesn't that make
max_fw_entries4096/8.
What is max_fw_entries ?
What the above explains is that a single NVMe page (4K) can store 512 (4096/8) PRP entries, each pointing at a 4K nvme page, so 512*4096=2M maximum size.
Quoted 1 line
Assuming 4096 byte sectors the longest transfer is then 4096/8*4096.
Yes, that's the SZ_2M Bytes.
Quoted 1 line
So none of this has anything to to with
SECTOR_SHIFT.
Apparently, nvme_mdts is in bytes, even though the documentation in mpt3sas_base.h does not mention anything about its unit. So yes, we need a SECTOR_SHIFT to convert that to 512B sectors unit.
Quoted 12 lines
drivers/scsi/mpt3sas/mpt3sas_scsih.c scsih_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim) · line 2754
Quoted 10 lines
drivers/scsi/mpt3sas/mpt3sas_scsih.c +7
-1+* +* Cap max_hw_sectors to the smaller of the drive's reported +* MDTS or the 2 MiB driver limit to prevent kernel oopses. +*/ + lim->max_hw_sectors =SZ_2M >>SECTOR_SHIFT ;if (pcie_device->nvme_mdts) - lim->max_hw_sectors = pcie_device->nvme_mdts /512 ; + lim->max_hw_sectors =min_t (u32, lim->max_hw_sectors, + pcie_device->nvme_mdts >>SECTOR_SHIFT );Why
min_t()?
max_hw_sectors is unsigned int and nvme_mdts is u32. Not sure if that bothers min(). Worth trying.
Quoted 7 lines
David
Quoted 3 lines
drivers/scsi/mpt3sas/mpt3sas_scsih.c +0
-0pcie_device_put (pcie_device);spin_unlock_irqrestore (&ioc->pcie_device_lock, flags);
Signature · 2 lines
Damien Le Moal Western Digital Research
Quoted 36 lines · On Tue, 14 Apr 2026 05:41:59 +0200 Damien Le Moal <[email protected]> wrote:
Quoted 35 lines · David Laight
Quoted 24 lines · On Mon, 13 Apr 2026 23:30:03 +0530 Ranjan Kumar <[email protected]>…
The HBA firmware reports NVMe MDTS values based on the underlying drive capability. However, due to the 4K PRP page size and a limit of 512 entries, the driver supports a maximum I/O transfer size of 2 MiB.
Limit
max_hw_sectorsto the smaller of the reported MDTS and the 2 MiB driver limit to prevent issuing oversized I/O that may lead to a kernel oops.Fixes 9b8b84879d4a ("block: Increase BLK_DEF_MAX_SECTORS_CAP")Reported-by Mira Limbeck <[email protected]>Suggested-by Keith Busch <[email protected]>Signed-off-by Ranjan Kumar <[email protected]>--- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)drivers/scsi/mpt3sas/mpt3sas_scsih.c +0
-0drivers/scsi/mpt3sas/mpt3sas_scsih.c scsih_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim) · line 2744
Quoted 7 lines
drivers/scsi/mpt3sas/mpt3sas_scsih.c +4
-0@@ -2738,8 +2738,20 @@ scsih_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim) pcie_device->enclosure_level, pcie_device->connector_name); +/* +* The HBA firmware passes the NVMe drive's MDTS +* (Maximum Data Transfer Size) up to the driver. However, +* the driver hardcodes a 4K page size for the PRP list, ^ buffer ?
Quoted 6 lines
Quoted 4 lines
drivers/scsi/mpt3sas/mpt3sas_scsih.c scsih_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim) · line 2746
Quoted 2 lines
drivers/scsi/mpt3sas/mpt3sas_scsih.c +2
-0+* accommodating at most 512 entries. This strictly limits +* the maximum supported NVMe I/O transfer to 2 MiB. Doesn't that make
max_fw_entries4096/8.What is
max_fw_entries?
A mistype for max_hw_sectors :-(
Quoted 6 lines
What the above explains is that a single NVMe page (4K) can store 512 (4096/8) PRP entries, each pointing at a 4K nvme page, so 512*4096=2M maximum size.
Quoted 1 line
Assuming 4096 byte sectors the longest transfer is then 4096/8*4096.
Yes, that's the
SZ_2MBytes.
So write it as (4096/8)*4096
Quoted 6 lines
Quoted 2 lines
So none of this has anything to to with
SECTOR_SHIFT.Apparently,
nvme_mdtsis in bytes, even though the documentation inmpt3sas_base.hdoes not mention anything about its unit. So yes, we need aSECTOR_SHIFTto convert that to 512B sectors unit.
It is all very confusing because of the 4k and 512 byte sectors and there being another 512 constant.
Perhaps the best expression is:
(4096 /* NVMe page */ / 8) * (4096 /* hw sector size */ >> SECTOR_SIZE)
Quoted 14 lines
Quoted 13 lines
drivers/scsi/mpt3sas/mpt3sas_scsih.c scsih_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim) · line 2754
Quoted 11 lines
drivers/scsi/mpt3sas/mpt3sas_scsih.c +7
-1+* +* Cap max_hw_sectors to the smaller of the drive's reported +* MDTS or the 2 MiB driver limit to prevent kernel oopses. +*/ + lim->max_hw_sectors =SZ_2M >>SECTOR_SHIFT ;if (pcie_device->nvme_mdts) - lim->max_hw_sectors = pcie_device->nvme_mdts /512 ; + lim->max_hw_sectors =min_t (u32, lim->max_hw_sectors, + pcie_device->nvme_mdts >>SECTOR_SHIFT );Why
min_t()?
Quoted 2 lines
max_hw_sectorsis unsigned int andnvme_mdtsis u32. Not sure if that bothersmin(). Worth trying.
It doesn't bother it (any more).
David
Quoted 10 lines
Quoted 8 lines
David
Quoted 3 lines
drivers/scsi/mpt3sas/mpt3sas_scsih.c +0
-0pcie_device_put (pcie_device);spin_unlock_irqrestore (&ioc->pcie_device_lock, flags);
Quoted 48 lines · David Laight
Quoted 36 lines · On Tue, 14 Apr 2026 05:41:59 +0200 Damien Le Moal <[email protected]> wrote:
Quoted 35 lines · David Laight
Quoted 24 lines · On Mon, 13 Apr 2026 23:30:03 +0530 Ranjan Kumar <[email protected]>…
The HBA firmware reports NVMe MDTS values based on the underlying drive capability. However, due to the 4K PRP page size and a limit of 512 entries, the driver supports a maximum I/O transfer size of 2 MiB.
Limit
max_hw_sectorsto the smaller of the reported MDTS and the 2 MiB driver limit to prevent issuing oversized I/O that may lead to a kernel oops.Fixes 9b8b84879d4a ("block: Increase BLK_DEF_MAX_SECTORS_CAP")Reported-by Mira Limbeck <[email protected]>Suggested-by Keith Busch <[email protected]>Signed-off-by Ranjan Kumar <[email protected]>--- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)drivers/scsi/mpt3sas/mpt3sas_scsih.c +0
-0drivers/scsi/mpt3sas/mpt3sas_scsih.c scsih_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim) · line 2744
Quoted 7 lines
drivers/scsi/mpt3sas/mpt3sas_scsih.c +4
-0@@ -2738,8 +2738,20 @@ scsih_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim) pcie_device->enclosure_level, pcie_device->connector_name); +/* +* The HBA firmware passes the NVMe drive's MDTS +* (Maximum Data Transfer Size) up to the driver. However, +* the driver hardcodes a 4K page size for the PRP list, ^ buffer ?
Quoted 6 lines
Quoted 4 lines
drivers/scsi/mpt3sas/mpt3sas_scsih.c scsih_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim) · line 2746
Quoted 2 lines
drivers/scsi/mpt3sas/mpt3sas_scsih.c +2
-0+* accommodating at most 512 entries. This strictly limits +* the maximum supported NVMe I/O transfer to 2 MiB. Doesn't that make
max_fw_entries4096/8.What is
max_fw_entries?A mistype for
max_hw_sectors:-(
Quoted 8 lines
Quoted 6 lines
What the above explains is that a single NVMe page (4K) can store 512 (4096/8) PRP entries, each pointing at a 4K nvme page, so 512*4096=2M maximum size.
Quoted 1 line
Assuming 4096 byte sectors the longest transfer is then 4096/8*4096.
Yes, that's the
SZ_2MBytes.So write it as (4096/8)*4096
See below.
Quoted 10 lines
Quoted 5 lines
Quoted 1 line
So none of this has anything to to with
SECTOR_SHIFT.Apparently,
nvme_mdtsis in bytes, even though the documentation inmpt3sas_base.hdoes not mention anything about its unit. So yes, we need aSECTOR_SHIFTto convert that to 512B sectors unit.It is all very confusing because of the 4k and 512 byte sectors and there being another 512 constant.
Perhaps the best expression is:(4096 /* NVMe page */ / 8) * (4096 /* hw sector size */ >> SECTOR_SIZE)
Yes, we could, but I think the comment is clear enough, so I have no issue with the code as it is. But I will not fight this though. I will let Martin & James decide.
Quoted 12 lines
Quoted 12 lines
Quoted 11 lines
drivers/scsi/mpt3sas/mpt3sas_scsih.c scsih_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim) · line 2754
Quoted 9 lines
drivers/scsi/mpt3sas/mpt3sas_scsih.c +7
-1+* +* Cap max_hw_sectors to the smaller of the drive's reported +* MDTS or the 2 MiB driver limit to prevent kernel oopses. +*/ + lim->max_hw_sectors =SZ_2M >>SECTOR_SHIFT ;if (pcie_device->nvme_mdts) - lim->max_hw_sectors = pcie_device->nvme_mdts /512 ; + lim->max_hw_sectors =min_t (u32, lim->max_hw_sectors, + pcie_device->nvme_mdts >>SECTOR_SHIFT );Why
min_t()?
Quoted 4 lines
Quoted 2 lines
max_hw_sectorsis unsigned int andnvme_mdtsis u32. Not sure if that bothersmin(). Worth trying.It doesn't bother it (any more).
OK. Let's drop the min_t() then and use min().
Signature · 2 lines
Damien Le Moal Western Digital Research
Ranjan Kumar
maintainerHi Damien and David,
Thanks for the suggestions.
Quoted 101 lines · Damien Le Moal
Quoted 49 lines · David Laight
Quoted 37 lines · On Tue, 14 Apr 2026 05:41:59 +0200 Damien Le Moal <[email protected]> wrote:
Quoted 36 lines · David Laight
Quoted 24 lines · On Mon, 13 Apr 2026 23:30:03 +0530 Ranjan Kumar <[email protected]>…
The HBA firmware reports NVMe MDTS values based on the underlying drive capability. However, due to the 4K PRP page size and a limit of 512 entries, the driver supports a maximum I/O transfer size of 2 MiB.
Limit
max_hw_sectorsto the smaller of the reported MDTS and the 2 MiB driver limit to prevent issuing oversized I/O that may lead to a kernel oops.Fixes 9b8b84879d4a ("block: Increase BLK_DEF_MAX_SECTORS_CAP")Reported-by Mira Limbeck <[email protected]>Suggested-by Keith Busch <[email protected]>Signed-off-by Ranjan Kumar <[email protected]>--- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)drivers/scsi/mpt3sas/mpt3sas_scsih.c +0
-0drivers/scsi/mpt3sas/mpt3sas_scsih.c scsih_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim) · line 2744
Quoted 7 lines
drivers/scsi/mpt3sas/mpt3sas_scsih.c +4
-0@@ -2738,8 +2738,20 @@ scsih_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim) pcie_device->enclosure_level, pcie_device->connector_name); +/* +* The HBA firmware passes the NVMe drive's MDTS +* (Maximum Data Transfer Size) up to the driver. However, +* the driver hardcodes a 4K page size for the PRP list, ^ buffer ?
I will change page size to "buffer size" .Quoted 6 lines
Quoted 4 lines
drivers/scsi/mpt3sas/mpt3sas_scsih.c scsih_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim) · line 2746
Quoted 2 lines
drivers/scsi/mpt3sas/mpt3sas_scsih.c +2
-0+* accommodating at most 512 entries. This strictly limits +* the maximum supported NVMe I/O transfer to 2 MiB. Doesn't that make
max_fw_entries4096/8.What is
max_fw_entries?A mistype for
max_hw_sectors:-(Quoted 8 lines
Quoted 6 lines
What the above explains is that a single NVMe page (4K) can store 512 (4096/8) PRP entries, each pointing at a 4K nvme page, so 512*4096=2M maximum size.
Quoted 1 line
Assuming 4096 byte sectors the longest transfer is then 4096/8*4096.
Yes, that's the
SZ_2MBytes.So write it as (4096/8)*4096
See below.
Quoted 10 lines
Quoted 5 lines
Quoted 1 line
So none of this has anything to to with
SECTOR_SHIFT.Apparently,
nvme_mdtsis in bytes, even though the documentation inmpt3sas_base.hdoes not mention anything about its unit. So yes, we need aSECTOR_SHIFTto convert that to 512B sectors unit.It is all very confusing because of the 4k and 512 byte sectors and there being another 512 constant.
Perhaps the best expression is:(4096 /* NVMe page */ / 8) * (4096 /* hw sector size */ >> SECTOR_SIZE)Yes, we could, but I think the comment is clear enough, so I have no issue with the code as it is. But I will not fight this though. I will let Martin & James decide.
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 9 lines
drivers/scsi/mpt3sas/mpt3sas_scsih.c +7
-1+* +* Cap max_hw_sectors to the smaller of the drive's reported +* MDTS or the 2 MiB driver limit to prevent kernel oopses. +*/ + lim->max_hw_sectors =SZ_2M >>SECTOR_SHIFT ;if (pcie_device->nvme_mdts) - lim->max_hw_sectors = pcie_device->nvme_mdts /512 ; + lim->max_hw_sectors =min_t (u32, lim->max_hw_sectors, + pcie_device->nvme_mdts >>SECTOR_SHIFT );Quoted 6 lines
Quoted 4 lines
Quoted 1 line
Why
min_t()?
max_hw_sectorsis unsigned int andnvme_mdtsis u32. Not sure if that bothersmin(). Worth trying.It doesn't bother it (any more).
OK. Let's drop the
min_t()then and usemin().Quoted 2 lines
I will drop
min_t()and will usemin().
I'll include these updates in the v4 patch.--
Damien Le Moal
Western Digital Research