Skip to content

Commit 15d9b01

Browse files
chuckleveramschuma-ntap
authored andcommitted
xprtrdma: Ensure ri_id is stable during MR recycling
ia->ri_id is replaced during a reconnect. The connect_worker runs with the transport send lock held to prevent ri_id from being dereferenced by the send_request path during this process. Currently, however, there is no guarantee that ia->ri_id is stable in the MR recycling worker, which operates in the background and is not serialized with the connect_worker in any way. But now that Local_Inv completions are being done in process context, we can handle the recycling operation there instead of deferring the recycling work to another process. Because the disconnect path drains all work before allowing tear down to proceed, it is guaranteed that Local Invalidations complete only while the ri_id pointer is stable. Signed-off-by: Chuck Lever <[email protected]> Signed-off-by: Anna Schumaker <[email protected]>
1 parent 9d2da4f commit 15d9b01

File tree

2 files changed

+6
-24
lines changed

2 files changed

+6
-24
lines changed

net/sunrpc/xprtrdma/frwr_ops.c

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,10 @@ void frwr_release_mr(struct rpcrdma_mr *mr)
8888
kfree(mr);
8989
}
9090

91-
static void frwr_mr_recycle(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr *mr)
91+
static void frwr_mr_recycle(struct rpcrdma_mr *mr)
9292
{
93+
struct rpcrdma_xprt *r_xprt = mr->mr_xprt;
94+
9395
trace_xprtrdma_mr_recycle(mr);
9496

9597
if (mr->mr_dir != DMA_NONE) {
@@ -107,18 +109,6 @@ static void frwr_mr_recycle(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr *mr)
107109
frwr_release_mr(mr);
108110
}
109111

110-
/* MRs are dynamically allocated, so simply clean up and release the MR.
111-
* A replacement MR will subsequently be allocated on demand.
112-
*/
113-
static void
114-
frwr_mr_recycle_worker(struct work_struct *work)
115-
{
116-
struct rpcrdma_mr *mr = container_of(work, struct rpcrdma_mr,
117-
mr_recycle);
118-
119-
frwr_mr_recycle(mr->mr_xprt, mr);
120-
}
121-
122112
/* frwr_reset - Place MRs back on the free list
123113
* @req: request to reset
124114
*
@@ -163,7 +153,6 @@ int frwr_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr)
163153
mr->frwr.fr_mr = frmr;
164154
mr->mr_dir = DMA_NONE;
165155
INIT_LIST_HEAD(&mr->mr_list);
166-
INIT_WORK(&mr->mr_recycle, frwr_mr_recycle_worker);
167156
init_completion(&mr->frwr.fr_linv_done);
168157

169158
sg_init_table(sg, depth);
@@ -448,7 +437,7 @@ void frwr_reminv(struct rpcrdma_rep *rep, struct list_head *mrs)
448437
static void __frwr_release_mr(struct ib_wc *wc, struct rpcrdma_mr *mr)
449438
{
450439
if (wc->status != IB_WC_SUCCESS)
451-
rpcrdma_mr_recycle(mr);
440+
frwr_mr_recycle(mr);
452441
else
453442
rpcrdma_mr_put(mr);
454443
}
@@ -570,7 +559,7 @@ void frwr_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)
570559
bad_wr = bad_wr->next;
571560

572561
list_del_init(&mr->mr_list);
573-
rpcrdma_mr_recycle(mr);
562+
frwr_mr_recycle(mr);
574563
}
575564
}
576565

@@ -664,7 +653,7 @@ void frwr_unmap_async(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)
664653
mr = container_of(frwr, struct rpcrdma_mr, frwr);
665654
bad_wr = bad_wr->next;
666655

667-
rpcrdma_mr_recycle(mr);
656+
frwr_mr_recycle(mr);
668657
}
669658

670659
/* The final LOCAL_INV WR in the chain is supposed to

net/sunrpc/xprtrdma/xprt_rdma.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,6 @@ struct rpcrdma_mr {
257257
u32 mr_handle;
258258
u32 mr_length;
259259
u64 mr_offset;
260-
struct work_struct mr_recycle;
261260
struct list_head mr_all;
262261
};
263262

@@ -490,12 +489,6 @@ struct rpcrdma_mr *rpcrdma_mr_get(struct rpcrdma_xprt *r_xprt);
490489
void rpcrdma_mr_put(struct rpcrdma_mr *mr);
491490
void rpcrdma_mrs_refresh(struct rpcrdma_xprt *r_xprt);
492491

493-
static inline void
494-
rpcrdma_mr_recycle(struct rpcrdma_mr *mr)
495-
{
496-
schedule_work(&mr->mr_recycle);
497-
}
498-
499492
struct rpcrdma_req *rpcrdma_buffer_get(struct rpcrdma_buffer *);
500493
void rpcrdma_buffer_put(struct rpcrdma_buffer *buffers,
501494
struct rpcrdma_req *req);

0 commit comments

Comments
 (0)