aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSagi Grimberg <sagi@grimberg.me>2018-06-25 13:58:17 -0400
committerChristoph Hellwig <hch@lst.de>2018-06-28 10:29:54 -0400
commit682630f00a219a1b0696abe9c0967e660068187b (patch)
tree43a225e137266a0943308eca09fdfd62acf6638e /drivers
parent15bfd21fbc5d35834b9ea383dc458a1f0c9e3434 (diff)
nvme-rdma: fix possible double free of controller async event buffer
If reconnect/reset failed where the controller async event buffer was freed, we might end up freeing it again as we call nvme_rdma_destroy_admin_queue again in the remove path. Given that the sequence is guaranteed to serialize by .ctrl_stop, we simply set ctrl->async_event_sqe.data to NULL and don't free it in future visits. Reported-by: Max Gurtovoy <maxg@mellanox.com> Tested-by: Max Gurtovoy <maxg@mellanox.com> Signed-off-by: Sagi Grimberg <sagi@grimberg.me> Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/nvme/host/rdma.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index 9544625c0b7d..518c5b09038c 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -732,8 +732,11 @@ static void nvme_rdma_destroy_admin_queue(struct nvme_rdma_ctrl *ctrl,
732 blk_cleanup_queue(ctrl->ctrl.admin_q); 732 blk_cleanup_queue(ctrl->ctrl.admin_q);
733 nvme_rdma_free_tagset(&ctrl->ctrl, ctrl->ctrl.admin_tagset); 733 nvme_rdma_free_tagset(&ctrl->ctrl, ctrl->ctrl.admin_tagset);
734 } 734 }
735 nvme_rdma_free_qe(ctrl->device->dev, &ctrl->async_event_sqe, 735 if (ctrl->async_event_sqe.data) {
736 sizeof(struct nvme_command), DMA_TO_DEVICE); 736 nvme_rdma_free_qe(ctrl->device->dev, &ctrl->async_event_sqe,
737 sizeof(struct nvme_command), DMA_TO_DEVICE);
738 ctrl->async_event_sqe.data = NULL;
739 }
737 nvme_rdma_free_queue(&ctrl->queues[0]); 740 nvme_rdma_free_queue(&ctrl->queues[0]);
738} 741}
739 742