Patch "nvme-pci: fix host memory buffer allocation fallback" has been added to the 4.13-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
nvme-pci: fix host memory buffer allocation fallback
to the 4.13-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
nvme-pci-fix-host-memory-buffer-allocation-fallback.patch
and it can be found in the queue-4.13 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
92dc689563170b90ba844b8a2eb95e8a5eda2e83Mon Sep 17 00:00:00 2001
From: Christoph Hellwig <[email protected]>
Date: Mon, 11 Sep 2017 12:08:43 -0400
Subject: nvme-pci: fix host memory buffer allocation fallback
From: Christoph Hellwig <[email protected]>
commit 92dc689563170b90ba844b8a2eb95e8a5eda2e83 upstream.
nvme_alloc_host_mem currently contains two loops that are interwinded, and the outer retry loop turns out to be broken. Fix this by untangling the two.
Based on a report an initial patch from Akinobu Mita.
--- drivers/nvme/host/pci.c | 48 ++++++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 18 deletions(-)
drivers/nvme/host/pci.c +30 -18
@@ -1609,18 +1609,16 @@ static void nvme_free_host_mem(struct nv dev->host_mem_descs =NULL ; } -static int nvme_alloc_host_mem (struct nvme_dev *dev,u64 min,u64 preferred) +static int __nvme_alloc_host_mem (struct nvme_dev *dev,u64 preferred, +u32 chunk_size) {struct nvme_host_mem_buf_desc *descs; -u32 chunk_size, max_entries, len; +u32 max_entries, len;dma_addr_t descs_dma;int i =0 ;void **bufs;u64 size =0 , tmp; -/* start big and work our way down */ - chunk_size =min (preferred, (u64 )PAGE_SIZE <<MAX_ORDER ); -retry: tmp = (preferred + chunk_size -1 );do_div (tmp, chunk_size); max_entries = tmp;
@@ -1647,15 +1645,9 @@ retry: i++; } -if (!size || (min && size < min)) { -dev_warn (dev->ctrl.device, -"failed to allocate host memory buffer.\n" ); +if (!size) goto out_free_bufs; - } -dev_info (dev->ctrl.device, -"allocated %lld MiB host memory buffer.\n" , - size >>ilog2 (SZ_1M )); dev->nr_host_mem_descs = i; dev->host_mem_size = size; dev->host_mem_descs = descs;
@@ -1676,15 +1668,28 @@ out_free_descs:dma_free_coherent (dev->dev, max_entries *sizeof (*descs), descs, descs_dma); out: -/* try a smaller chunk size if we failed early */ -if (chunk_size >=PAGE_SIZE *2 && (i ==0 || size < min)) { - chunk_size /=2 ; - goto retry; - } dev->host_mem_descs =NULL ;return -ENOMEM ; } +static int nvme_alloc_host_mem (struct nvme_dev *dev,u64 min,u64 preferred) +{ +u32 chunk_size; + +/* start big and work our way down */ +for (chunk_size =min_t (u64, preferred,PAGE_SIZE <<MAX_ORDER ); + chunk_size >=PAGE_SIZE *2 ; + chunk_size /=2 ) { +if (!__nvme_alloc_host_mem (dev, preferred, chunk_size)) { +if (!min || dev->host_mem_size >= min) +return 0 ; +nvme_free_host_mem (dev); + } + } + +return -ENOMEM ; +} +static void nvme_setup_host_mem (struct nvme_dev *dev) {u64 max = (u64 )max_host_mem_size_mb *SZ_1M ;
@@ -1712,8 +1717,15 @@ static void nvme_setup_host_mem(struct n }if (!dev->host_mem_descs) { -if (nvme_alloc_host_mem (dev, min, preferred)) +if (nvme_alloc_host_mem (dev, min, preferred)) { +dev_warn (dev->ctrl.device, +"failed to allocate host memory buffer.\n" );return ; + } + +dev_info (dev->ctrl.device, +"allocated %lld MiB host memory buffer.\n" , + dev->host_mem_size >>ilog2 (SZ_1M )); }if (nvme_set_host_mem (dev, enable_bits))
Patches currently in stable-queue which might be from [email protected] are
queue-4.13/nvme-pci-propagate-some-errors-from-host-memory-buffer-setup.patch queue-4.13/nvme-pci-use-appropriate-initial-chunk-size-for-hmb-allocation.patch queue-4.13/nvme-pci-fix-host-memory-buffer-allocation-fallback.patch queue-4.13/scsi-scsi_transport_fc-fix-null-pointer-dereference-in-fc_bsg_job_timeout.patch