From: cel@kernel.org
To: <linux-nfs@vger.kernel.org>, <linux-rdma@vger.kernel.org>
Cc: Chuck Lever <chuck.lever@oracle.com>
Subject: [RFC PATCH 4/4] xprtrdma: Move MRs to struct rpcrdma_ep
Date: Mon, 29 Apr 2024 11:25:42 -0400 [thread overview]
Message-ID: <20240429152537.212958-10-cel@kernel.org> (raw)
In-Reply-To: <20240429152537.212958-6-cel@kernel.org>
From: Chuck Lever <chuck.lever@oracle.com>
MRs are a connection-specific hardware resource, thus they should be
anchored in the EP and released with the other hardware resources.
Closes: Link: https://bugzilla.kernel.org/show_bug.cgi?id=218704
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
net/sunrpc/xprtrdma/frwr_ops.c | 7 ++--
net/sunrpc/xprtrdma/verbs.c | 70 ++++++++++++++++-----------------
net/sunrpc/xprtrdma/xprt_rdma.h | 13 +++---
3 files changed, 45 insertions(+), 45 deletions(-)
diff --git a/net/sunrpc/xprtrdma/frwr_ops.c b/net/sunrpc/xprtrdma/frwr_ops.c
index 6e508708d06d..7e918753eec4 100644
--- a/net/sunrpc/xprtrdma/frwr_ops.c
+++ b/net/sunrpc/xprtrdma/frwr_ops.c
@@ -112,15 +112,14 @@ void frwr_reset(struct rpcrdma_req *req)
/**
* frwr_mr_init - Initialize one MR
- * @r_xprt: controlling transport instance
+ * @ep: controlling transport instance
* @mr: generic MR to prepare for FRWR
*
* Returns zero if successful. Otherwise a negative errno
* is returned.
*/
-int frwr_mr_init(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr *mr)
+int frwr_mr_init(struct rpcrdma_ep *ep, struct rpcrdma_mr *mr)
{
- struct rpcrdma_ep *ep = r_xprt->rx_ep;
unsigned int depth = ep->re_max_fr_depth;
struct scatterlist *sg;
struct ib_mr *frmr;
@@ -134,7 +133,7 @@ int frwr_mr_init(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr *mr)
if (IS_ERR(frmr))
goto out_mr_err;
- mr->mr_xprt = r_xprt;
+ mr->mr_ep = ep;
mr->mr_ibmr = frmr;
mr->mr_device = NULL;
INIT_LIST_HEAD(&mr->mr_list);
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
index f1e4a28325fa..2578d9e77056 100644
--- a/net/sunrpc/xprtrdma/verbs.c
+++ b/net/sunrpc/xprtrdma/verbs.c
@@ -71,7 +71,8 @@ static int rpcrdma_reqs_setup(struct rpcrdma_xprt *r_xprt);
static void rpcrdma_reqs_reset(struct rpcrdma_xprt *r_xprt);
static void rpcrdma_reps_unmap(struct rpcrdma_xprt *r_xprt);
static void rpcrdma_mrs_create(struct rpcrdma_xprt *r_xprt);
-static void rpcrdma_mrs_destroy(struct rpcrdma_xprt *r_xprt);
+static void rpcrdma_mrs_destroy(struct rpcrdma_ep *ep);
+static void rpcrdma_mr_refresh_worker(struct work_struct *work);
static void rpcrdma_ep_get(struct rpcrdma_ep *ep);
static void rpcrdma_ep_put(struct rpcrdma_ep *ep);
static struct rpcrdma_regbuf *
@@ -337,6 +338,8 @@ static void rpcrdma_ep_destroy(struct work_struct *work)
{
struct rpcrdma_ep *ep = container_of(work, struct rpcrdma_ep, re_worker);
+ rpcrdma_mrs_destroy(ep);
+
if (ep->re_id->qp) {
rdma_destroy_qp(ep->re_id);
ep->re_id->qp = NULL;
@@ -393,6 +396,11 @@ static int rpcrdma_ep_create(struct rpcrdma_xprt *r_xprt)
ep->re_xprt = &r_xprt->rx_xprt;
kref_init(&ep->re_kref);
+ spin_lock_init(&ep->re_mr_lock);
+ INIT_WORK(&ep->re_refresh_worker, rpcrdma_mr_refresh_worker);
+ INIT_LIST_HEAD(&ep->re_mrs);
+ INIT_LIST_HEAD(&ep->re_all_mrs);
+
id = rpcrdma_create_id(r_xprt, ep);
if (IS_ERR(id)) {
kfree(ep);
@@ -575,7 +583,6 @@ void rpcrdma_xprt_disconnect(struct rpcrdma_xprt *r_xprt)
rpcrdma_xprt_drain(r_xprt);
rpcrdma_reps_unmap(r_xprt);
rpcrdma_reqs_reset(r_xprt);
- rpcrdma_mrs_destroy(r_xprt);
rpcrdma_sendctxs_destroy(r_xprt);
r_xprt->rx_ep = NULL;
@@ -749,7 +756,6 @@ static void rpcrdma_sendctx_put_locked(struct rpcrdma_xprt *r_xprt,
static void
rpcrdma_mrs_create(struct rpcrdma_xprt *r_xprt)
{
- struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
struct rpcrdma_ep *ep = r_xprt->rx_ep;
struct ib_device *device = ep->re_id->device;
unsigned int count;
@@ -764,16 +770,16 @@ rpcrdma_mrs_create(struct rpcrdma_xprt *r_xprt)
if (!mr)
break;
- rc = frwr_mr_init(r_xprt, mr);
+ rc = frwr_mr_init(ep, mr);
if (rc) {
kfree(mr);
break;
}
- spin_lock(&buf->rb_lock);
- rpcrdma_mr_push(mr, &buf->rb_mrs);
- list_add(&mr->mr_all, &buf->rb_all_mrs);
- spin_unlock(&buf->rb_lock);
+ spin_lock(&ep->re_mr_lock);
+ rpcrdma_mr_push(mr, &ep->re_mrs);
+ list_add(&mr->mr_all, &ep->re_all_mrs);
+ spin_unlock(&ep->re_mr_lock);
}
r_xprt->rx_stats.mrs_allocated += count;
@@ -783,10 +789,11 @@ rpcrdma_mrs_create(struct rpcrdma_xprt *r_xprt)
static void
rpcrdma_mr_refresh_worker(struct work_struct *work)
{
- struct rpcrdma_buffer *buf = container_of(work, struct rpcrdma_buffer,
- rb_refresh_worker);
- struct rpcrdma_xprt *r_xprt = container_of(buf, struct rpcrdma_xprt,
- rx_buf);
+ struct rpcrdma_ep *ep = container_of(work, struct rpcrdma_ep,
+ re_refresh_worker);
+ struct rpcrdma_xprt *r_xprt = container_of(ep->re_xprt,
+ struct rpcrdma_xprt,
+ rx_xprt);
rpcrdma_mrs_create(r_xprt);
xprt_write_space(&r_xprt->rx_xprt);
@@ -799,7 +806,6 @@ rpcrdma_mr_refresh_worker(struct work_struct *work)
*/
void rpcrdma_mrs_refresh(struct rpcrdma_xprt *r_xprt)
{
- struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
struct rpcrdma_ep *ep = r_xprt->rx_ep;
/* If there is no underlying connection, it's no use
@@ -807,7 +813,7 @@ void rpcrdma_mrs_refresh(struct rpcrdma_xprt *r_xprt)
*/
if (ep->re_connect_status != 1)
return;
- queue_work(system_highpri_wq, &buf->rb_refresh_worker);
+ queue_work(system_highpri_wq, &ep->re_refresh_worker);
}
/**
@@ -1044,9 +1050,6 @@ int rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt)
buf->rb_bc_srv_max_requests = 0;
spin_lock_init(&buf->rb_lock);
- INIT_LIST_HEAD(&buf->rb_mrs);
- INIT_LIST_HEAD(&buf->rb_all_mrs);
- INIT_WORK(&buf->rb_refresh_worker, rpcrdma_mr_refresh_worker);
INIT_LIST_HEAD(&buf->rb_send_bufs);
INIT_LIST_HEAD(&buf->rb_allreqs);
@@ -1085,11 +1088,11 @@ void rpcrdma_req_destroy(struct rpcrdma_req *req)
list_del(&req->rl_all);
while ((mr = rpcrdma_mr_pop(&req->rl_free_mrs))) {
- struct rpcrdma_buffer *buf = &mr->mr_xprt->rx_buf;
+ struct rpcrdma_ep *ep = mr->mr_ep;
- spin_lock(&buf->rb_lock);
+ spin_lock(&ep->re_mr_lock);
list_del(&mr->mr_all);
- spin_unlock(&buf->rb_lock);
+ spin_unlock(&ep->re_mr_lock);
frwr_mr_release(mr);
}
@@ -1102,31 +1105,28 @@ void rpcrdma_req_destroy(struct rpcrdma_req *req)
/**
* rpcrdma_mrs_destroy - Release all of a transport's MRs
- * @r_xprt: controlling transport instance
+ * @ep: controlling transport instance
*
- * Relies on caller holding the transport send lock to protect
- * removing mr->mr_list from req->rl_free_mrs safely.
*/
-static void rpcrdma_mrs_destroy(struct rpcrdma_xprt *r_xprt)
+static void rpcrdma_mrs_destroy(struct rpcrdma_ep *ep)
{
- struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
struct rpcrdma_mr *mr;
- cancel_work_sync(&buf->rb_refresh_worker);
+ cancel_work_sync(&ep->re_refresh_worker);
- spin_lock(&buf->rb_lock);
- while ((mr = list_first_entry_or_null(&buf->rb_all_mrs,
+ spin_lock(&ep->re_mr_lock);
+ while ((mr = list_first_entry_or_null(&ep->re_all_mrs,
struct rpcrdma_mr,
mr_all)) != NULL) {
list_del(&mr->mr_list);
list_del(&mr->mr_all);
- spin_unlock(&buf->rb_lock);
+ spin_unlock(&ep->re_mr_lock);
frwr_mr_release(mr);
- spin_lock(&buf->rb_lock);
+ spin_lock(&ep->re_mr_lock);
}
- spin_unlock(&buf->rb_lock);
+ spin_unlock(&ep->re_mr_lock);
}
/**
@@ -1162,12 +1162,12 @@ rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
struct rpcrdma_mr *
rpcrdma_mr_get(struct rpcrdma_xprt *r_xprt)
{
- struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
+ struct rpcrdma_ep *ep = r_xprt->rx_ep;
struct rpcrdma_mr *mr;
- spin_lock(&buf->rb_lock);
- mr = rpcrdma_mr_pop(&buf->rb_mrs);
- spin_unlock(&buf->rb_lock);
+ spin_lock(&ep->re_mr_lock);
+ mr = rpcrdma_mr_pop(&ep->re_mrs);
+ spin_unlock(&ep->re_mr_lock);
return mr;
}
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h
index 048d2e329384..ce703b6e3b86 100644
--- a/net/sunrpc/xprtrdma/xprt_rdma.h
+++ b/net/sunrpc/xprtrdma/xprt_rdma.h
@@ -96,6 +96,11 @@ struct rpcrdma_ep {
unsigned int re_inline_send; /* negotiated */
unsigned int re_inline_recv; /* negotiated */
+ spinlock_t re_mr_lock;
+ struct list_head re_mrs;
+ struct list_head re_all_mrs;
+ struct work_struct re_refresh_worker;
+
atomic_t re_completion_ids;
char re_write_pad[XDR_UNIT];
@@ -253,7 +258,7 @@ struct rpcrdma_mr {
struct ib_reg_wr mr_regwr;
struct ib_send_wr mr_invwr;
};
- struct rpcrdma_xprt *mr_xprt;
+ struct rpcrdma_ep *mr_ep;
u32 mr_handle;
u32 mr_length;
u64 mr_offset;
@@ -365,7 +370,6 @@ rpcrdma_mr_pop(struct list_head *list)
struct rpcrdma_buffer {
spinlock_t rb_lock;
struct list_head rb_send_bufs;
- struct list_head rb_mrs;
unsigned long rb_sc_head;
unsigned long rb_sc_tail;
@@ -373,7 +377,6 @@ struct rpcrdma_buffer {
struct rpcrdma_sendctx **rb_sc_ctxs;
struct list_head rb_allreqs;
- struct list_head rb_all_mrs;
struct list_head rb_all_reps;
struct llist_head rb_free_reps;
@@ -383,8 +386,6 @@ struct rpcrdma_buffer {
u32 rb_bc_srv_max_requests;
u32 rb_bc_max_requests;
-
- struct work_struct rb_refresh_worker;
};
/*
@@ -533,7 +534,7 @@ rpcrdma_data_dir(bool writing)
*/
void frwr_reset(struct rpcrdma_req *req);
int frwr_query_device(struct rpcrdma_ep *ep, const struct ib_device *device);
-int frwr_mr_init(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr *mr);
+int frwr_mr_init(struct rpcrdma_ep *ep, struct rpcrdma_mr *mr);
void frwr_mr_release(struct rpcrdma_mr *mr);
struct rpcrdma_mr_seg *frwr_map(struct rpcrdma_xprt *r_xprt,
struct rpcrdma_mr_seg *seg,
--
2.44.0
next prev parent reply other threads:[~2024-04-29 15:25 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-29 15:25 [RFC PATCH 0/4] NFS: Fix another 'check_flush_dependency' splat cel
2024-04-29 15:25 ` [RFC PATCH 1/4] xprtrdma: Remove temp allocation of rpcrdma_rep objects cel
2024-04-29 15:25 ` [RFC PATCH 2/4] xprtrdma: Clean up synopsis of frwr_mr_unmap() cel
2024-04-29 15:25 ` [RFC PATCH 3/4] xprtrdma: Delay releasing connection hardware resources cel
2024-04-29 15:25 ` cel [this message]
2024-04-30 7:26 ` [RFC PATCH 0/4] NFS: Fix another 'check_flush_dependency' splat Zhu Yanjun
2024-04-30 13:42 ` Chuck Lever III
2024-04-30 13:58 ` Zhu Yanjun
2024-04-30 14:13 ` Chuck Lever III
2024-04-30 14:45 ` Zhu Yanjun
2024-04-30 14:52 ` Chuck Lever III
2024-04-30 14:57 ` Zhu Yanjun
2024-06-02 15:40 ` Chuck Lever III
2024-06-02 18:14 ` Zhu Yanjun
2024-06-03 15:59 ` Chuck Lever III
2024-06-03 16:54 ` Zhu Yanjun
2024-06-03 17:06 ` Chuck Lever III
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240429152537.212958-10-cel@kernel.org \
--to=cel@kernel.org \
--cc=chuck.lever@oracle.com \
--cc=linux-nfs@vger.kernel.org \
--cc=linux-rdma@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox