svcrdma: Add a utility workqueue to svcrdma
authorChuck Lever <chuck.lever@oracle.com>
Tue, 21 Nov 2023 16:40:26 +0000 (11:40 -0500)
committerChuck Lever <chuck.lever@oracle.com>
Sun, 7 Jan 2024 22:54:26 +0000 (17:54 -0500)
To handle work in the background, set up an UNBOUND workqueue for
svcrdma. Subsequent patches will make use of it.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
include/linux/sunrpc/svc_rdma.h
net/sunrpc/xprtrdma/svc_rdma.c
net/sunrpc/xprtrdma/svc_rdma_transport.c

index 4ac3289..e18c94e 100644 (file)
@@ -65,6 +65,7 @@ extern unsigned int svcrdma_ord;
 extern unsigned int svcrdma_max_requests;
 extern unsigned int svcrdma_max_bc_requests;
 extern unsigned int svcrdma_max_req_size;
+extern struct workqueue_struct *svcrdma_wq;
 
 extern struct percpu_counter svcrdma_stat_read;
 extern struct percpu_counter svcrdma_stat_recv;
index f0d5eee..f869707 100644 (file)
@@ -256,28 +256,44 @@ out_err:
        return rc;
 }
 
+struct workqueue_struct *svcrdma_wq;
+
 void svc_rdma_cleanup(void)
 {
-       dprintk("SVCRDMA Module Removed, deregister RPC RDMA transport\n");
        svc_unreg_xprt_class(&svc_rdma_class);
        svc_rdma_proc_cleanup();
+       if (svcrdma_wq) {
+               struct workqueue_struct *wq = svcrdma_wq;
+
+               svcrdma_wq = NULL;
+               destroy_workqueue(wq);
+       }
+
+       dprintk("SVCRDMA Module Removed, deregister RPC RDMA transport\n");
 }
 
 int svc_rdma_init(void)
 {
+       struct workqueue_struct *wq;
        int rc;
 
-       dprintk("SVCRDMA Module Init, register RPC RDMA transport\n");
-       dprintk("\tsvcrdma_ord      : %d\n", svcrdma_ord);
-       dprintk("\tmax_requests     : %u\n", svcrdma_max_requests);
-       dprintk("\tmax_bc_requests  : %u\n", svcrdma_max_bc_requests);
-       dprintk("\tmax_inline       : %d\n", svcrdma_max_req_size);
+       wq = alloc_workqueue("svcrdma", WQ_UNBOUND, 0);
+       if (!wq)
+               return -ENOMEM;
 
        rc = svc_rdma_proc_init();
-       if (rc)
+       if (rc) {
+               destroy_workqueue(wq);
                return rc;
+       }
 
-       /* Register RDMA with the SVC transport switch */
+       svcrdma_wq = wq;
        svc_reg_xprt_class(&svc_rdma_class);
+
+       dprintk("SVCRDMA Module Init, register RPC RDMA transport\n");
+       dprintk("\tsvcrdma_ord      : %d\n", svcrdma_ord);
+       dprintk("\tmax_requests     : %u\n", svcrdma_max_requests);
+       dprintk("\tmax_bc_requests  : %u\n", svcrdma_max_bc_requests);
+       dprintk("\tmax_inline       : %d\n", svcrdma_max_req_size);
        return 0;
 }
index 2abd895..c046916 100644 (file)
@@ -547,6 +547,7 @@ static void __svc_rdma_free(struct work_struct *work)
        /* This blocks until the Completion Queues are empty */
        if (rdma->sc_qp && !IS_ERR(rdma->sc_qp))
                ib_drain_qp(rdma->sc_qp);
+       flush_workqueue(svcrdma_wq);
 
        svc_rdma_flush_recv_queues(rdma);