From 3aa123dee7264ee9ab9c2876fa541a8dc8f08e73 Mon Sep 17 00:00:00 2001 From: Ashok Vairavan Date: Thu, 27 Oct 2016 12:31:52 -0700 Subject: [PATCH] nvme: fix max_segments integer truncation The block layer uses an unsigned short for max_segments. The way we calculate the value for NVMe tends to generate very large 32-bit values, which after integer truncation may lead to a zero value instead of the desired outcome. Signed-off-by: Christoph Hellwig Reported-by: Jeff Lien Tested-by: Jeff Lien Reviewed-by: Keith Busch Signed-off-by: Jens Axboe Orabug: 24928835 Cherry picked commit: 45686b6198bd824f083ff5293f191d78db9d708a Conflicts: UEK4 QU2 nvme module doesn't have core.c file. All the functions resides in pci.c. Hence, this patch is manually ported to the respective function in pci.c drivers/nvme/host/core.c Signed-off-by: Ashok Vairavan --- drivers/nvme/host/pci.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index fd0879823856f..6369a6280dd47 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -2153,9 +2153,11 @@ static void nvme_alloc_ns(struct nvme_dev *dev, unsigned nsid) blk_queue_logical_block_size(ns->queue, 1 << ns->lba_shift); if (dev->max_hw_sectors) { + u32 max_segments = + (dev->max_hw_sectors / (dev->page_size >> 9)) + 1; + blk_queue_max_hw_sectors(ns->queue, dev->max_hw_sectors); - blk_queue_max_segments(ns->queue, - (dev->max_hw_sectors / (dev->page_size >> 9)) + 1); + blk_queue_max_segments(ns->queue, min_t(u32, max_segments, USHRT_MAX)); } if (dev->stripe_size) blk_queue_chunk_sectors(ns->queue, dev->stripe_size >> 9); -- 2.49.0