From: Chuck Lever <chuck.lever@oracle.com>
To: NeilBrown <neilb@suse.de>, trondmy@hammerspace.com, anna@kernel.org
Cc: Jeff Layton <jlayton@kernel.org>, linux-nfs@vger.kernel.org
Subject: Re: [PATCH 3/6] SUNRPC: integrate back-channel processing with svc_recv()
Date: Mon, 7 Aug 2023 10:09:23 -0400 [thread overview]
Message-ID: <ZND7E31GZjpX/DME@tissot.1015granger.net> (raw)
In-Reply-To: <20230802073443.17965-4-neilb@suse.de>
On Wed, Aug 02, 2023 at 05:34:40PM +1000, NeilBrown wrote:
> Using svc_recv() for (NFSv4.1) back-channel handling means we have just
> one mechanism for waking threads.
>
> Also change kthread_freezable_should_stop() in nfs4_callback_svc() to
> kthread_should_stop() as used elsewhere.
> kthread_freezable_should_stop() effectively adds a try_to_freeze() call,
> and svc_recv() already contains that at an appropriate place.
>
> Signed-off-by: NeilBrown <neilb@suse.de>
This one needs review and ack from the client maintainers.
Anna/Trond, if you haven't been following along, we're working on
updating the server-side thread scheduler. This patch replaces the
ad hoc scheduler in the client's NFSv4 callback service so that all
kernel RPC services utilize the same thread scheduling mechanism.
The whole series so far appears in the topic-sunrpc-thread-scheduling
branch in the public nfsd repo:
https://git.kernel.org/pub/scm/linux/kernel/git/cel/linux.git
> ---
> fs/nfs/callback.c | 46 ++-----------------------------
> include/linux/sunrpc/svc.h | 2 --
> net/sunrpc/backchannel_rqst.c | 8 ++----
> net/sunrpc/svc.c | 2 +-
> net/sunrpc/svc_xprt.c | 32 +++++++++++++++++++++
> net/sunrpc/xprtrdma/backchannel.c | 2 +-
> 6 files changed, 39 insertions(+), 53 deletions(-)
>
> diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
> index 466ebf1d41b2..42a0c2f1e785 100644
> --- a/fs/nfs/callback.c
> +++ b/fs/nfs/callback.c
> @@ -78,7 +78,7 @@ nfs4_callback_svc(void *vrqstp)
>
> set_freezable();
>
> - while (!kthread_freezable_should_stop(NULL))
> + while (!kthread_should_stop())
> svc_recv(rqstp);
>
> svc_exit_thread(rqstp);
> @@ -86,45 +86,6 @@ nfs4_callback_svc(void *vrqstp)
> }
>
> #if defined(CONFIG_NFS_V4_1)
> -/*
> - * The callback service for NFSv4.1 callbacks
> - */
> -static int
> -nfs41_callback_svc(void *vrqstp)
> -{
> - struct svc_rqst *rqstp = vrqstp;
> - struct svc_serv *serv = rqstp->rq_server;
> - struct rpc_rqst *req;
> - int error;
> - DEFINE_WAIT(wq);
> -
> - set_freezable();
> -
> - while (!kthread_freezable_should_stop(NULL)) {
> - prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_IDLE);
> - spin_lock_bh(&serv->sv_cb_lock);
> - if (!list_empty(&serv->sv_cb_list)) {
> - req = list_first_entry(&serv->sv_cb_list,
> - struct rpc_rqst, rq_bc_list);
> - list_del(&req->rq_bc_list);
> - spin_unlock_bh(&serv->sv_cb_lock);
> - finish_wait(&serv->sv_cb_waitq, &wq);
> - dprintk("Invoking bc_svc_process()\n");
> - error = bc_svc_process(serv, req, rqstp);
> - dprintk("bc_svc_process() returned w/ error code= %d\n",
> - error);
> - } else {
> - spin_unlock_bh(&serv->sv_cb_lock);
> - if (!kthread_should_stop())
> - schedule();
> - finish_wait(&serv->sv_cb_waitq, &wq);
> - }
> - }
> -
> - svc_exit_thread(rqstp);
> - return 0;
> -}
> -
> static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt,
> struct svc_serv *serv)
> {
> @@ -237,10 +198,7 @@ static struct svc_serv *nfs_callback_create_svc(int minorversion)
> cb_info->users);
>
> threadfn = nfs4_callback_svc;
> -#if defined(CONFIG_NFS_V4_1)
> - if (minorversion)
> - threadfn = nfs41_callback_svc;
> -#else
> +#if !defined(CONFIG_NFS_V4_1)
> if (minorversion)
> return ERR_PTR(-ENOTSUPP);
> #endif
> diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
> index dbf5b21feafe..5e2d3b83999e 100644
> --- a/include/linux/sunrpc/svc.h
> +++ b/include/linux/sunrpc/svc.h
> @@ -92,8 +92,6 @@ struct svc_serv {
> * that arrive over the same
> * connection */
> spinlock_t sv_cb_lock; /* protects the svc_cb_list */
> - wait_queue_head_t sv_cb_waitq; /* sleep here if there are no
> - * entries in the svc_cb_list */
> bool sv_bc_enabled; /* service uses backchannel */
> #endif /* CONFIG_SUNRPC_BACKCHANNEL */
> };
> diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c
> index 65a6c6429a53..44b7c89a635f 100644
> --- a/net/sunrpc/backchannel_rqst.c
> +++ b/net/sunrpc/backchannel_rqst.c
> @@ -349,10 +349,8 @@ struct rpc_rqst *xprt_lookup_bc_request(struct rpc_xprt *xprt, __be32 xid)
> }
>
> /*
> - * Add callback request to callback list. The callback
> - * service sleeps on the sv_cb_waitq waiting for new
> - * requests. Wake it up after adding enqueing the
> - * request.
> + * Add callback request to callback list. Wake a thread
> + * on the first pool (usually the only pool) to handle it.
> */
> void xprt_complete_bc_request(struct rpc_rqst *req, uint32_t copied)
> {
> @@ -371,6 +369,6 @@ void xprt_complete_bc_request(struct rpc_rqst *req, uint32_t copied)
> xprt_get(xprt);
> spin_lock(&bc_serv->sv_cb_lock);
> list_add(&req->rq_bc_list, &bc_serv->sv_cb_list);
> - wake_up(&bc_serv->sv_cb_waitq);
> spin_unlock(&bc_serv->sv_cb_lock);
> + svc_pool_wake_idle_thread(&bc_serv->sv_pools[0]);
> }
> diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
> index dc21e6c732db..0c3272f1b3b6 100644
> --- a/net/sunrpc/svc.c
> +++ b/net/sunrpc/svc.c
> @@ -440,7 +440,6 @@ __svc_init_bc(struct svc_serv *serv)
> {
> INIT_LIST_HEAD(&serv->sv_cb_list);
> spin_lock_init(&serv->sv_cb_lock);
> - init_waitqueue_head(&serv->sv_cb_waitq);
> }
> #else
> static void
> @@ -718,6 +717,7 @@ void svc_pool_wake_idle_thread(struct svc_pool *pool)
>
> set_bit(SP_CONGESTED, &pool->sp_flags);
> }
> +EXPORT_SYMBOL_GPL(svc_pool_wake_idle_thread);
>
> static struct svc_pool *
> svc_pool_next(struct svc_serv *serv, struct svc_pool *pool, unsigned int *state)
> diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
> index f1d64ded89fb..39582ac33cbd 100644
> --- a/net/sunrpc/svc_xprt.c
> +++ b/net/sunrpc/svc_xprt.c
> @@ -17,6 +17,7 @@
> #include <linux/sunrpc/svc_xprt.h>
> #include <linux/sunrpc/svcsock.h>
> #include <linux/sunrpc/xprt.h>
> +#include <linux/sunrpc/bc_xprt.h>
> #include <linux/module.h>
> #include <linux/netdevice.h>
> #include <trace/events/sunrpc.h>
> @@ -719,6 +720,13 @@ rqst_should_sleep(struct svc_rqst *rqstp)
> if (freezing(current))
> return false;
>
> +#if defined(CONFIG_SUNRPC_BACKCHANNEL)
> + if (svc_is_backchannel(rqstp)) {
> + if (!list_empty(&rqstp->rq_server->sv_cb_list))
> + return false;
> + }
> +#endif
> +
> return true;
> }
>
> @@ -867,6 +875,30 @@ void svc_recv(struct svc_rqst *rqstp)
> trace_svc_xprt_dequeue(rqstp);
> svc_handle_xprt(rqstp, xprt);
> }
> +
> +#if defined(CONFIG_SUNRPC_BACKCHANNEL)
> + if (svc_is_backchannel(rqstp)) {
> + struct svc_serv *serv = rqstp->rq_server;
> + struct rpc_rqst *req;
> +
> + spin_lock_bh(&serv->sv_cb_lock);
> + req = list_first_entry_or_null(&serv->sv_cb_list,
> + struct rpc_rqst, rq_bc_list);
> + if (req) {
> + int error;
> +
> + list_del(&req->rq_bc_list);
> + spin_unlock_bh(&serv->sv_cb_lock);
> +
> + dprintk("Invoking bc_svc_process()\n");
> + error = bc_svc_process(rqstp->rq_server, req, rqstp);
> + dprintk("bc_svc_process() returned w/ error code= %d\n",
> + error);
> + return;
> + }
> + spin_unlock_bh(&serv->sv_cb_lock);
> + }
> +#endif
> }
> EXPORT_SYMBOL_GPL(svc_recv);
>
> diff --git a/net/sunrpc/xprtrdma/backchannel.c b/net/sunrpc/xprtrdma/backchannel.c
> index e4d84a13c566..bfc434ec52a7 100644
> --- a/net/sunrpc/xprtrdma/backchannel.c
> +++ b/net/sunrpc/xprtrdma/backchannel.c
> @@ -267,7 +267,7 @@ void rpcrdma_bc_receive_call(struct rpcrdma_xprt *r_xprt,
> list_add(&rqst->rq_bc_list, &bc_serv->sv_cb_list);
> spin_unlock(&bc_serv->sv_cb_lock);
>
> - wake_up(&bc_serv->sv_cb_waitq);
> + svc_pool_wake_idle_thread(&bc_serv->sv_pools[0]);
>
> r_xprt->rx_stats.bcall_count++;
> return;
> --
> 2.40.1
>
--
Chuck Lever
next prev parent reply other threads:[~2023-08-07 14:09 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-02 7:34 [PATCH 0/6] SUNRPC: thread management improvements NeilBrown
2023-08-02 7:34 ` [PATCH 1/6] SUNRPC: move all of xprt handling into svc_xprt_handle() NeilBrown
2023-08-02 7:34 ` [PATCH 2/6] SUNRPC: rename and refactor svc_get_next_xprt() NeilBrown
2023-08-03 19:00 ` Chuck Lever
2023-08-03 21:12 ` NeilBrown
2023-08-06 23:07 ` NeilBrown
2023-08-07 14:59 ` Chuck Lever III
2023-08-02 7:34 ` [PATCH 3/6] SUNRPC: integrate back-channel processing with svc_recv() NeilBrown
2023-08-07 14:09 ` Chuck Lever [this message]
2023-08-02 7:34 ` [PATCH 4/6] SUNRPC: change how svc threads are asked to exit NeilBrown
2023-08-02 7:34 ` [PATCH 5/6] SUNRPC: add list of idle threads NeilBrown
2023-08-14 17:28 ` Chuck Lever
2023-08-14 21:32 ` NeilBrown
2023-08-02 7:34 ` [PATCH 6/6] SUNRPC: discard SP_CONGESTED NeilBrown
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=ZND7E31GZjpX/DME@tissot.1015granger.net \
--to=chuck.lever@oracle.com \
--cc=anna@kernel.org \
--cc=jlayton@kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=neilb@suse.de \
--cc=trondmy@hammerspace.com \
/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