Commit 9e866774aab5d2654b0fa8f97890f68913f05700

Authored by Matthew Wilcox
1 parent cd58ad7d18

NVMe: Free admin queue memory on initialisation failure

If the adapter fails initialisation, the memory allocated for the
admin queue may not be freed.  Split the memory freeing part of
nvme_free_queue() into nvme_free_queue_mem() and call it in the case of
initialisation failure.

Signed-off-by: Matthew Wilcox <matthew.r.wilcox@intel.com>
Reported-by: Vishal Verma <vishal.l.verma@intel.com>

Showing 1 changed file with 19 additions and 9 deletions Side-by-side Diff

drivers/block/nvme.c
... ... @@ -868,6 +868,15 @@
868 868 return nvme_submit_admin_cmd(dev, &c, result);
869 869 }
870 870  
  871 +static void nvme_free_queue_mem(struct nvme_queue *nvmeq)
  872 +{
  873 + dma_free_coherent(nvmeq->q_dmadev, CQ_SIZE(nvmeq->q_depth),
  874 + (void *)nvmeq->cqes, nvmeq->cq_dma_addr);
  875 + dma_free_coherent(nvmeq->q_dmadev, SQ_SIZE(nvmeq->q_depth),
  876 + nvmeq->sq_cmds, nvmeq->sq_dma_addr);
  877 + kfree(nvmeq);
  878 +}
  879 +
871 880 static void nvme_free_queue(struct nvme_dev *dev, int qid)
872 881 {
873 882 struct nvme_queue *nvmeq = dev->queues[qid];
... ... @@ -882,11 +891,7 @@
882 891 adapter_delete_cq(dev, qid);
883 892 }
884 893  
885   - dma_free_coherent(nvmeq->q_dmadev, CQ_SIZE(nvmeq->q_depth),
886   - (void *)nvmeq->cqes, nvmeq->cq_dma_addr);
887   - dma_free_coherent(nvmeq->q_dmadev, SQ_SIZE(nvmeq->q_depth),
888   - nvmeq->sq_cmds, nvmeq->sq_dma_addr);
889   - kfree(nvmeq);
  894 + nvme_free_queue_mem(nvmeq);
890 895 }
891 896  
892 897 static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid,
... ... @@ -982,7 +987,7 @@
982 987  
983 988 static int __devinit nvme_configure_admin_queue(struct nvme_dev *dev)
984 989 {
985   - int result;
  990 + int result = 0;
986 991 u32 aqa;
987 992 u64 cap;
988 993 unsigned long timeout;
989 994  
990 995  
991 996  
... ... @@ -1012,15 +1017,20 @@
1012 1017 timeout = ((NVME_CAP_TIMEOUT(cap) + 1) * HZ / 2) + jiffies;
1013 1018 dev->db_stride = NVME_CAP_STRIDE(cap);
1014 1019  
1015   - while (!(readl(&dev->bar->csts) & NVME_CSTS_RDY)) {
  1020 + while (!result && !(readl(&dev->bar->csts) & NVME_CSTS_RDY)) {
1016 1021 msleep(100);
1017 1022 if (fatal_signal_pending(current))
1018   - return -EINTR;
  1023 + result = -EINTR;
1019 1024 if (time_after(jiffies, timeout)) {
1020 1025 dev_err(&dev->pci_dev->dev,
1021 1026 "Device not ready; aborting initialisation\n");
1022   - return -ENODEV;
  1027 + result = -ENODEV;
1023 1028 }
  1029 + }
  1030 +
  1031 + if (result) {
  1032 + nvme_free_queue_mem(nvmeq);
  1033 + return result;
1024 1034 }
1025 1035  
1026 1036 result = queue_request_irq(dev, nvmeq, "nvme admin");