Linux-NVME Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] nvmet-rdma: Remove unused queue state
@ 2018-03-14 10:22 Israel Rukshin
  2018-03-14 10:22 ` [PATCH 2/2] nvmet-rdma: Fix use after free in nvmet_rdma_cm_handler() Israel Rukshin
  2018-03-15 20:58 ` [PATCH 1/2] nvmet-rdma: Remove unused queue state Keith Busch
  0 siblings, 2 replies; 3+ messages in thread
From: Israel Rukshin @ 2018-03-14 10:22 UTC (permalink / raw)


Signed-off-by: Israel Rukshin <israelr at mellanox.com>
Reviewed-by: Max Gurtovoy <maxg at mellanox.com>
---
 drivers/nvme/target/rdma.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c
index 978e169..58332e1 100644
--- a/drivers/nvme/target/rdma.c
+++ b/drivers/nvme/target/rdma.c
@@ -77,7 +77,6 @@ enum nvmet_rdma_queue_state {
 	NVMET_RDMA_Q_CONNECTING,
 	NVMET_RDMA_Q_LIVE,
 	NVMET_RDMA_Q_DISCONNECTING,
-	NVMET_RDMA_IN_DEVICE_REMOVAL,
 };
 
 struct nvmet_rdma_queue {
@@ -942,12 +941,10 @@ static void nvmet_rdma_release_queue_work(struct work_struct *w)
 		container_of(w, struct nvmet_rdma_queue, release_work);
 	struct rdma_cm_id *cm_id = queue->cm_id;
 	struct nvmet_rdma_device *dev = queue->dev;
-	enum nvmet_rdma_queue_state state = queue->state;
 
 	nvmet_rdma_free_queue(queue);
 
-	if (state != NVMET_RDMA_IN_DEVICE_REMOVAL)
-		rdma_destroy_id(cm_id);
+	rdma_destroy_id(cm_id);
 
 	kref_put(&dev->ref, nvmet_rdma_free_dev);
 }
@@ -1209,7 +1206,6 @@ static void __nvmet_rdma_queue_disconnect(struct nvmet_rdma_queue *queue)
 	case NVMET_RDMA_Q_CONNECTING:
 	case NVMET_RDMA_Q_LIVE:
 		queue->state = NVMET_RDMA_Q_DISCONNECTING;
-	case NVMET_RDMA_IN_DEVICE_REMOVAL:
 		disconnect = true;
 		break;
 	case NVMET_RDMA_Q_DISCONNECTING:
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] nvmet-rdma: Fix use after free in nvmet_rdma_cm_handler()
  2018-03-14 10:22 [PATCH 1/2] nvmet-rdma: Remove unused queue state Israel Rukshin
@ 2018-03-14 10:22 ` Israel Rukshin
  2018-03-15 20:58 ` [PATCH 1/2] nvmet-rdma: Remove unused queue state Keith Busch
  1 sibling, 0 replies; 3+ messages in thread
From: Israel Rukshin @ 2018-03-14 10:22 UTC (permalink / raw)


We free nvmet rdma queues while handling rdma_cm events.
In order to avoid this we destroy the qp and the queue after destroying
the cm_id which guarantees that all rdma_cm events are done.

Signed-off-by: Israel Rukshin <israelr at mellanox.com>
Reviewed-by: Max Gurtovoy <maxg at mellanox.com>
---
 drivers/nvme/target/rdma.c | 27 +++++++++++----------------
 1 file changed, 11 insertions(+), 16 deletions(-)

diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c
index 58332e1..210e4e3 100644
--- a/drivers/nvme/target/rdma.c
+++ b/drivers/nvme/target/rdma.c
@@ -913,8 +913,11 @@ static int nvmet_rdma_create_queue_ib(struct nvmet_rdma_queue *queue)
 
 static void nvmet_rdma_destroy_queue_ib(struct nvmet_rdma_queue *queue)
 {
-	ib_drain_qp(queue->cm_id->qp);
-	rdma_destroy_qp(queue->cm_id);
+	struct ib_qp *qp = queue->cm_id->qp;
+
+	ib_drain_qp(qp);
+	rdma_destroy_id(queue->cm_id);
+	ib_destroy_qp(qp);
 	ib_free_cq(queue->cq);
 }
 
@@ -939,13 +942,10 @@ static void nvmet_rdma_release_queue_work(struct work_struct *w)
 {
 	struct nvmet_rdma_queue *queue =
 		container_of(w, struct nvmet_rdma_queue, release_work);
-	struct rdma_cm_id *cm_id = queue->cm_id;
 	struct nvmet_rdma_device *dev = queue->dev;
 
 	nvmet_rdma_free_queue(queue);
 
-	rdma_destroy_id(cm_id);
-
 	kref_put(&dev->ref, nvmet_rdma_free_dev);
 }
 
@@ -1150,8 +1150,11 @@ static int nvmet_rdma_queue_connect(struct rdma_cm_id *cm_id,
 	}
 
 	ret = nvmet_rdma_cm_accept(cm_id, queue, &event->param.conn);
-	if (ret)
-		goto release_queue;
+	if (ret) {
+		schedule_work(&queue->release_work);
+		/* Destroying rdma_cm id is not needed here */
+		return 0;
+	}
 
 	mutex_lock(&nvmet_rdma_queue_mutex);
 	list_add_tail(&queue->queue_list, &nvmet_rdma_queue_list);
@@ -1159,8 +1162,6 @@ static int nvmet_rdma_queue_connect(struct rdma_cm_id *cm_id,
 
 	return 0;
 
-release_queue:
-	nvmet_rdma_free_queue(queue);
 put_device:
 	kref_put(&ndev->ref, nvmet_rdma_free_dev);
 
@@ -1318,13 +1319,7 @@ static int nvmet_rdma_cm_handler(struct rdma_cm_id *cm_id,
 	case RDMA_CM_EVENT_ADDR_CHANGE:
 	case RDMA_CM_EVENT_DISCONNECTED:
 	case RDMA_CM_EVENT_TIMEWAIT_EXIT:
-		/*
-		 * We might end up here when we already freed the qp
-		 * which means queue release sequence is in progress,
-		 * so don't get in the way...
-		 */
-		if (queue)
-			nvmet_rdma_queue_disconnect(queue);
+		nvmet_rdma_queue_disconnect(queue);
 		break;
 	case RDMA_CM_EVENT_DEVICE_REMOVAL:
 		ret = nvmet_rdma_device_removal(cm_id, queue);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 1/2] nvmet-rdma: Remove unused queue state
  2018-03-14 10:22 [PATCH 1/2] nvmet-rdma: Remove unused queue state Israel Rukshin
  2018-03-14 10:22 ` [PATCH 2/2] nvmet-rdma: Fix use after free in nvmet_rdma_cm_handler() Israel Rukshin
@ 2018-03-15 20:58 ` Keith Busch
  1 sibling, 0 replies; 3+ messages in thread
From: Keith Busch @ 2018-03-15 20:58 UTC (permalink / raw)


Thanks, series applied for 4.17.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2018-03-15 20:58 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-03-14 10:22 [PATCH 1/2] nvmet-rdma: Remove unused queue state Israel Rukshin
2018-03-14 10:22 ` [PATCH 2/2] nvmet-rdma: Fix use after free in nvmet_rdma_cm_handler() Israel Rukshin
2018-03-15 20:58 ` [PATCH 1/2] nvmet-rdma: Remove unused queue state Keith Busch

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox