@@ -49,46 +49,7 @@ fmr_is_supported(struct rpcrdma_ia *ia)
49
49
return true;
50
50
}
51
51
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
92
53
__fmr_unmap (struct rpcrdma_mr * mr )
93
54
{
94
55
LIST_HEAD (l );
@@ -97,13 +58,16 @@ __fmr_unmap(struct rpcrdma_mr *mr)
97
58
list_add (& mr -> fmr .fm_mr -> list , & l );
98
59
rc = ib_unmap_fmr (& l );
99
60
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 );
101
64
}
102
65
66
+ /* Release an MR.
67
+ */
103
68
static void
104
69
fmr_op_release_mr (struct rpcrdma_mr * mr )
105
70
{
106
- LIST_HEAD (unmap_list );
107
71
int rc ;
108
72
109
73
kfree (mr -> fmr .fm_physaddrs );
@@ -112,10 +76,7 @@ fmr_op_release_mr(struct rpcrdma_mr *mr)
112
76
/* In case this one was left mapped, try to unmap it
113
77
* to prevent dealloc_fmr from failing with EBUSY
114
78
*/
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 );
119
80
120
81
rc = ib_dealloc_fmr (mr -> fmr .fm_mr );
121
82
if (rc )
@@ -125,40 +86,68 @@ fmr_op_release_mr(struct rpcrdma_mr *mr)
125
86
kfree (mr );
126
87
}
127
88
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.
129
91
*/
130
92
static void
131
- fmr_op_recover_mr (struct rpcrdma_mr * mr )
93
+ fmr_mr_recycle_worker (struct work_struct * work )
132
94
{
95
+ struct rpcrdma_mr * mr = container_of (work , struct rpcrdma_mr , mr_recycle );
133
96
struct rpcrdma_xprt * r_xprt = mr -> mr_xprt ;
134
- int rc ;
135
97
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 );
98
+ trace_xprtrdma_mr_recycle (mr );
143
99
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 ++ ;
150
-
151
- trace_xprtrdma_dma_unmap (mr );
100
+ trace_xprtrdma_mr_unmap (mr );
152
101
ib_dma_unmap_sg (r_xprt -> rx_ia .ri_device ,
153
102
mr -> mr_sg , mr -> mr_nents , mr -> mr_dir );
154
103
155
104
spin_lock (& r_xprt -> rx_buf .rb_mrlock );
156
105
list_del (& mr -> mr_all );
106
+ r_xprt -> rx_stats .mrs_recycled ++ ;
157
107
spin_unlock (& r_xprt -> rx_buf .rb_mrlock );
158
-
159
108
fmr_op_release_mr (mr );
160
109
}
161
110
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
+
162
151
/* On success, sets:
163
152
* ep->rep_attr.cap.max_send_wr
164
153
* ep->rep_attr.cap.max_recv_wr
@@ -187,6 +176,7 @@ fmr_op_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep,
187
176
188
177
ia -> ri_max_segs = max_t (unsigned int , 1 , RPCRDMA_MAX_DATA_SEGS /
189
178
RPCRDMA_MAX_FMR_SGES );
179
+ ia -> ri_max_segs += 2 ; /* segments for head and tail buffers */
190
180
return 0 ;
191
181
}
192
182
@@ -244,7 +234,7 @@ fmr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg,
244
234
mr -> mr_sg , i , mr -> mr_dir );
245
235
if (!mr -> mr_nents )
246
236
goto out_dmamap_err ;
247
- trace_xprtrdma_dma_map (mr );
237
+ trace_xprtrdma_mr_map (mr );
248
238
249
239
for (i = 0 , dma_pages = mr -> fmr .fm_physaddrs ; i < mr -> mr_nents ; i ++ )
250
240
dma_pages [i ] = sg_dma_address (& mr -> mr_sg [i ]);
@@ -305,13 +295,13 @@ fmr_op_unmap_sync(struct rpcrdma_xprt *r_xprt, struct list_head *mrs)
305
295
list_for_each_entry (mr , mrs , mr_list ) {
306
296
dprintk ("RPC: %s: unmapping fmr %p\n" ,
307
297
__func__ , & mr -> fmr );
308
- trace_xprtrdma_localinv (mr );
298
+ trace_xprtrdma_mr_localinv (mr );
309
299
list_add_tail (& mr -> fmr .fm_mr -> list , & unmap_list );
310
300
}
311
301
r_xprt -> rx_stats .local_inv_needed ++ ;
312
302
rc = ib_unmap_fmr (& unmap_list );
313
303
if (rc )
314
- goto out_reset ;
304
+ goto out_release ;
315
305
316
306
/* ORDER: Now DMA unmap all of the req's MRs, and return
317
307
* them to the free MW list.
@@ -324,21 +314,20 @@ fmr_op_unmap_sync(struct rpcrdma_xprt *r_xprt, struct list_head *mrs)
324
314
325
315
return ;
326
316
327
- out_reset :
317
+ out_release :
328
318
pr_err ("rpcrdma: ib_unmap_fmr failed (%i)\n" , rc );
329
319
330
320
while (!list_empty (mrs )) {
331
321
mr = rpcrdma_mr_pop (mrs );
332
322
list_del (& mr -> fmr .fm_mr -> list );
333
- fmr_op_recover_mr (mr );
323
+ rpcrdma_mr_recycle (mr );
334
324
}
335
325
}
336
326
337
327
const struct rpcrdma_memreg_ops rpcrdma_fmr_memreg_ops = {
338
328
.ro_map = fmr_op_map ,
339
329
.ro_send = fmr_op_send ,
340
330
.ro_unmap_sync = fmr_op_unmap_sync ,
341
- .ro_recover_mr = fmr_op_recover_mr ,
342
331
.ro_open = fmr_op_open ,
343
332
.ro_maxpages = fmr_op_maxpages ,
344
333
.ro_init_mr = fmr_op_init_mr ,
0 commit comments