Whamcloud - gitweb
LU-17249 ptlrpc: protect scp_rqbd_idle list operations
authorMikhail Pershin <mpershin@whamcloud.com>
Wed, 1 Nov 2023 14:55:39 +0000 (17:55 +0300)
committerAndreas Dilger <adilger@whamcloud.com>
Thu, 9 Nov 2023 08:41:14 +0000 (08:41 +0000)
Protect scp_rqbd_idle list entry getting by spinlock
in ptlrpc_service_purge_all() like it does in all
other places where rqbd_list linkage is being managed

Lustre-change: https://review.whamcloud.com/52931
Lustre-commit: 9ba375983d498690f5caa29c289c137470a76505

Test-Parameters: testgroup=full-part-1 env="SLOW=yes,ENABLE_QUOTA=yes"
Signed-off-by: Mikhail Pershin <mpershin@whamcloud.com>
Change-Id: Iace37b1ee79bfd0c3a54a35722952e17d860a91c
Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/52952
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
lustre/ptlrpc/service.c

index b81a941..e39cd5c 100644 (file)
@@ -107,11 +107,6 @@ static void ptlrpc_free_rqbd(struct ptlrpc_request_buffer_desc *rqbd)
        LASSERT(rqbd->rqbd_refcount == 0);
        LASSERT(list_empty(&rqbd->rqbd_reqs));
 
-       spin_lock(&svcpt->scp_lock);
-       list_del(&rqbd->rqbd_list);
-       svcpt->scp_nrqbds_total--;
-       spin_unlock(&svcpt->scp_lock);
-
        OBD_FREE_LARGE(rqbd->rqbd_buffer, svcpt->scp_service->srv_buf_size);
        OBD_FREE_PTR(rqbd);
 }
@@ -3550,13 +3545,20 @@ ptlrpc_service_purge_all(struct ptlrpc_service *svc)
                 * Now free all the request buffers since nothing
                 * references them any more...
                 */
-
+               spin_lock(&svcpt->scp_lock);
                while (!list_empty(&svcpt->scp_rqbd_idle)) {
                        rqbd = list_entry(svcpt->scp_rqbd_idle.next,
                                              struct ptlrpc_request_buffer_desc,
                                              rqbd_list);
+                       list_del(&rqbd->rqbd_list);
+                       svcpt->scp_nrqbds_total--;
+                       spin_unlock(&svcpt->scp_lock);
+
                        ptlrpc_free_rqbd(rqbd);
+                       spin_lock(&svcpt->scp_lock);
                }
+               spin_unlock(&svcpt->scp_lock);
+
                ptlrpc_wait_replies(svcpt);
 
                while (!list_empty(&svcpt->scp_rep_idle)) {