aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/xprtrdma
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2015-03-30 14:35:35 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2015-03-31 09:52:53 -0400
commite46ac34c3c34e408435656a5fed605c4c787d081 (patch)
treeb0d20c2172ba82d6548f8c6769c60521c1a37b5e /net/sunrpc/xprtrdma
parent3968cb58501bf526eed1441f4ef237028aa9cd2d (diff)
xprtrdma: Handle non-SEND completions via a callout
Allow each memory registration mode to plug in a callout that handles the completion of a memory registration operation. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Reviewed-by: Sagi Grimberg <sagig@mellanox.com> Tested-by: Devesh Sharma <Devesh.Sharma@Emulex.Com> Tested-by: Meghana Cheripady <Meghana.Cheripady@Emulex.Com> Tested-by: Veeresh U. Kokatnur <veereshuk@chelsio.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'net/sunrpc/xprtrdma')
-rw-r--r--net/sunrpc/xprtrdma/frwr_ops.c17
-rw-r--r--net/sunrpc/xprtrdma/verbs.c16
-rw-r--r--net/sunrpc/xprtrdma/xprt_rdma.h5
3 files changed, 28 insertions, 10 deletions
diff --git a/net/sunrpc/xprtrdma/frwr_ops.c b/net/sunrpc/xprtrdma/frwr_ops.c
index e17d54d473a7..ea59c1b435ff 100644
--- a/net/sunrpc/xprtrdma/frwr_ops.c
+++ b/net/sunrpc/xprtrdma/frwr_ops.c
@@ -117,6 +117,22 @@ frwr_op_maxpages(struct rpcrdma_xprt *r_xprt)
117 rpcrdma_max_segments(r_xprt) * ia->ri_max_frmr_depth); 117 rpcrdma_max_segments(r_xprt) * ia->ri_max_frmr_depth);
118} 118}
119 119
120/* If FAST_REG or LOCAL_INV failed, indicate the frmr needs to be reset. */
121static void
122frwr_sendcompletion(struct ib_wc *wc)
123{
124 struct rpcrdma_mw *r;
125
126 if (likely(wc->status == IB_WC_SUCCESS))
127 return;
128
129 /* WARNING: Only wr_id and status are reliable at this point */
130 r = (struct rpcrdma_mw *)(unsigned long)wc->wr_id;
131 dprintk("RPC: %s: frmr %p (stale), status %d\n",
132 __func__, r, wc->status);
133 r->r.frmr.fr_state = FRMR_IS_STALE;
134}
135
120static int 136static int
121frwr_op_init(struct rpcrdma_xprt *r_xprt) 137frwr_op_init(struct rpcrdma_xprt *r_xprt)
122{ 138{
@@ -148,6 +164,7 @@ frwr_op_init(struct rpcrdma_xprt *r_xprt)
148 164
149 list_add(&r->mw_list, &buf->rb_mws); 165 list_add(&r->mw_list, &buf->rb_mws);
150 list_add(&r->mw_all, &buf->rb_all); 166 list_add(&r->mw_all, &buf->rb_all);
167 r->mw_sendcompletion = frwr_sendcompletion;
151 } 168 }
152 169
153 return 0; 170 return 0;
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
index b697b3ed6273..cac06f290a26 100644
--- a/net/sunrpc/xprtrdma/verbs.c
+++ b/net/sunrpc/xprtrdma/verbs.c
@@ -186,7 +186,7 @@ static const char * const wc_status[] = {
186 "remote access error", 186 "remote access error",
187 "remote operation error", 187 "remote operation error",
188 "transport retry counter exceeded", 188 "transport retry counter exceeded",
189 "RNR retrycounter exceeded", 189 "RNR retry counter exceeded",
190 "local RDD violation error", 190 "local RDD violation error",
191 "remove invalid RD request", 191 "remove invalid RD request",
192 "operation aborted", 192 "operation aborted",
@@ -204,21 +204,17 @@ static const char * const wc_status[] = {
204static void 204static void
205rpcrdma_sendcq_process_wc(struct ib_wc *wc) 205rpcrdma_sendcq_process_wc(struct ib_wc *wc)
206{ 206{
207 if (likely(wc->status == IB_WC_SUCCESS))
208 return;
209
210 /* WARNING: Only wr_id and status are reliable at this point */ 207 /* WARNING: Only wr_id and status are reliable at this point */
211 if (wc->wr_id == 0ULL) { 208 if (wc->wr_id == RPCRDMA_IGNORE_COMPLETION) {
212 if (wc->status != IB_WC_WR_FLUSH_ERR) 209 if (wc->status != IB_WC_SUCCESS &&
210 wc->status != IB_WC_WR_FLUSH_ERR)
213 pr_err("RPC: %s: SEND: %s\n", 211 pr_err("RPC: %s: SEND: %s\n",
214 __func__, COMPLETION_MSG(wc->status)); 212 __func__, COMPLETION_MSG(wc->status));
215 } else { 213 } else {
216 struct rpcrdma_mw *r; 214 struct rpcrdma_mw *r;
217 215
218 r = (struct rpcrdma_mw *)(unsigned long)wc->wr_id; 216 r = (struct rpcrdma_mw *)(unsigned long)wc->wr_id;
219 r->r.frmr.fr_state = FRMR_IS_STALE; 217 r->mw_sendcompletion(wc);
220 pr_err("RPC: %s: frmr %p (stale): %s\n",
221 __func__, r, COMPLETION_MSG(wc->status));
222 } 218 }
223} 219}
224 220
@@ -1622,7 +1618,7 @@ rpcrdma_ep_post(struct rpcrdma_ia *ia,
1622 } 1618 }
1623 1619
1624 send_wr.next = NULL; 1620 send_wr.next = NULL;
1625 send_wr.wr_id = 0ULL; /* no send cookie */ 1621 send_wr.wr_id = RPCRDMA_IGNORE_COMPLETION;
1626 send_wr.sg_list = req->rl_send_iov; 1622 send_wr.sg_list = req->rl_send_iov;
1627 send_wr.num_sge = req->rl_niovs; 1623 send_wr.num_sge = req->rl_niovs;
1628 send_wr.opcode = IB_WR_SEND; 1624 send_wr.opcode = IB_WR_SEND;
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h
index 9036fb4174d5..54bcbe47075d 100644
--- a/net/sunrpc/xprtrdma/xprt_rdma.h
+++ b/net/sunrpc/xprtrdma/xprt_rdma.h
@@ -106,6 +106,10 @@ struct rpcrdma_ep {
106#define INIT_CQCOUNT(ep) atomic_set(&(ep)->rep_cqcount, (ep)->rep_cqinit) 106#define INIT_CQCOUNT(ep) atomic_set(&(ep)->rep_cqcount, (ep)->rep_cqinit)
107#define DECR_CQCOUNT(ep) atomic_sub_return(1, &(ep)->rep_cqcount) 107#define DECR_CQCOUNT(ep) atomic_sub_return(1, &(ep)->rep_cqcount)
108 108
109/* Force completion handler to ignore the signal
110 */
111#define RPCRDMA_IGNORE_COMPLETION (0ULL)
112
109/* Registered buffer -- registered kmalloc'd memory for RDMA SEND/RECV 113/* Registered buffer -- registered kmalloc'd memory for RDMA SEND/RECV
110 * 114 *
111 * The below structure appears at the front of a large region of kmalloc'd 115 * The below structure appears at the front of a large region of kmalloc'd
@@ -206,6 +210,7 @@ struct rpcrdma_mw {
206 struct ib_fmr *fmr; 210 struct ib_fmr *fmr;
207 struct rpcrdma_frmr frmr; 211 struct rpcrdma_frmr frmr;
208 } r; 212 } r;
213 void (*mw_sendcompletion)(struct ib_wc *);
209 struct list_head mw_list; 214 struct list_head mw_list;
210 struct list_head mw_all; 215 struct list_head mw_all;
211}; 216};