nvmet-rdma: Avoid o(n^2) loop in delete_ctrl
authorSagi Grimberg <sagi.grimberg@vastdata.com>
Tue, 7 May 2024 06:54:44 +0000 (09:54 +0300)
committerKeith Busch <kbusch@kernel.org>
Tue, 7 May 2024 15:04:02 +0000 (08:04 -0700)
When deleting a nvmet-rdma ctrl, we essentially loop over all
queues that belong to the controller and schedule a removal of
each. Instead of restarting the loop every time a queue is found,
do a simple safe list traversal.

This addresses an unneeded time spent scheduling queue removal in
cases there a lot of queues.

Signed-off-by: Sagi Grimberg <sagi.grimberg@vastdata.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>
drivers/nvme/target/rdma.c

index 5b8c63e74639d7485fe7feedf514e06d7e7c1d4e..955296ac377f3d01ff36c6846bb5fa18bcb7252d 100644 (file)
@@ -1814,18 +1814,14 @@ static int nvmet_rdma_cm_handler(struct rdma_cm_id *cm_id,
 
 static void nvmet_rdma_delete_ctrl(struct nvmet_ctrl *ctrl)
 {
-       struct nvmet_rdma_queue *queue;
+       struct nvmet_rdma_queue *queue, *n;
 
-restart:
        mutex_lock(&nvmet_rdma_queue_mutex);
-       list_for_each_entry(queue, &nvmet_rdma_queue_list, queue_list) {
-               if (queue->nvme_sq.ctrl == ctrl) {
-                       list_del_init(&queue->queue_list);
-                       mutex_unlock(&nvmet_rdma_queue_mutex);
-
-                       __nvmet_rdma_queue_disconnect(queue);
-                       goto restart;
-               }
+       list_for_each_entry_safe(queue, n, &nvmet_rdma_queue_list, queue_list) {
+               if (queue->nvme_sq.ctrl != ctrl)
+                       continue;
+               list_del_init(&queue->queue_list);
+               __nvmet_rdma_queue_disconnect(queue);
        }
        mutex_unlock(&nvmet_rdma_queue_mutex);
 }