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; |
