From: Christoph Hellwig Date: Fri, 3 Jun 2016 13:42:16 +0000 (-0600) Subject: nvme: fix max_segments integer truncation X-Git-Tag: Ubuntu-snapdragon-4.4.0-1029.32~1766 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=b3f17ffffd0af94dcdb6bc968bd1960f24dd2486;p=mirror_ubuntu-zesty-kernel.git nvme: fix max_segments integer truncation BugLink: http://bugs.launchpad.net/bugs/1588449 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 (cherry picked from commit 45686b6198bd824f083ff5293f191d78db9d708a) Signed-off-by: Tim Gardner Acked-by: Stefan Bader Signed-off-by: Kamal Mostafa --- diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index fde3b4a4e03c..6ab452d931b2 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -839,9 +839,11 @@ static void nvme_set_queue_limits(struct nvme_ctrl *ctrl, struct request_queue *q) { if (ctrl->max_hw_sectors) { + u32 max_segments = + (ctrl->max_hw_sectors / (ctrl->page_size >> 9)) + 1; + blk_queue_max_hw_sectors(q, ctrl->max_hw_sectors); - blk_queue_max_segments(q, - (ctrl->max_hw_sectors / (ctrl->page_size >> 9)) + 1); + blk_queue_max_segments(q, min_t(u32, max_segments, USHRT_MAX)); } if (ctrl->stripe_size) blk_queue_chunk_sectors(q, ctrl->stripe_size >> 9);