diff options
author | Matthew Wilcox <matthew.r.wilcox@intel.com> | 2012-08-03 13:55:56 -0400 |
---|---|---|
committer | Matthew Wilcox <matthew.r.wilcox@intel.com> | 2012-08-03 13:55:56 -0400 |
commit | 9e866774aab5d2654b0fa8f97890f68913f05700 (patch) | |
tree | a971538c8e58a72f9e14c6ba89b33bf7ab737220 | |
parent | cd58ad7d188c643cf572b038909c2f7dd96fdafe (diff) |
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>
-rw-r--r-- | drivers/block/nvme.c | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/drivers/block/nvme.c b/drivers/block/nvme.c index 3278fbdb8dc0..214037055e2a 100644 --- a/drivers/block/nvme.c +++ b/drivers/block/nvme.c | |||
@@ -868,6 +868,15 @@ static int nvme_set_features(struct nvme_dev *dev, unsigned fid, | |||
868 | return nvme_submit_admin_cmd(dev, &c, result); | 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 | static void nvme_free_queue(struct nvme_dev *dev, int qid) | 880 | static void nvme_free_queue(struct nvme_dev *dev, int qid) |
872 | { | 881 | { |
873 | struct nvme_queue *nvmeq = dev->queues[qid]; | 882 | struct nvme_queue *nvmeq = dev->queues[qid]; |
@@ -882,11 +891,7 @@ static void nvme_free_queue(struct nvme_dev *dev, int qid) | |||
882 | adapter_delete_cq(dev, qid); | 891 | adapter_delete_cq(dev, qid); |
883 | } | 892 | } |
884 | 893 | ||
885 | dma_free_coherent(nvmeq->q_dmadev, CQ_SIZE(nvmeq->q_depth), | 894 | nvme_free_queue_mem(nvmeq); |
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); | ||
890 | } | 895 | } |
891 | 896 | ||
892 | static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid, | 897 | static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid, |
@@ -982,7 +987,7 @@ static __devinit struct nvme_queue *nvme_create_queue(struct nvme_dev *dev, | |||
982 | 987 | ||
983 | static int __devinit nvme_configure_admin_queue(struct nvme_dev *dev) | 988 | static int __devinit nvme_configure_admin_queue(struct nvme_dev *dev) |
984 | { | 989 | { |
985 | int result; | 990 | int result = 0; |
986 | u32 aqa; | 991 | u32 aqa; |
987 | u64 cap; | 992 | u64 cap; |
988 | unsigned long timeout; | 993 | unsigned long timeout; |
@@ -1012,17 +1017,22 @@ static int __devinit nvme_configure_admin_queue(struct nvme_dev *dev) | |||
1012 | timeout = ((NVME_CAP_TIMEOUT(cap) + 1) * HZ / 2) + jiffies; | 1017 | timeout = ((NVME_CAP_TIMEOUT(cap) + 1) * HZ / 2) + jiffies; |
1013 | dev->db_stride = NVME_CAP_STRIDE(cap); | 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 | msleep(100); | 1021 | msleep(100); |
1017 | if (fatal_signal_pending(current)) | 1022 | if (fatal_signal_pending(current)) |
1018 | return -EINTR; | 1023 | result = -EINTR; |
1019 | if (time_after(jiffies, timeout)) { | 1024 | if (time_after(jiffies, timeout)) { |
1020 | dev_err(&dev->pci_dev->dev, | 1025 | dev_err(&dev->pci_dev->dev, |
1021 | "Device not ready; aborting initialisation\n"); | 1026 | "Device not ready; aborting initialisation\n"); |
1022 | return -ENODEV; | 1027 | result = -ENODEV; |
1023 | } | 1028 | } |
1024 | } | 1029 | } |
1025 | 1030 | ||
1031 | if (result) { | ||
1032 | nvme_free_queue_mem(nvmeq); | ||
1033 | return result; | ||
1034 | } | ||
1035 | |||
1026 | result = queue_request_irq(dev, nvmeq, "nvme admin"); | 1036 | result = queue_request_irq(dev, nvmeq, "nvme admin"); |
1027 | dev->queues[0] = nvmeq; | 1037 | dev->queues[0] = nvmeq; |
1028 | return result; | 1038 | return result; |