Drives with MDTS set to zero

Keith Busch keith.busch at intel.com
Wed Nov 18 14:58:20 PST 2015


On Tue, Nov 17, 2015 at 08:51:50PM +0000, Paul Grabinar wrote:
> I have a drive that sets MDTS to zero. According to the NVMe
> specification, that is valid and means that the drive does not have a
> limit on the transfer size.
> 
> In the current 4.4 kernel driver, we detect this and set
> dev->max_hw_sectors to UINT_MAX.
> 
> Later, when a namespace is allocated, we set the block level
> max_hw_sectors and max_segments based on dev->max_hw_sectors. This
> operations perform shifts on the value, but we are already at UINT_MAX,
> so end up with strange results.
> 
> I'm not entirely sure what is supposed to happen. The following patch
> sets max_hw_sectors to
> 
> BLK_DEF_MAX_SECTORS and max_segments to BLK_MAX_SEGMENTS, but this still does not seem right, as drives with a large MDTS will set max_segments higher than this.

Nice find. The original code was written before the segment count, so
probably was not tested together (my controllers define MDTS, so I've
never tested it at all).

We can fix this by reordering the math instead of artificially reducing
the transfer size.
---
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 5aca81c..f17e3d3 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -2266,7 +2266,7 @@ static void nvme_alloc_ns(struct nvme_dev *dev, unsigned nsid)
 	if (dev->max_hw_sectors) {
 		blk_queue_max_hw_sectors(ns->queue, dev->max_hw_sectors);
 		blk_queue_max_segments(ns->queue,
-			((dev->max_hw_sectors << 9) / dev->page_size) + 1);
+			((dev->max_hw_sectors / (dev->page_size >> 9) + 1);
 	}
 	if (dev->stripe_size)
 		blk_queue_chunk_sectors(ns->queue, dev->stripe_size >> 9);
--



More information about the Linux-nvme mailing list