@@ -49,46 +49,7 @@ fmr_is_supported(struct rpcrdma_ia *ia)
4949 return true;
5050}
5151
52- static int
53- fmr_op_init_mr (struct rpcrdma_ia * ia , struct rpcrdma_mr * mr )
54- {
55- static struct ib_fmr_attr fmr_attr = {
56- .max_pages = RPCRDMA_MAX_FMR_SGES ,
57- .max_maps = 1 ,
58- .page_shift = PAGE_SHIFT
59- };
60-
61- mr -> fmr .fm_physaddrs = kcalloc (RPCRDMA_MAX_FMR_SGES ,
62- sizeof (u64 ), GFP_KERNEL );
63- if (!mr -> fmr .fm_physaddrs )
64- goto out_free ;
65-
66- mr -> mr_sg = kcalloc (RPCRDMA_MAX_FMR_SGES ,
67- sizeof (* mr -> mr_sg ), GFP_KERNEL );
68- if (!mr -> mr_sg )
69- goto out_free ;
70-
71- sg_init_table (mr -> mr_sg , RPCRDMA_MAX_FMR_SGES );
72-
73- mr -> fmr .fm_mr = ib_alloc_fmr (ia -> ri_pd , RPCRDMA_FMR_ACCESS_FLAGS ,
74- & fmr_attr );
75- if (IS_ERR (mr -> fmr .fm_mr ))
76- goto out_fmr_err ;
77-
78- INIT_LIST_HEAD (& mr -> mr_list );
79- return 0 ;
80-
81- out_fmr_err :
82- dprintk ("RPC: %s: ib_alloc_fmr returned %ld\n" , __func__ ,
83- PTR_ERR (mr -> fmr .fm_mr ));
84-
85- out_free :
86- kfree (mr -> mr_sg );
87- kfree (mr -> fmr .fm_physaddrs );
88- return - ENOMEM ;
89- }
90-
91- static int
52+ static void
9253__fmr_unmap (struct rpcrdma_mr * mr )
9354{
9455 LIST_HEAD (l );
@@ -97,13 +58,16 @@ __fmr_unmap(struct rpcrdma_mr *mr)
9758 list_add (& mr -> fmr .fm_mr -> list , & l );
9859 rc = ib_unmap_fmr (& l );
9960 list_del (& mr -> fmr .fm_mr -> list );
100- return rc ;
61+ if (rc )
62+ pr_err ("rpcrdma: final ib_unmap_fmr for %p failed %i\n" ,
63+ mr , rc );
10164}
10265
66+ /* Release an MR.
67+ */
10368static void
10469fmr_op_release_mr (struct rpcrdma_mr * mr )
10570{
106- LIST_HEAD (unmap_list );
10771 int rc ;
10872
10973 kfree (mr -> fmr .fm_physaddrs );
@@ -112,10 +76,7 @@ fmr_op_release_mr(struct rpcrdma_mr *mr)
11276 /* In case this one was left mapped, try to unmap it
11377 * to prevent dealloc_fmr from failing with EBUSY
11478 */
115- rc = __fmr_unmap (mr );
116- if (rc )
117- pr_err ("rpcrdma: final ib_unmap_fmr for %p failed %i\n" ,
118- mr , rc );
79+ __fmr_unmap (mr );
11980
12081 rc = ib_dealloc_fmr (mr -> fmr .fm_mr );
12182 if (rc )
@@ -125,40 +86,68 @@ fmr_op_release_mr(struct rpcrdma_mr *mr)
12586 kfree (mr );
12687}
12788
128- /* Reset of a single FMR.
89+ /* MRs are dynamically allocated, so simply clean up and release the MR.
90+ * A replacement MR will subsequently be allocated on demand.
12991 */
13092static void
131- fmr_op_recover_mr (struct rpcrdma_mr * mr )
93+ fmr_mr_recycle_worker (struct work_struct * work )
13294{
95+ struct rpcrdma_mr * mr = container_of (work , struct rpcrdma_mr , mr_recycle );
13396 struct rpcrdma_xprt * r_xprt = mr -> mr_xprt ;
134- int rc ;
13597
136- /* ORDER: invalidate first */
137- rc = __fmr_unmap (mr );
138- if (rc )
139- goto out_release ;
140-
141- /* ORDER: then DMA unmap */
142- rpcrdma_mr_unmap_and_put (mr );
143-
144- r_xprt -> rx_stats .mrs_recovered ++ ;
145- return ;
146-
147- out_release :
148- pr_err ("rpcrdma: FMR reset failed (%d), %p released\n" , rc , mr );
149- r_xprt -> rx_stats .mrs_orphaned ++ ;
98+ trace_xprtrdma_mr_recycle (mr );
15099
151100 trace_xprtrdma_dma_unmap (mr );
152101 ib_dma_unmap_sg (r_xprt -> rx_ia .ri_device ,
153102 mr -> mr_sg , mr -> mr_nents , mr -> mr_dir );
154103
155104 spin_lock (& r_xprt -> rx_buf .rb_mrlock );
156105 list_del (& mr -> mr_all );
106+ r_xprt -> rx_stats .mrs_recycled ++ ;
157107 spin_unlock (& r_xprt -> rx_buf .rb_mrlock );
158-
159108 fmr_op_release_mr (mr );
160109}
161110
111+ static int
112+ fmr_op_init_mr (struct rpcrdma_ia * ia , struct rpcrdma_mr * mr )
113+ {
114+ static struct ib_fmr_attr fmr_attr = {
115+ .max_pages = RPCRDMA_MAX_FMR_SGES ,
116+ .max_maps = 1 ,
117+ .page_shift = PAGE_SHIFT
118+ };
119+
120+ mr -> fmr .fm_physaddrs = kcalloc (RPCRDMA_MAX_FMR_SGES ,
121+ sizeof (u64 ), GFP_KERNEL );
122+ if (!mr -> fmr .fm_physaddrs )
123+ goto out_free ;
124+
125+ mr -> mr_sg = kcalloc (RPCRDMA_MAX_FMR_SGES ,
126+ sizeof (* mr -> mr_sg ), GFP_KERNEL );
127+ if (!mr -> mr_sg )
128+ goto out_free ;
129+
130+ sg_init_table (mr -> mr_sg , RPCRDMA_MAX_FMR_SGES );
131+
132+ mr -> fmr .fm_mr = ib_alloc_fmr (ia -> ri_pd , RPCRDMA_FMR_ACCESS_FLAGS ,
133+ & fmr_attr );
134+ if (IS_ERR (mr -> fmr .fm_mr ))
135+ goto out_fmr_err ;
136+
137+ INIT_LIST_HEAD (& mr -> mr_list );
138+ INIT_WORK (& mr -> mr_recycle , fmr_mr_recycle_worker );
139+ return 0 ;
140+
141+ out_fmr_err :
142+ dprintk ("RPC: %s: ib_alloc_fmr returned %ld\n" , __func__ ,
143+ PTR_ERR (mr -> fmr .fm_mr ));
144+
145+ out_free :
146+ kfree (mr -> mr_sg );
147+ kfree (mr -> fmr .fm_physaddrs );
148+ return - ENOMEM ;
149+ }
150+
162151/* On success, sets:
163152 * ep->rep_attr.cap.max_send_wr
164153 * ep->rep_attr.cap.max_recv_wr
@@ -312,7 +301,7 @@ fmr_op_unmap_sync(struct rpcrdma_xprt *r_xprt, struct list_head *mrs)
312301 r_xprt -> rx_stats .local_inv_needed ++ ;
313302 rc = ib_unmap_fmr (& unmap_list );
314303 if (rc )
315- goto out_reset ;
304+ goto out_release ;
316305
317306 /* ORDER: Now DMA unmap all of the req's MRs, and return
318307 * them to the free MW list.
@@ -325,21 +314,20 @@ fmr_op_unmap_sync(struct rpcrdma_xprt *r_xprt, struct list_head *mrs)
325314
326315 return ;
327316
328- out_reset :
317+ out_release :
329318 pr_err ("rpcrdma: ib_unmap_fmr failed (%i)\n" , rc );
330319
331320 while (!list_empty (mrs )) {
332321 mr = rpcrdma_mr_pop (mrs );
333322 list_del (& mr -> fmr .fm_mr -> list );
334- fmr_op_recover_mr (mr );
323+ rpcrdma_mr_recycle (mr );
335324 }
336325}
337326
338327const struct rpcrdma_memreg_ops rpcrdma_fmr_memreg_ops = {
339328 .ro_map = fmr_op_map ,
340329 .ro_send = fmr_op_send ,
341330 .ro_unmap_sync = fmr_op_unmap_sync ,
342- .ro_recover_mr = fmr_op_recover_mr ,
343331 .ro_open = fmr_op_open ,
344332 .ro_maxpages = fmr_op_maxpages ,
345333 .ro_init_mr = fmr_op_init_mr ,
0 commit comments