xprtrdma: Make sendctx queue lifetime the same as connection lifetime

The size of the sendctx queue depends on the value stored in
ia->ri_max_send_sges. This value is determined by querying the
underlying device.

Eventually, rpcrdma_ia_open() and rpcrdma_ep_create() will be called
in the connect worker rather than at transport set-up time. The
underlying device will not have been chosen device set-up time.

The sendctx queue will thus have to be created after the underlying
device has been chosen via address and route resolution; in other
words, in the connect worker.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
Chuck Lever 2020-01-03 11:56:32 -05:00 committed by Anna Schumaker
parent 2e87036814
commit cb586decbb
2 changed files with 23 additions and 11 deletions

View file

@ -729,6 +729,7 @@ TRACE_EVENT(xprtrdma_post_send,
TP_STRUCT__entry( TP_STRUCT__entry(
__field(const void *, req) __field(const void *, req)
__field(const void *, sc)
__field(unsigned int, task_id) __field(unsigned int, task_id)
__field(unsigned int, client_id) __field(unsigned int, client_id)
__field(int, num_sge) __field(int, num_sge)
@ -743,14 +744,15 @@ TRACE_EVENT(xprtrdma_post_send,
__entry->client_id = rqst->rq_task->tk_client ? __entry->client_id = rqst->rq_task->tk_client ?
rqst->rq_task->tk_client->cl_clid : -1; rqst->rq_task->tk_client->cl_clid : -1;
__entry->req = req; __entry->req = req;
__entry->sc = req->rl_sendctx;
__entry->num_sge = req->rl_wr.num_sge; __entry->num_sge = req->rl_wr.num_sge;
__entry->signaled = req->rl_wr.send_flags & IB_SEND_SIGNALED; __entry->signaled = req->rl_wr.send_flags & IB_SEND_SIGNALED;
__entry->status = status; __entry->status = status;
), ),
TP_printk("task:%u@%u req=%p (%d SGE%s) %sstatus=%d", TP_printk("task:%u@%u req=%p sc=%p (%d SGE%s) %sstatus=%d",
__entry->task_id, __entry->client_id, __entry->task_id, __entry->client_id,
__entry->req, __entry->num_sge, __entry->req, __entry->sc, __entry->num_sge,
(__entry->num_sge == 1 ? "" : "s"), (__entry->num_sge == 1 ? "" : "s"),
(__entry->signaled ? "signaled " : ""), (__entry->signaled ? "signaled " : ""),
__entry->status __entry->status
@ -849,6 +851,7 @@ TRACE_EVENT(xprtrdma_wc_send,
TP_STRUCT__entry( TP_STRUCT__entry(
__field(const void *, req) __field(const void *, req)
__field(const void *, sc)
__field(unsigned int, unmap_count) __field(unsigned int, unmap_count)
__field(unsigned int, status) __field(unsigned int, status)
__field(unsigned int, vendor_err) __field(unsigned int, vendor_err)
@ -856,13 +859,14 @@ TRACE_EVENT(xprtrdma_wc_send,
TP_fast_assign( TP_fast_assign(
__entry->req = sc->sc_req; __entry->req = sc->sc_req;
__entry->sc = sc;
__entry->unmap_count = sc->sc_unmap_count; __entry->unmap_count = sc->sc_unmap_count;
__entry->status = wc->status; __entry->status = wc->status;
__entry->vendor_err = __entry->status ? wc->vendor_err : 0; __entry->vendor_err = __entry->status ? wc->vendor_err : 0;
), ),
TP_printk("req=%p, unmapped %u pages: %s (%u/0x%x)", TP_printk("req=%p sc=%p unmapped=%u: %s (%u/0x%x)",
__entry->req, __entry->unmap_count, __entry->req, __entry->sc, __entry->unmap_count,
rdma_show_wc_status(__entry->status), rdma_show_wc_status(__entry->status),
__entry->status, __entry->vendor_err __entry->status, __entry->vendor_err
) )

View file

@ -74,6 +74,8 @@
/* /*
* internal functions * internal functions
*/ */
static int rpcrdma_sendctxs_create(struct rpcrdma_xprt *r_xprt);
static void rpcrdma_sendctxs_destroy(struct rpcrdma_xprt *r_xprt);
static void rpcrdma_sendctx_put_locked(struct rpcrdma_xprt *r_xprt, static void rpcrdma_sendctx_put_locked(struct rpcrdma_xprt *r_xprt,
struct rpcrdma_sendctx *sc); struct rpcrdma_sendctx *sc);
static void rpcrdma_reqs_reset(struct rpcrdma_xprt *r_xprt); static void rpcrdma_reqs_reset(struct rpcrdma_xprt *r_xprt);
@ -428,6 +430,7 @@ rpcrdma_ia_remove(struct rpcrdma_ia *ia)
rpcrdma_regbuf_dma_unmap(req->rl_recvbuf); rpcrdma_regbuf_dma_unmap(req->rl_recvbuf);
} }
rpcrdma_mrs_destroy(r_xprt); rpcrdma_mrs_destroy(r_xprt);
rpcrdma_sendctxs_destroy(r_xprt);
ib_dealloc_pd(ia->ri_pd); ib_dealloc_pd(ia->ri_pd);
ia->ri_pd = NULL; ia->ri_pd = NULL;
@ -705,6 +708,10 @@ retry:
rpcrdma_reset_cwnd(r_xprt); rpcrdma_reset_cwnd(r_xprt);
rpcrdma_post_recvs(r_xprt, true); rpcrdma_post_recvs(r_xprt, true);
rc = rpcrdma_sendctxs_create(r_xprt);
if (rc)
goto out;
rc = rdma_connect(ia->ri_id, &ep->rep_remote_cma); rc = rdma_connect(ia->ri_id, &ep->rep_remote_cma);
if (rc) if (rc)
goto out; goto out;
@ -757,6 +764,7 @@ rpcrdma_ep_disconnect(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
rpcrdma_xprt_drain(r_xprt); rpcrdma_xprt_drain(r_xprt);
rpcrdma_reqs_reset(r_xprt); rpcrdma_reqs_reset(r_xprt);
rpcrdma_mrs_destroy(r_xprt); rpcrdma_mrs_destroy(r_xprt);
rpcrdma_sendctxs_destroy(r_xprt);
} }
/* Fixed-size circular FIFO queue. This implementation is wait-free and /* Fixed-size circular FIFO queue. This implementation is wait-free and
@ -776,13 +784,17 @@ rpcrdma_ep_disconnect(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
* queue activity, and rpcrdma_xprt_drain has flushed all remaining * queue activity, and rpcrdma_xprt_drain has flushed all remaining
* Send requests. * Send requests.
*/ */
static void rpcrdma_sendctxs_destroy(struct rpcrdma_buffer *buf) static void rpcrdma_sendctxs_destroy(struct rpcrdma_xprt *r_xprt)
{ {
struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
unsigned long i; unsigned long i;
if (!buf->rb_sc_ctxs)
return;
for (i = 0; i <= buf->rb_sc_last; i++) for (i = 0; i <= buf->rb_sc_last; i++)
kfree(buf->rb_sc_ctxs[i]); kfree(buf->rb_sc_ctxs[i]);
kfree(buf->rb_sc_ctxs); kfree(buf->rb_sc_ctxs);
buf->rb_sc_ctxs = NULL;
} }
static struct rpcrdma_sendctx *rpcrdma_sendctx_create(struct rpcrdma_ep *ep) static struct rpcrdma_sendctx *rpcrdma_sendctx_create(struct rpcrdma_ep *ep)
@ -810,7 +822,6 @@ static int rpcrdma_sendctxs_create(struct rpcrdma_xprt *r_xprt)
* Sends are posted. * Sends are posted.
*/ */
i = buf->rb_max_requests + RPCRDMA_MAX_BC_REQUESTS; i = buf->rb_max_requests + RPCRDMA_MAX_BC_REQUESTS;
dprintk("RPC: %s: allocating %lu send_ctxs\n", __func__, i);
buf->rb_sc_ctxs = kcalloc(i, sizeof(sc), GFP_KERNEL); buf->rb_sc_ctxs = kcalloc(i, sizeof(sc), GFP_KERNEL);
if (!buf->rb_sc_ctxs) if (!buf->rb_sc_ctxs)
return -ENOMEM; return -ENOMEM;
@ -824,6 +835,8 @@ static int rpcrdma_sendctxs_create(struct rpcrdma_xprt *r_xprt)
buf->rb_sc_ctxs[i] = sc; buf->rb_sc_ctxs[i] = sc;
} }
buf->rb_sc_head = 0;
buf->rb_sc_tail = 0;
return 0; return 0;
} }
@ -1166,10 +1179,6 @@ int rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt)
init_llist_head(&buf->rb_free_reps); init_llist_head(&buf->rb_free_reps);
rc = rpcrdma_sendctxs_create(r_xprt);
if (rc)
goto out;
return 0; return 0;
out: out:
rpcrdma_buffer_destroy(buf); rpcrdma_buffer_destroy(buf);
@ -1245,7 +1254,6 @@ static void rpcrdma_mrs_destroy(struct rpcrdma_xprt *r_xprt)
void void
rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf) rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
{ {
rpcrdma_sendctxs_destroy(buf);
rpcrdma_reps_destroy(buf); rpcrdma_reps_destroy(buf);
while (!list_empty(&buf->rb_send_bufs)) { while (!list_empty(&buf->rb_send_bufs)) {