From patchwork Tue Jul 18 06:38:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: NeilBrown X-Patchwork-Id: 13316777 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C5282EB64DD for ; Tue, 18 Jul 2023 06:39:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231140AbjGRGjK (ORCPT ); Tue, 18 Jul 2023 02:39:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44468 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229923AbjGRGjI (ORCPT ); Tue, 18 Jul 2023 02:39:08 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A2541B1 for ; Mon, 17 Jul 2023 23:39:06 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 4ACBD1FDBC; Tue, 18 Jul 2023 06:39:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1689662345; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rWCEP/Mc5gojphRKRm4FHtda4qY/sWmT7/WQI2pi3JY=; b=yodBiJR5ZbNz6eoem7bgtu/6k5onBxhKs5GtU+TT80pCROHvgqAY+Jv7JDb9Gz/jPzWA7l 8kYGVFCJ0lLzt1znojtoh2lo2YdxuQ21ty9Vk/1vQHmk1RuCNiEsBJ68uxBz0qOzNMENX0 d+lJotJxjNTgq4fgXrfsNB0GI94M7WQ= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1689662345; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rWCEP/Mc5gojphRKRm4FHtda4qY/sWmT7/WQI2pi3JY=; b=Ei+rBEUoH+g0Nd9NYEg5hWWe8BpZ7KlEts0SDVZA6whZdnt709cHQPr1btOJBV9Xek98iX aErOze4ktU55J+CQ== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 093DF13494; Tue, 18 Jul 2023 06:39:03 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id SIBiK4cztmQjDAAAMHmgww (envelope-from ); Tue, 18 Jul 2023 06:39:03 +0000 Subject: [PATCH 01/14] lockd: remove SIGKILL handling. From: NeilBrown To: Chuck Lever , Jeff Layton Cc: linux-nfs@vger.kernel.org Date: Tue, 18 Jul 2023 16:38:08 +1000 Message-ID: <168966228859.11075.13570585046156408745.stgit@noble.brown> In-Reply-To: <168966227838.11075.2974227708495338626.stgit@noble.brown> References: <168966227838.11075.2974227708495338626.stgit@noble.brown> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org lockd allows SIGKILL and responds by dropping all locks and restarting the grace period. This functionality has been present since 2.1.32 when lockd was added to Linux. This functionality is undocumented and most liked added as a useful debug aid. When there is a need to drop locks, the best approach is using /proc/fs/nfsd/unlock_*. This patch removes the handling of SIGKILL as part of preparation for removing all signal handling from sunrpc service threads. Signed-off-by: NeilBrown Reviewed-by: Jeff Layton --- fs/lockd/svc.c | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 22d3ff3818f5..614faa5f69cd 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -45,7 +45,6 @@ #define NLMDBG_FACILITY NLMDBG_SVC #define LOCKD_BUFSIZE (1024 + NLMSVC_XDRSIZE) -#define ALLOWED_SIGS (sigmask(SIGKILL)) static struct svc_program nlmsvc_program; @@ -111,19 +110,6 @@ static void set_grace_period(struct net *net) schedule_delayed_work(&ln->grace_period_end, grace_period); } -static void restart_grace(void) -{ - if (nlmsvc_ops) { - struct net *net = &init_net; - struct lockd_net *ln = net_generic(net, lockd_net_id); - - cancel_delayed_work_sync(&ln->grace_period_end); - locks_end_grace(&ln->lockd_manager); - nlmsvc_invalidate_all(); - set_grace_period(net); - } -} - /* * This is the lockd kernel thread */ @@ -138,9 +124,6 @@ lockd(void *vrqstp) /* try_to_freeze() is called from svc_recv() */ set_freezable(); - /* Allow SIGKILL to tell lockd to drop all of its locks */ - allow_signal(SIGKILL); - dprintk("NFS locking service started (ver " LOCKD_VERSION ").\n"); /* @@ -154,12 +137,6 @@ lockd(void *vrqstp) /* update sv_maxconn if it has changed */ rqstp->rq_server->sv_maxconn = nlm_max_connections; - if (signalled()) { - flush_signals(current); - restart_grace(); - continue; - } - timeout = nlmsvc_retry_blocked(); /* @@ -174,7 +151,6 @@ lockd(void *vrqstp) svc_process(rqstp); } - flush_signals(current); if (nlmsvc_ops) nlmsvc_invalidate_all(); nlm_shutdown_hosts(); From patchwork Tue Jul 18 06:38:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: NeilBrown X-Patchwork-Id: 13316778 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1717CEB64DD for ; Tue, 18 Jul 2023 06:39:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230348AbjGRGjN (ORCPT ); Tue, 18 Jul 2023 02:39:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44476 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230193AbjGRGjM (ORCPT ); Tue, 18 Jul 2023 02:39:12 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 974E6134 for ; Mon, 17 Jul 2023 23:39:11 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 432D21FDBC; Tue, 18 Jul 2023 06:39:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1689662350; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8SsquPAl8Ukn9SN2QqF6oIY12wkz6s2wKJCZOujxUlQ=; b=wVi1HmmXibGjcedeF2rflz6pF/a6dQ1TXsYBv1zkDO4h730ukqg34dYORlyDK3K6hjCOcd f4cqZI7cV9MgnjT8R1dwWqiSk1mQC7LfRSL5Yi3uWnaCnKchgKDs34qdpIfUCYha/6bFgb hJTUxb5jhuxjhSLS5+FZGRm7oh+65IQ= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1689662350; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8SsquPAl8Ukn9SN2QqF6oIY12wkz6s2wKJCZOujxUlQ=; b=8hQ7bvRHj+toKOVG/Nz4T2m9+1efb3i6hQrRZIRMZnkgSDQAIRfCOF4jay1ha0rw6syUXV 0s8KxhDWrt+rfZBA== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id ED7BB13494; Tue, 18 Jul 2023 06:39:08 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id oei8J4wztmQ1DAAAMHmgww (envelope-from ); Tue, 18 Jul 2023 06:39:08 +0000 Subject: [PATCH 02/14] nfsd: don't allow nfsd threads to be signalled. From: NeilBrown To: Chuck Lever , Jeff Layton Cc: linux-nfs@vger.kernel.org Date: Tue, 18 Jul 2023 16:38:08 +1000 Message-ID: <168966228860.11075.10973222274248478768.stgit@noble.brown> In-Reply-To: <168966227838.11075.2974227708495338626.stgit@noble.brown> References: <168966227838.11075.2974227708495338626.stgit@noble.brown> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org The original implementation of nfsd used signals to stop threads during shutdown. In Linux 2.3.46pre5 nfsd gained the ability to shutdown threads internally it if was asked to run "0" threads. After this user-space transitioned to using "rpc.nfsd 0" to stop nfsd and sending signals to threads was no longer an important part of the API. In Commit 3ebdbe5203a8 ("SUNRPC: discard svo_setup and rename svc_set_num_threads_sync()") (v5.17-rc1~75^2~41) we finally removed the use of signals for stopping threads, using kthread_stop() instead. This patch makes the "obvious" next step and removes the ability to signal nfsd threads - or any svc threads. nfsd stops allowing signals and we don't check for their delivery any more. This will allow for some simplification in later patches. A change worth noting is in nfsd4_ssc_setup_dul(). There was previously a signal_pending() check which would only succeed when the thread was being shut down. It should really have tested kthread_should_stop() as well. Now it just does the later, not the former. Signed-off-by: NeilBrown Reviewed-by: Jeff Layton --- fs/nfs/callback.c | 9 +-------- fs/nfsd/nfs4proc.c | 4 ++-- fs/nfsd/nfssvc.c | 12 ------------ net/sunrpc/svc_xprt.c | 16 ++++++---------- 4 files changed, 9 insertions(+), 32 deletions(-) diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 456af7d230cf..46a0a2d6962e 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -80,9 +80,6 @@ nfs4_callback_svc(void *vrqstp) set_freezable(); while (!kthread_freezable_should_stop(NULL)) { - - if (signal_pending(current)) - flush_signals(current); /* * Listen for a request on the socket */ @@ -112,11 +109,7 @@ nfs41_callback_svc(void *vrqstp) set_freezable(); while (!kthread_freezable_should_stop(NULL)) { - - if (signal_pending(current)) - flush_signals(current); - - prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_INTERRUPTIBLE); + 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, diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index d8e7a533f9d2..157488290676 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1325,11 +1325,11 @@ static __be32 nfsd4_ssc_setup_dul(struct nfsd_net *nn, char *ipaddr, if (ni->nsui_busy) { /* wait - and try again */ prepare_to_wait(&nn->nfsd_ssc_waitq, &wait, - TASK_INTERRUPTIBLE); + TASK_IDLE); spin_unlock(&nn->nfsd_ssc_lock); /* allow 20secs for mount/unmount for now - revisit */ - if (signal_pending(current) || + if (kthread_should_stop() || (schedule_timeout(20*HZ) == 0)) { finish_wait(&nn->nfsd_ssc_waitq, &wait); kfree(work); diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 97830e28c140..439fca195925 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -965,15 +965,6 @@ nfsd(void *vrqstp) current->fs->umask = 0; - /* - * thread is spawned with all signals set to SIG_IGN, re-enable - * the ones that will bring down the thread - */ - allow_signal(SIGKILL); - allow_signal(SIGHUP); - allow_signal(SIGINT); - allow_signal(SIGQUIT); - atomic_inc(&nfsdstats.th_cnt); set_freezable(); @@ -998,9 +989,6 @@ nfsd(void *vrqstp) validate_process_creds(); } - /* Clear signals before calling svc_exit_thread() */ - flush_signals(current); - atomic_dec(&nfsdstats.th_cnt); out: diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 71b19d0ed642..93395606a0ba 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -686,8 +686,8 @@ static int svc_alloc_arg(struct svc_rqst *rqstp) /* Made progress, don't sleep yet */ continue; - set_current_state(TASK_INTERRUPTIBLE); - if (signalled() || kthread_should_stop()) { + set_current_state(TASK_IDLE); + if (kthread_should_stop()) { set_current_state(TASK_RUNNING); return -EINTR; } @@ -725,7 +725,7 @@ rqst_should_sleep(struct svc_rqst *rqstp) return false; /* are we shutting down? */ - if (signalled() || kthread_should_stop()) + if (kthread_should_stop()) return false; /* are we freezing? */ @@ -749,11 +749,7 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout) goto out_found; } - /* - * We have to be able to interrupt this wait - * to bring down the daemons ... - */ - set_current_state(TASK_INTERRUPTIBLE); + set_current_state(TASK_IDLE); smp_mb__before_atomic(); clear_bit(SP_CONGESTED, &pool->sp_flags); clear_bit(RQ_BUSY, &rqstp->rq_flags); @@ -776,7 +772,7 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout) if (!time_left) percpu_counter_inc(&pool->sp_threads_timedout); - if (signalled() || kthread_should_stop()) + if (kthread_should_stop()) return ERR_PTR(-EINTR); percpu_counter_inc(&pool->sp_threads_no_work); return ERR_PTR(-EAGAIN); @@ -873,7 +869,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) try_to_freeze(); cond_resched(); err = -EINTR; - if (signalled() || kthread_should_stop()) + if (kthread_should_stop()) goto out; xprt = svc_get_next_xprt(rqstp, timeout); From patchwork Tue Jul 18 06:38:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: NeilBrown X-Patchwork-Id: 13316779 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A9F63EB64DC for ; Tue, 18 Jul 2023 06:39:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231416AbjGRGjU (ORCPT ); Tue, 18 Jul 2023 02:39:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44648 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231360AbjGRGjR (ORCPT ); Tue, 18 Jul 2023 02:39:17 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [IPv6:2001:67c:2178:6::1c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 83213198 for ; Mon, 17 Jul 2023 23:39:16 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 3E6E62197F; Tue, 18 Jul 2023 06:39:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1689662355; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/t/y/epzgmGxfN8+0Nclw0tUxGKxQ6msbvf5pN6rITY=; b=KT1iROBxlr0NZRiLk45c56E2Vj5nGQQJbSFqCiyo/96bzNx1gmuRwAd8nCs5opgPgTkZf7 l57GX7cxVE9sdTs7ZZddMhHJliJzrw8Vn9DDats/RuYeEI1jOcj4yb8WA3GPuu4K829gAj FROkT/XpWt1SHZH23P4Imp4jxYOm/ig= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1689662355; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/t/y/epzgmGxfN8+0Nclw0tUxGKxQ6msbvf5pN6rITY=; b=N0dtvTE0YJ1eC1B/YzzkfW0daALG9zpi1nhqkKWE1M0x5KAP0DGkqFKR//AhKRb5tIceXh WMRgZ3Wk1kWC3cCQ== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id D2C4213494; Tue, 18 Jul 2023 06:39:13 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id oKYVIZEztmRBDAAAMHmgww (envelope-from ); Tue, 18 Jul 2023 06:39:13 +0000 Subject: [PATCH 03/14] SUNRPC: call svc_process() from svc_recv(). From: NeilBrown To: Chuck Lever , Jeff Layton Cc: linux-nfs@vger.kernel.org Date: Tue, 18 Jul 2023 16:38:08 +1000 Message-ID: <168966228861.11075.6512110736168003985.stgit@noble.brown> In-Reply-To: <168966227838.11075.2974227708495338626.stgit@noble.brown> References: <168966227838.11075.2974227708495338626.stgit@noble.brown> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org All callers of svc_recv() go on to call svc_process() on success. Simplify callers by having svc_recv() do that for them. This loses one call to validate_process_creds() in nfsd. That was debugging code added 14 years ago. I don't think we need to keep it. Signed-off-by: NeilBrown Reviewed-by: Jeff Layton --- fs/lockd/svc.c | 5 ----- fs/nfs/callback.c | 1 - fs/nfsd/nfssvc.c | 2 -- net/sunrpc/svc_xprt.c | 3 ++- 4 files changed, 2 insertions(+), 9 deletions(-) diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 614faa5f69cd..91ef139a7757 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -132,7 +132,6 @@ lockd(void *vrqstp) */ while (!kthread_should_stop()) { long timeout = MAX_SCHEDULE_TIMEOUT; - RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); /* update sv_maxconn if it has changed */ rqstp->rq_server->sv_maxconn = nlm_max_connections; @@ -146,10 +145,6 @@ lockd(void *vrqstp) err = svc_recv(rqstp, timeout); if (err == -EAGAIN || err == -EINTR) continue; - dprintk("lockd: request from %s\n", - svc_print_addr(rqstp, buf, sizeof(buf))); - - svc_process(rqstp); } if (nlmsvc_ops) nlmsvc_invalidate_all(); diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 46a0a2d6962e..2d94384bd6a9 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -86,7 +86,6 @@ nfs4_callback_svc(void *vrqstp) err = svc_recv(rqstp, MAX_SCHEDULE_TIMEOUT); if (err == -EAGAIN || err == -EINTR) continue; - svc_process(rqstp); } svc_exit_thread(rqstp); diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 439fca195925..3e08cc746870 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -985,8 +985,6 @@ nfsd(void *vrqstp) if (err == -EINTR) break; validate_process_creds(); - svc_process(rqstp); - validate_process_creds(); } atomic_dec(&nfsdstats.th_cnt); diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 93395606a0ba..c808f6d60c99 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -895,7 +895,8 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) serv->sv_stats->netcnt++; percpu_counter_inc(&rqstp->rq_pool->sp_messages_arrived); rqstp->rq_stime = ktime_get(); - return len; + svc_process(rqstp); + return 0; out_release: rqstp->rq_res.len = 0; svc_xprt_release(rqstp); From patchwork Tue Jul 18 06:38:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: NeilBrown X-Patchwork-Id: 13316780 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2FB1BEB64DA for ; Tue, 18 Jul 2023 06:39:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231299AbjGRGjZ (ORCPT ); Tue, 18 Jul 2023 02:39:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44430 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230506AbjGRGjX (ORCPT ); Tue, 18 Jul 2023 02:39:23 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [IPv6:2001:67c:2178:6::1c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 66F4F1A6 for ; Mon, 17 Jul 2023 23:39:21 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 1DCFB2193C; Tue, 18 Jul 2023 06:39:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1689662360; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=xg2RgBEO/rX8EeCfAvefOHhgjcQoKsl3XKkN4lPtPJM=; b=Oif/wl/htNbnHLV3KASreO6JYFdZkC6UuY2nWMKRnbSXpuQqZCYlVLK7DpWm5J18CF79rw y9AraUPccgmPXweLRN+6ou/NoQxUTaVli7tSJKt8RwwkRWtTZeqXQ1b4v37yvg2cpCp8Xr JZ9mKv+ElQ9qQpf94GIzq7EJOOxoXQc= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1689662360; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=xg2RgBEO/rX8EeCfAvefOHhgjcQoKsl3XKkN4lPtPJM=; b=yM2LKqmaVEkYQBXinx/su0UiRIzmO5D3o7f5m1fWCcmOQXcWGBCNHWir+4UbiMX1jXXdTL QG9l3Kl6KAa0swAg== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id D50D913494; Tue, 18 Jul 2023 06:39:18 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id 9hXDIZYztmRhDAAAMHmgww (envelope-from ); Tue, 18 Jul 2023 06:39:18 +0000 Subject: [PATCH 04/14] SUNRPC: change svc_recv() to return void. From: NeilBrown To: Chuck Lever , Jeff Layton Cc: linux-nfs@vger.kernel.org Date: Tue, 18 Jul 2023 16:38:08 +1000 Message-ID: <168966228862.11075.10086063375287695723.stgit@noble.brown> In-Reply-To: <168966227838.11075.2974227708495338626.stgit@noble.brown> References: <168966227838.11075.2974227708495338626.stgit@noble.brown> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org svc_recv() currently returns a 0 on success or one of two errors: - -EAGAIN means no message was successfully received - -EINTR means the thread has been told to stop Previously nfsd would stop as the result of a signal as well as following kthread_stop(). In that case the difference was useful: EINTR means stop unconditionally. EAGAIN means stop if kthread_should_stop(), continue otherwise. Now threads only exit when kthread_should_stop() so we don't need the distinction. So have all threads test kthread_should_stop() (most do), and return simple success/failure from svc_recv(). Also change some helpers that svc_recv() uses to not bother with an error code, returning a bool in once case, and NULL for failure in another. Signed-off-by: NeilBrown --- fs/lockd/svc.c | 9 +++------ fs/nfs/callback.c | 5 +---- fs/nfsd/nfssvc.c | 8 ++------ include/linux/sunrpc/svcsock.h | 2 +- net/sunrpc/svc_xprt.c | 27 +++++++++++---------------- 5 files changed, 18 insertions(+), 33 deletions(-) diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 91ef139a7757..a43b63e46127 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -116,7 +116,6 @@ static void set_grace_period(struct net *net) static int lockd(void *vrqstp) { - int err = 0; struct svc_rqst *rqstp = vrqstp; struct net *net = &init_net; struct lockd_net *ln = net_generic(net, lockd_net_id); @@ -139,12 +138,10 @@ lockd(void *vrqstp) timeout = nlmsvc_retry_blocked(); /* - * Find a socket with data available and call its - * recvfrom routine. + * Find any work to do, such as a socket with data available, + * and do the work. */ - err = svc_recv(rqstp, timeout); - if (err == -EAGAIN || err == -EINTR) - continue; + svc_recv(rqstp, timeout); } if (nlmsvc_ops) nlmsvc_invalidate_all(); diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 2d94384bd6a9..914d2402ca98 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -74,7 +74,6 @@ static int nfs4_callback_up_net(struct svc_serv *serv, struct net *net) static int nfs4_callback_svc(void *vrqstp) { - int err; struct svc_rqst *rqstp = vrqstp; set_freezable(); @@ -83,9 +82,7 @@ nfs4_callback_svc(void *vrqstp) /* * Listen for a request on the socket */ - err = svc_recv(rqstp, MAX_SCHEDULE_TIMEOUT); - if (err == -EAGAIN || err == -EINTR) - continue; + svc_recv(rqstp, MAX_SCHEDULE_TIMEOUT); } svc_exit_thread(rqstp); diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 3e08cc746870..5bf48c33986e 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -953,7 +953,6 @@ nfsd(void *vrqstp) struct svc_xprt *perm_sock = list_entry(rqstp->rq_server->sv_permsocks.next, typeof(struct svc_xprt), xpt_list); struct net *net = perm_sock->xpt_net; struct nfsd_net *nn = net_generic(net, nfsd_net_id); - int err; /* At this point, the thread shares current->fs * with the init process. We need to create files with the @@ -972,7 +971,7 @@ nfsd(void *vrqstp) /* * The main request loop */ - for (;;) { + while (!kthread_should_stop()) { /* Update sv_maxconn if it has changed */ rqstp->rq_server->sv_maxconn = nn->max_connections; @@ -980,10 +979,7 @@ nfsd(void *vrqstp) * Find a socket with data available and call its * recvfrom routine. */ - while ((err = svc_recv(rqstp, 60*60*HZ)) == -EAGAIN) - ; - if (err == -EINTR) - break; + svc_recv(rqstp, 60*60*HZ); validate_process_creds(); } diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h index 55446136499f..fb5c98069356 100644 --- a/include/linux/sunrpc/svcsock.h +++ b/include/linux/sunrpc/svcsock.h @@ -64,7 +64,7 @@ static inline u32 svc_sock_final_rec(struct svc_sock *svsk) * Function prototypes. */ void svc_close_net(struct svc_serv *, struct net *); -int svc_recv(struct svc_rqst *, long); +void svc_recv(struct svc_rqst *, long); void svc_send(struct svc_rqst *rqstp); void svc_drop(struct svc_rqst *); void svc_sock_update_bufs(struct svc_serv *serv); diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index c808f6d60c99..67825eef8646 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -664,7 +664,7 @@ static void svc_check_conn_limits(struct svc_serv *serv) } } -static int svc_alloc_arg(struct svc_rqst *rqstp) +static bool svc_alloc_arg(struct svc_rqst *rqstp) { struct svc_serv *serv = rqstp->rq_server; struct xdr_buf *arg = &rqstp->rq_arg; @@ -689,7 +689,7 @@ static int svc_alloc_arg(struct svc_rqst *rqstp) set_current_state(TASK_IDLE); if (kthread_should_stop()) { set_current_state(TASK_RUNNING); - return -EINTR; + return false; } trace_svc_alloc_arg_err(pages, ret); memalloc_retry_wait(GFP_KERNEL); @@ -708,7 +708,7 @@ static int svc_alloc_arg(struct svc_rqst *rqstp) arg->tail[0].iov_len = 0; rqstp->rq_xid = xdr_zero; - return 0; + return true; } static bool @@ -773,9 +773,9 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout) if (!time_left) percpu_counter_inc(&pool->sp_threads_timedout); if (kthread_should_stop()) - return ERR_PTR(-EINTR); + return NULL; percpu_counter_inc(&pool->sp_threads_no_work); - return ERR_PTR(-EAGAIN); + return NULL; out_found: /* Normally we will wait up to 5 seconds for any required * cache information to be provided. @@ -856,32 +856,27 @@ static int svc_handle_xprt(struct svc_rqst *rqstp, struct svc_xprt *xprt) * organised not to touch any cachelines in the shared svc_serv * structure, only cachelines in the local svc_pool. */ -int svc_recv(struct svc_rqst *rqstp, long timeout) +void svc_recv(struct svc_rqst *rqstp, long timeout) { struct svc_xprt *xprt = NULL; struct svc_serv *serv = rqstp->rq_server; - int len, err; + int len; - err = svc_alloc_arg(rqstp); - if (err) + if (!svc_alloc_arg(rqstp)) goto out; try_to_freeze(); cond_resched(); - err = -EINTR; if (kthread_should_stop()) goto out; xprt = svc_get_next_xprt(rqstp, timeout); - if (IS_ERR(xprt)) { - err = PTR_ERR(xprt); + if (!xprt) goto out; - } len = svc_handle_xprt(rqstp, xprt); /* No data, incomplete (TCP) read, or accept() */ - err = -EAGAIN; if (len <= 0) goto out_release; @@ -896,12 +891,12 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) percpu_counter_inc(&rqstp->rq_pool->sp_messages_arrived); rqstp->rq_stime = ktime_get(); svc_process(rqstp); - return 0; + return; out_release: rqstp->rq_res.len = 0; svc_xprt_release(rqstp); out: - return err; + return; } EXPORT_SYMBOL_GPL(svc_recv); From patchwork Tue Jul 18 06:38:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: NeilBrown X-Patchwork-Id: 13316781 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5C429EB64DA for ; Tue, 18 Jul 2023 06:39:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230245AbjGRGjc (ORCPT ); Tue, 18 Jul 2023 02:39:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44786 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229811AbjGRGjb (ORCPT ); Tue, 18 Jul 2023 02:39:31 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A57D51A6 for ; Mon, 17 Jul 2023 23:39:26 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 0004721958; Tue, 18 Jul 2023 06:39:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1689662365; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=CF2Clzk7tKgySjNqen1ELNCMJ6JvvWQXIe0cIO8GlYQ=; b=Pa6VUi3fpIR0gox7yoG9XVfMjkyhJhX1Q62obRWzRXLq+jOIDoooEZMI26DwqKJIIcGMuz 3K6yOsdZz8Tun3u25Mb4C+RU03HUmLgKsoLl8r6LPM6eHjdwJXXoj1RnhCbFrWhh4ycVHh hCmkrIgwsD5qEYe5IFGASUxOi9aEbqc= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1689662365; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=CF2Clzk7tKgySjNqen1ELNCMJ6JvvWQXIe0cIO8GlYQ=; b=rzlLb4XtpDvcJPYZCum8pDTl41S8TZKTUnld1R88/B0DuAmIzcb7CzA+YYZAwkj4N2gKge ZOi3Mj+Nn8myTnAQ== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id B535F13494; Tue, 18 Jul 2023 06:39:23 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id 5HLqGZsztmR9DAAAMHmgww (envelope-from ); Tue, 18 Jul 2023 06:39:23 +0000 Subject: [PATCH 05/14] SUNRPC: remove timeout arg from svc_recv() From: NeilBrown To: Chuck Lever , Jeff Layton Cc: linux-nfs@vger.kernel.org Date: Tue, 18 Jul 2023 16:38:08 +1000 Message-ID: <168966228862.11075.7544295807519851006.stgit@noble.brown> In-Reply-To: <168966227838.11075.2974227708495338626.stgit@noble.brown> References: <168966227838.11075.2974227708495338626.stgit@noble.brown> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org Most svc threads have no interest in a timeout. nfsd sets it to 1 hour, but this is a wart of no significance. lockd uses the timeout so that it can call nlmsvc_retry_blocked(). It also sometimes calls svc_wake_up() to ensure this is called. So change lockd to be consistent and always use svc_wake_up() to trigger nlmsvc_retry_blocked() - using a timer instead of a timeout to svc_recv(). And change svc_recv() to not take a timeout arg. This makes the sp_threads_timedout counter always zero. Signed-off-by: NeilBrown Reviewed-by: Jeff Layton --- fs/lockd/svc.c | 11 ++++++++--- fs/lockd/svclock.c | 5 +++-- fs/nfs/callback.c | 2 +- fs/nfsd/nfssvc.c | 2 +- include/linux/lockd/lockd.h | 4 +++- include/linux/sunrpc/svc.h | 1 - include/linux/sunrpc/svcsock.h | 2 +- net/sunrpc/svc.c | 2 -- net/sunrpc/svc_xprt.c | 27 ++++++++++++--------------- 9 files changed, 29 insertions(+), 27 deletions(-) diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index a43b63e46127..4f55cd42c2e6 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -55,6 +55,11 @@ static DEFINE_MUTEX(nlmsvc_mutex); static unsigned int nlmsvc_users; static struct svc_serv *nlmsvc_serv; unsigned long nlmsvc_timeout; +static void nlmsvc_request_retry(struct timer_list *tl) +{ + svc_wake_up(nlmsvc_serv); +} +DEFINE_TIMER(nlmsvc_retry, nlmsvc_request_retry); unsigned int lockd_net_id; @@ -130,18 +135,17 @@ lockd(void *vrqstp) * NFS mount or NFS daemon has gone away. */ while (!kthread_should_stop()) { - long timeout = MAX_SCHEDULE_TIMEOUT; /* update sv_maxconn if it has changed */ rqstp->rq_server->sv_maxconn = nlm_max_connections; - timeout = nlmsvc_retry_blocked(); + nlmsvc_retry_blocked(); /* * Find any work to do, such as a socket with data available, * and do the work. */ - svc_recv(rqstp, timeout); + svc_recv(rqstp); } if (nlmsvc_ops) nlmsvc_invalidate_all(); @@ -375,6 +379,7 @@ static void lockd_put(void) #endif svc_set_num_threads(nlmsvc_serv, NULL, 0); + timer_delete_sync(&nlmsvc_retry); nlmsvc_serv = NULL; dprintk("lockd_down: service destroyed\n"); } diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index c43ccdf28ed9..3d7bd5c04b36 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c @@ -1008,7 +1008,7 @@ retry_deferred_block(struct nlm_block *block) * picks up locks that can be granted, or grant notifications that must * be retransmitted. */ -unsigned long +void nlmsvc_retry_blocked(void) { unsigned long timeout = MAX_SCHEDULE_TIMEOUT; @@ -1038,5 +1038,6 @@ nlmsvc_retry_blocked(void) } spin_unlock(&nlm_blocked_lock); - return timeout; + if (timeout < MAX_SCHEDULE_TIMEOUT) + mod_timer(&nlmsvc_retry, jiffies + timeout); } diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 914d2402ca98..c47834970224 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -82,7 +82,7 @@ nfs4_callback_svc(void *vrqstp) /* * Listen for a request on the socket */ - svc_recv(rqstp, MAX_SCHEDULE_TIMEOUT); + svc_recv(rqstp); } svc_exit_thread(rqstp); diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 5bf48c33986e..b536b254c59e 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -979,7 +979,7 @@ nfsd(void *vrqstp) * Find a socket with data available and call its * recvfrom routine. */ - svc_recv(rqstp, 60*60*HZ); + svc_recv(rqstp); validate_process_creds(); } diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index f42594a9efe0..0f016d69c996 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h @@ -204,6 +204,8 @@ extern unsigned long nlmsvc_timeout; extern bool nsm_use_hostnames; extern u32 nsm_local_state; +extern struct timer_list nlmsvc_retry; + /* * Lockd client functions */ @@ -280,7 +282,7 @@ __be32 nlmsvc_testlock(struct svc_rqst *, struct nlm_file *, struct nlm_host *, struct nlm_lock *, struct nlm_lock *, struct nlm_cookie *); __be32 nlmsvc_cancel_blocked(struct net *net, struct nlm_file *, struct nlm_lock *); -unsigned long nlmsvc_retry_blocked(void); +void nlmsvc_retry_blocked(void); void nlmsvc_traverse_blocks(struct nlm_host *, struct nlm_file *, nlm_host_match_fn_t match); void nlmsvc_grant_reply(struct nlm_cookie *, __be32); diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index d51ae1e109b6..f3df7f963653 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -41,7 +41,6 @@ struct svc_pool { struct percpu_counter sp_messages_arrived; struct percpu_counter sp_sockets_queued; struct percpu_counter sp_threads_woken; - struct percpu_counter sp_threads_timedout; struct percpu_counter sp_threads_starved; struct percpu_counter sp_threads_no_work; diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h index fb5c98069356..8da31799affe 100644 --- a/include/linux/sunrpc/svcsock.h +++ b/include/linux/sunrpc/svcsock.h @@ -64,7 +64,7 @@ static inline u32 svc_sock_final_rec(struct svc_sock *svsk) * Function prototypes. */ void svc_close_net(struct svc_serv *, struct net *); -void svc_recv(struct svc_rqst *, long); +void svc_recv(struct svc_rqst *); void svc_send(struct svc_rqst *rqstp); void svc_drop(struct svc_rqst *); void svc_sock_update_bufs(struct svc_serv *serv); diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index f09b0cce041c..170eabc03988 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -513,7 +513,6 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools, percpu_counter_init(&pool->sp_messages_arrived, 0, GFP_KERNEL); percpu_counter_init(&pool->sp_sockets_queued, 0, GFP_KERNEL); percpu_counter_init(&pool->sp_threads_woken, 0, GFP_KERNEL); - percpu_counter_init(&pool->sp_threads_timedout, 0, GFP_KERNEL); percpu_counter_init(&pool->sp_threads_starved, 0, GFP_KERNEL); percpu_counter_init(&pool->sp_threads_no_work, 0, GFP_KERNEL); @@ -593,7 +592,6 @@ svc_destroy(struct kref *ref) percpu_counter_destroy(&pool->sp_messages_arrived); percpu_counter_destroy(&pool->sp_sockets_queued); percpu_counter_destroy(&pool->sp_threads_woken); - percpu_counter_destroy(&pool->sp_threads_timedout); percpu_counter_destroy(&pool->sp_threads_starved); percpu_counter_destroy(&pool->sp_threads_no_work); } diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 67825eef8646..44a33b1f542f 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -735,10 +735,9 @@ rqst_should_sleep(struct svc_rqst *rqstp) return true; } -static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout) +static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp) { struct svc_pool *pool = rqstp->rq_pool; - long time_left = 0; /* rq_xprt should be clear on entry */ WARN_ON_ONCE(rqstp->rq_xprt); @@ -756,7 +755,7 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout) smp_mb__after_atomic(); if (likely(rqst_should_sleep(rqstp))) - time_left = schedule_timeout(timeout); + schedule(); else __set_current_state(TASK_RUNNING); @@ -770,8 +769,6 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout) goto out_found; } - if (!time_left) - percpu_counter_inc(&pool->sp_threads_timedout); if (kthread_should_stop()) return NULL; percpu_counter_inc(&pool->sp_threads_no_work); @@ -856,7 +853,7 @@ static int svc_handle_xprt(struct svc_rqst *rqstp, struct svc_xprt *xprt) * organised not to touch any cachelines in the shared svc_serv * structure, only cachelines in the local svc_pool. */ -void svc_recv(struct svc_rqst *rqstp, long timeout) +void svc_recv(struct svc_rqst *rqstp) { struct svc_xprt *xprt = NULL; struct svc_serv *serv = rqstp->rq_server; @@ -870,7 +867,7 @@ void svc_recv(struct svc_rqst *rqstp, long timeout) if (kthread_should_stop()) goto out; - xprt = svc_get_next_xprt(rqstp, timeout); + xprt = svc_get_next_xprt(rqstp); if (!xprt) goto out; @@ -1437,14 +1434,14 @@ static int svc_pool_stats_show(struct seq_file *m, void *p) return 0; } - seq_printf(m, "%u %llu %llu %llu %llu %llu %llu\n", - pool->sp_id, - percpu_counter_sum_positive(&pool->sp_messages_arrived), - percpu_counter_sum_positive(&pool->sp_sockets_queued), - percpu_counter_sum_positive(&pool->sp_threads_woken), - percpu_counter_sum_positive(&pool->sp_threads_timedout), - percpu_counter_sum_positive(&pool->sp_threads_starved), - percpu_counter_sum_positive(&pool->sp_threads_no_work)); + seq_printf(m, "%u %llu %llu %llu 0 %llu %llu\n", + pool->sp_id, + percpu_counter_sum_positive(&pool->sp_messages_arrived), + percpu_counter_sum_positive(&pool->sp_sockets_queued), + percpu_counter_sum_positive(&pool->sp_threads_woken), + /* prevously pool->sp_threads_timedout */ + percpu_counter_sum_positive(&pool->sp_threads_starved), + percpu_counter_sum_positive(&pool->sp_threads_no_work)); return 0; } From patchwork Tue Jul 18 06:38:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: NeilBrown X-Patchwork-Id: 13316782 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 50280EB64DC for ; Tue, 18 Jul 2023 06:39:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229736AbjGRGjm (ORCPT ); Tue, 18 Jul 2023 02:39:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44656 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229811AbjGRGjl (ORCPT ); Tue, 18 Jul 2023 02:39:41 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 74FB11A2 for ; Mon, 17 Jul 2023 23:39:31 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id ECEA71FDBC; Tue, 18 Jul 2023 06:39:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1689662369; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=XqoF4aRq/tppdG0+gAmx1ALCkLGey3yj574bSfpsbxw=; b=nKiQ+WLC5nU8KSEZzshB3bcjtIXjq75QMRb91pda48cwprDtjbqeoVnz4ViOoO1EqA48h1 gqp31NJK7g5i2MpKUMjaP0UZhYtYGNm3h6QZiLcJOgy5JSwvQrc4+xFGxh6znwjnOqimqt 3RxXns91bjXxqE0jglUQEZahkieivoE= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1689662369; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=XqoF4aRq/tppdG0+gAmx1ALCkLGey3yj574bSfpsbxw=; b=YH2/xG95a0Zc2I7ln6syTHcA9JjtbAdgxA67ntCgO7GG3x8MxyQFLW1rVyLE6GgYlMhCR/ zJH+Kwrgy73Z99Cw== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id AAA2A13494; Tue, 18 Jul 2023 06:39:28 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id Vx9AF6AztmSHDAAAMHmgww (envelope-from ); Tue, 18 Jul 2023 06:39:28 +0000 Subject: [PATCH 06/14] SUNRPC: change various server-side #defines to enum From: NeilBrown To: Chuck Lever , Jeff Layton Cc: linux-nfs@vger.kernel.org Date: Tue, 18 Jul 2023 16:38:08 +1000 Message-ID: <168966228863.11075.8173252015139876869.stgit@noble.brown> In-Reply-To: <168966227838.11075.2974227708495338626.stgit@noble.brown> References: <168966227838.11075.2974227708495338626.stgit@noble.brown> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org When a sequence of numbers are needed for internal-use only, an enum is typically best. The sequence will inevitably need to be changed one day, and having an enum means the developer doesn't need to think about renumbering after insertion or deletion. The patch will be easier to review. Signed-off-by: NeilBrown --- include/linux/sunrpc/cache.h | 11 +++++++---- include/linux/sunrpc/svc.h | 34 ++++++++++++++++++++-------------- include/linux/sunrpc/svc_xprt.h | 39 +++++++++++++++++++++------------------ include/linux/sunrpc/svcauth.h | 29 ++++++++++++++++------------- include/linux/sunrpc/xprtsock.h | 25 +++++++++++++------------ 5 files changed, 77 insertions(+), 61 deletions(-) diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h index 518bd28f5ab8..3cc4f4f0c764 100644 --- a/include/linux/sunrpc/cache.h +++ b/include/linux/sunrpc/cache.h @@ -56,10 +56,13 @@ struct cache_head { struct kref ref; unsigned long flags; }; -#define CACHE_VALID 0 /* Entry contains valid data */ -#define CACHE_NEGATIVE 1 /* Negative entry - there is no match for the key */ -#define CACHE_PENDING 2 /* An upcall has been sent but no reply received yet*/ -#define CACHE_CLEANED 3 /* Entry has been cleaned from cache */ +/* cache_head.flags */ +enum { + CACHE_VALID, /* Entry contains valid data */ + CACHE_NEGATIVE, /* Negative entry - there is no match for the key */ + CACHE_PENDING, /* An upcall has been sent but no reply received yet*/ + CACHE_CLEANED, /* Entry has been cleaned from cache */ +}; #define CACHE_NEW_EXPIRY 120 /* keep new things pending confirmation for 120 seconds */ diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index f3df7f963653..83f31a09c853 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -31,7 +31,7 @@ * node traffic on multi-node NUMA NFS servers. */ struct svc_pool { - unsigned int sp_id; /* pool id; also node id on NUMA */ + unsigned int sp_id; /* pool id; also node id on NUMA */ spinlock_t sp_lock; /* protects all fields */ struct list_head sp_sockets; /* pending sockets */ unsigned int sp_nrthreads; /* # of threads in pool */ @@ -44,12 +44,15 @@ struct svc_pool { struct percpu_counter sp_threads_starved; struct percpu_counter sp_threads_no_work; -#define SP_TASK_PENDING (0) /* still work to do even if no - * xprt is queued. */ -#define SP_CONGESTED (1) unsigned long sp_flags; } ____cacheline_aligned_in_smp; +/* bits for sp_flags */ +enum { + SP_TASK_PENDING, /* still work to do even if no xprt is queued */ + SP_CONGESTED, /* all threads are busy, none idle */ +}; + /* * RPC service. * @@ -232,16 +235,6 @@ struct svc_rqst { u32 rq_proc; /* procedure number */ u32 rq_prot; /* IP protocol */ int rq_cachetype; /* catering to nfsd */ -#define RQ_SECURE (0) /* secure port */ -#define RQ_LOCAL (1) /* local request */ -#define RQ_USEDEFERRAL (2) /* use deferral */ -#define RQ_DROPME (3) /* drop current reply */ -#define RQ_SPLICE_OK (4) /* turned off in gss privacy - * to prevent encrypting page - * cache pages */ -#define RQ_VICTIM (5) /* about to be shut down */ -#define RQ_BUSY (6) /* request is busy */ -#define RQ_DATA (7) /* request has data */ unsigned long rq_flags; /* flags field */ ktime_t rq_qtime; /* enqueue time */ @@ -272,6 +265,19 @@ struct svc_rqst { void ** rq_lease_breaker; /* The v4 client breaking a lease */ }; +/* bits for rq_flags */ +enum { + RQ_SECURE, /* secure port */ + RQ_LOCAL, /* local request */ + RQ_USEDEFERRAL, /* use deferral */ + RQ_DROPME, /* drop current reply */ + RQ_SPLICE_OK, /* turned off in gss privacy to prevent encrypting page + * cache pages */ + RQ_VICTIM, /* about to be shut down */ + RQ_BUSY, /* request is busy */ + RQ_DATA, /* request has data */ +}; + #define SVC_NET(rqst) (rqst->rq_xprt ? rqst->rq_xprt->xpt_net : rqst->rq_bc_net) /* diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h index a6b12631db21..af383d0349b3 100644 --- a/include/linux/sunrpc/svc_xprt.h +++ b/include/linux/sunrpc/svc_xprt.h @@ -56,26 +56,9 @@ struct svc_xprt { struct list_head xpt_list; struct list_head xpt_ready; unsigned long xpt_flags; -#define XPT_BUSY 0 /* enqueued/receiving */ -#define XPT_CONN 1 /* conn pending */ -#define XPT_CLOSE 2 /* dead or dying */ -#define XPT_DATA 3 /* data pending */ -#define XPT_TEMP 4 /* connected transport */ -#define XPT_DEAD 6 /* transport closed */ -#define XPT_CHNGBUF 7 /* need to change snd/rcv buf sizes */ -#define XPT_DEFERRED 8 /* deferred request pending */ -#define XPT_OLD 9 /* used for xprt aging mark+sweep */ -#define XPT_LISTENER 10 /* listening endpoint */ -#define XPT_CACHE_AUTH 11 /* cache auth info */ -#define XPT_LOCAL 12 /* connection from loopback interface */ -#define XPT_KILL_TEMP 13 /* call xpo_kill_temp_xprt before closing */ -#define XPT_CONG_CTRL 14 /* has congestion control */ -#define XPT_HANDSHAKE 15 /* xprt requests a handshake */ -#define XPT_TLS_SESSION 16 /* transport-layer security established */ -#define XPT_PEER_AUTH 17 /* peer has been authenticated */ struct svc_serv *xpt_server; /* service for transport */ - atomic_t xpt_reserved; /* space on outq that is rsvd */ + atomic_t xpt_reserved; /* space on outq that is rsvd */ atomic_t xpt_nr_rqsts; /* Number of requests */ struct mutex xpt_mutex; /* to serialize sending data */ spinlock_t xpt_lock; /* protects sk_deferred @@ -96,6 +79,26 @@ struct svc_xprt { struct rpc_xprt *xpt_bc_xprt; /* NFSv4.1 backchannel */ struct rpc_xprt_switch *xpt_bc_xps; /* NFSv4.1 backchannel */ }; +/* flag bits for xpt_flags */ +enum { + XPT_BUSY, /* enqueued/receiving */ + XPT_CONN, /* conn pending */ + XPT_CLOSE, /* dead or dying */ + XPT_DATA, /* data pending */ + XPT_TEMP, /* connected transport */ + XPT_DEAD, /* transport closed */ + XPT_CHNGBUF, /* need to change snd/rcv buf sizes */ + XPT_DEFERRED, /* deferred request pending */ + XPT_OLD, /* used for xprt aging mark+sweep */ + XPT_LISTENER, /* listening endpoint */ + XPT_CACHE_AUTH, /* cache auth info */ + XPT_LOCAL, /* connection from loopback interface */ + XPT_KILL_TEMP, /* call xpo_kill_temp_xprt before closing */ + XPT_CONG_CTRL, /* has congestion control */ + XPT_HANDSHAKE, /* xprt requests a handshake */ + XPT_TLS_SESSION, /* transport-layer security established */ + XPT_PEER_AUTH, /* peer has been authenticated */ +}; static inline void unregister_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u) { diff --git a/include/linux/sunrpc/svcauth.h b/include/linux/sunrpc/svcauth.h index 6d9cc9080aca..8d1d0d0721d2 100644 --- a/include/linux/sunrpc/svcauth.h +++ b/include/linux/sunrpc/svcauth.h @@ -133,19 +133,22 @@ struct auth_ops { int (*set_client)(struct svc_rqst *rq); }; -#define SVC_GARBAGE 1 -#define SVC_SYSERR 2 -#define SVC_VALID 3 -#define SVC_NEGATIVE 4 -#define SVC_OK 5 -#define SVC_DROP 6 -#define SVC_CLOSE 7 /* Like SVC_DROP, but request is definitely - * lost so if there is a tcp connection, it - * should be closed - */ -#define SVC_DENIED 8 -#define SVC_PENDING 9 -#define SVC_COMPLETE 10 +/*return values for svc functions that analyse request */ +enum { + SVC_GARBAGE, + SVC_SYSERR, + SVC_VALID, + SVC_NEGATIVE, + SVC_OK, + SVC_DROP, + SVC_CLOSE, /* Like SVC_DROP, but request is definitely + * lost so if there is a tcp connection, it + * should be closed + */ + SVC_DENIED, + SVC_PENDING, + SVC_COMPLETE, +}; struct svc_xprt; diff --git a/include/linux/sunrpc/xprtsock.h b/include/linux/sunrpc/xprtsock.h index 700a1e6c047c..1ed2f446010b 100644 --- a/include/linux/sunrpc/xprtsock.h +++ b/include/linux/sunrpc/xprtsock.h @@ -81,17 +81,18 @@ struct sock_xprt { }; /* - * TCP RPC flags + * TCP RPC flags in ->sock_state */ -#define XPRT_SOCK_CONNECTING 1U -#define XPRT_SOCK_DATA_READY (2) -#define XPRT_SOCK_UPD_TIMEOUT (3) -#define XPRT_SOCK_WAKE_ERROR (4) -#define XPRT_SOCK_WAKE_WRITE (5) -#define XPRT_SOCK_WAKE_PENDING (6) -#define XPRT_SOCK_WAKE_DISCONNECT (7) -#define XPRT_SOCK_CONNECT_SENT (8) -#define XPRT_SOCK_NOSPACE (9) -#define XPRT_SOCK_IGNORE_RECV (10) - +enum { + XPRT_SOCK_CONNECTING, + XPRT_SOCK_DATA_READY, + XPRT_SOCK_UPD_TIMEOUT, + XPRT_SOCK_WAKE_ERROR, + XPRT_SOCK_WAKE_WRITE, + XPRT_SOCK_WAKE_PENDING, + XPRT_SOCK_WAKE_DISCONNECT, + XPRT_SOCK_CONNECT_SENT, + XPRT_SOCK_NOSPACE, + XPRT_SOCK_IGNORE_RECV, +}; #endif /* _LINUX_SUNRPC_XPRTSOCK_H */ From patchwork Tue Jul 18 06:38:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: NeilBrown X-Patchwork-Id: 13316783 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D2E9BEB64DC for ; Tue, 18 Jul 2023 06:39:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231263AbjGRGjs (ORCPT ); Tue, 18 Jul 2023 02:39:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45110 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231320AbjGRGjq (ORCPT ); Tue, 18 Jul 2023 02:39:46 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 290EB1722 for ; Mon, 17 Jul 2023 23:39:36 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id DF5D81FDBF; Tue, 18 Jul 2023 06:39:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1689662374; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=h+oQs4XlArrHxV/X0+QOfyQHqu7jXMUGddWKRRlBwWc=; b=vuC9NmdXWSdXDP8CPf74TOTiVa2C0i2DPezZv1pjy5zEQKz6j6BlKzr4ziEk0DdyJr9U5M FdZ4LLDKMt0kfCj/8ooo8dHc4qvkHbv5nAgMkYvUFaEVW5ktEuDfYOAzQ944Up52M8TrYT AFk0YBxDUkx1rKePkLRcCRSvkAvoi+g= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1689662374; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=h+oQs4XlArrHxV/X0+QOfyQHqu7jXMUGddWKRRlBwWc=; b=IeuVzqF7Oew2jUxO1+pXOhKRWesZnU5f7pMwK0X6+EKP1PVPVC8IN6dxd9YO42bdpl6Qfi 3cZco4PpnLw//5Ag== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 9E84213494; Tue, 18 Jul 2023 06:39:33 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id YEJeFKUztmSTDAAAMHmgww (envelope-from ); Tue, 18 Jul 2023 06:39:33 +0000 Subject: [PATCH 07/14] SUNRPC: refactor svc_recv() From: NeilBrown To: Chuck Lever , Jeff Layton Cc: linux-nfs@vger.kernel.org Date: Tue, 18 Jul 2023 16:38:08 +1000 Message-ID: <168966228864.11075.17318657609206358910.stgit@noble.brown> In-Reply-To: <168966227838.11075.2974227708495338626.stgit@noble.brown> References: <168966227838.11075.2974227708495338626.stgit@noble.brown> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org svc_get_next_xprt() does a lot more than get an xprt. It mostly waits. So rename to svc_wait_for_work() and don't bother returning a value. The xprt can be found in ->rq_xprt. Also move all the code to handle ->rq_xprt into a single if branch, so that other handlers can be added there if other work is found. Remove the call to svc_xprt_dequeue() that is before we set TASK_IDLE. If there is still something to dequeue will still get it after a few more checks - no sleeping. This was an unnecessary optimisation which muddles the code. Drop a call to kthread_should_stop(). There are enough of those in svc_wait_for_work(). (This patch is best viewed with "-b") Signed-off-by: NeilBrown --- net/sunrpc/svc_xprt.c | 70 +++++++++++++++++++------------------------------ 1 file changed, 27 insertions(+), 43 deletions(-) diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 44a33b1f542f..c7095ff7d5fd 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -735,19 +735,10 @@ rqst_should_sleep(struct svc_rqst *rqstp) return true; } -static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp) +static void svc_wait_for_work(struct svc_rqst *rqstp) { struct svc_pool *pool = rqstp->rq_pool; - /* rq_xprt should be clear on entry */ - WARN_ON_ONCE(rqstp->rq_xprt); - - rqstp->rq_xprt = svc_xprt_dequeue(pool); - if (rqstp->rq_xprt) { - trace_svc_pool_polled(rqstp); - goto out_found; - } - set_current_state(TASK_IDLE); smp_mb__before_atomic(); clear_bit(SP_CONGESTED, &pool->sp_flags); @@ -769,10 +760,9 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp) goto out_found; } - if (kthread_should_stop()) - return NULL; - percpu_counter_inc(&pool->sp_threads_no_work); - return NULL; + if (!kthread_should_stop()) + percpu_counter_inc(&pool->sp_threads_no_work); + return; out_found: /* Normally we will wait up to 5 seconds for any required * cache information to be provided. @@ -781,7 +771,6 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp) rqstp->rq_chandle.thread_wait = 5*HZ; else rqstp->rq_chandle.thread_wait = 1*HZ; - return rqstp->rq_xprt; } static void svc_add_new_temp_xprt(struct svc_serv *serv, struct svc_xprt *newxpt) @@ -855,45 +844,40 @@ static int svc_handle_xprt(struct svc_rqst *rqstp, struct svc_xprt *xprt) */ void svc_recv(struct svc_rqst *rqstp) { - struct svc_xprt *xprt = NULL; - struct svc_serv *serv = rqstp->rq_server; - int len; - if (!svc_alloc_arg(rqstp)) - goto out; + return; try_to_freeze(); cond_resched(); - if (kthread_should_stop()) - goto out; - xprt = svc_get_next_xprt(rqstp); - if (!xprt) - goto out; + svc_wait_for_work(rqstp); - len = svc_handle_xprt(rqstp, xprt); + if (rqstp->rq_xprt) { + struct svc_serv *serv = rqstp->rq_server; + struct svc_xprt *xprt = rqstp->rq_xprt; + int len; - /* No data, incomplete (TCP) read, or accept() */ - if (len <= 0) - goto out_release; + len = svc_handle_xprt(rqstp, xprt); - trace_svc_xdr_recvfrom(&rqstp->rq_arg); + /* No data, incomplete (TCP) read, or accept() */ + if (len <= 0) { + rqstp->rq_res.len = 0; + svc_xprt_release(rqstp); + } else { - clear_bit(XPT_OLD, &xprt->xpt_flags); + trace_svc_xdr_recvfrom(&rqstp->rq_arg); - rqstp->rq_chandle.defer = svc_defer; + clear_bit(XPT_OLD, &xprt->xpt_flags); - if (serv->sv_stats) - serv->sv_stats->netcnt++; - percpu_counter_inc(&rqstp->rq_pool->sp_messages_arrived); - rqstp->rq_stime = ktime_get(); - svc_process(rqstp); - return; -out_release: - rqstp->rq_res.len = 0; - svc_xprt_release(rqstp); -out: - return; + rqstp->rq_chandle.defer = svc_defer; + + if (serv->sv_stats) + serv->sv_stats->netcnt++; + percpu_counter_inc(&rqstp->rq_pool->sp_messages_arrived); + rqstp->rq_stime = ktime_get(); + svc_process(rqstp); + } + } } EXPORT_SYMBOL_GPL(svc_recv); From patchwork Tue Jul 18 06:38:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: NeilBrown X-Patchwork-Id: 13316784 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 91028EB64DA for ; Tue, 18 Jul 2023 06:39:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230336AbjGRGjw (ORCPT ); Tue, 18 Jul 2023 02:39:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45172 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230512AbjGRGjv (ORCPT ); Tue, 18 Jul 2023 02:39:51 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1E164198 for ; Mon, 17 Jul 2023 23:39:41 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id D3DC221941; Tue, 18 Jul 2023 06:39:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1689662379; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7yj26PBry9bJIgKbc37t5xNObCHcwn7ezGD/vgmCewc=; b=r30nZdiihK4qgIXcJ5iFR96amhPpJlP6zMoK311vhuswQnAHDFXN10WsbvOVs7i2Fo5cdU lIgZMMxAz1jiZs5AqTz/yXWEBkuNaRC+h+mr58ZyCaOeJkJPzGialQoMonbUpzzfw7OWf+ +0/3UzyGaZ3pdrSOa2xyRPdjY0lMrSA= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1689662379; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7yj26PBry9bJIgKbc37t5xNObCHcwn7ezGD/vgmCewc=; b=a7Lfv3+jBWbjDkbUMPopMRrrDq95hHaidQfqGOGY2NR45JANQ4LjtpVzlBxu8NmU4PzHXV v7iuYu3nZNq/IIAw== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 931BE13494; Tue, 18 Jul 2023 06:39:38 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id oBZtEaoztmSYDAAAMHmgww (envelope-from ); Tue, 18 Jul 2023 06:39:38 +0000 Subject: [PATCH 08/14] SUNRPC: integrate back-channel processing with svc_recv() and svc_process() From: NeilBrown To: Chuck Lever , Jeff Layton Cc: linux-nfs@vger.kernel.org Date: Tue, 18 Jul 2023 16:38:08 +1000 Message-ID: <168966228864.11075.5425376786095915126.stgit@noble.brown> In-Reply-To: <168966227838.11075.2974227708495338626.stgit@noble.brown> References: <168966227838.11075.2974227708495338626.stgit@noble.brown> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org Using svc_recv() and svc_process() 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 Reviewed-by: Jeff Layton --- fs/nfs/callback.c | 46 ++--------------------------------- include/linux/sunrpc/svc.h | 6 +++-- net/sunrpc/backchannel_rqst.c | 8 ++---- net/sunrpc/svc.c | 2 +- net/sunrpc/svc_xprt.c | 48 ++++++++++++++++++++++++++++++++++++- net/sunrpc/xprtrdma/backchannel.c | 2 +- 6 files changed, 58 insertions(+), 54 deletions(-) diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index c47834970224..660cec36c45c 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()) { /* * Listen for a request on the socket */ @@ -90,45 +90,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) { @@ -241,10 +202,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 83f31a09c853..15d468d852b5 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 */ }; @@ -202,6 +200,10 @@ struct svc_rqst { struct rcu_head rq_rcu_head; /* for RCU deferred kfree */ struct svc_xprt * rq_xprt; /* transport ptr */ +#if defined(CONFIG_SUNRPC_BACKCHANNEL) + struct rpc_rqst *rq_cb; /* callback to be handled */ +#endif + struct sockaddr_storage rq_addr; /* peer address */ size_t rq_addrlen; struct sockaddr_storage rq_daddr; /* dest addr of request diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c index 65a6c6429a53..60b8d310bb27 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, &bc_serv->sv_pools[0]); } diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 170eabc03988..56b4a88776d5 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 @@ -724,6 +723,7 @@ struct svc_rqst *svc_pool_wake_idle_thread(struct svc_serv *serv, percpu_counter_inc(&pool->sp_threads_starved); return NULL; } +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 c7095ff7d5fd..4fdf1aaa514b 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -732,6 +733,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; } @@ -754,12 +762,31 @@ static void svc_wait_for_work(struct svc_rqst *rqstp) set_bit(RQ_BUSY, &rqstp->rq_flags); smp_mb__after_atomic(); + rqstp->rq_xprt = svc_xprt_dequeue(pool); if (rqstp->rq_xprt) { trace_svc_pool_awoken(rqstp); goto out_found; } +#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) { + list_del(&req->rq_bc_list); + rqstp->rq_cb = req; + } + spin_unlock_bh(&serv->sv_cb_lock); + if (rqstp->rq_cb) + goto out_found; + } +#endif + if (!kthread_should_stop()) percpu_counter_inc(&pool->sp_threads_no_work); return; @@ -853,7 +880,7 @@ void svc_recv(struct svc_rqst *rqstp) svc_wait_for_work(rqstp); if (rqstp->rq_xprt) { - struct svc_serv *serv = rqstp->rq_server; + struct svc_serv *serv = rqstp->rq_server; struct svc_xprt *xprt = rqstp->rq_xprt; int len; @@ -878,6 +905,25 @@ void svc_recv(struct svc_rqst *rqstp) svc_process(rqstp); } } +#if defined(CONFIG_SUNRPC_BACKCHANNEL) + if (svc_is_backchannel(rqstp)) { + struct rpc_rqst *cb; + int error; + + if (!rqstp->rq_cb) + return; + + cb = rqstp->rq_cb; + rqstp->rq_cb = NULL; + + dprintk("Invoking bc_svc_process()\n"); + error = bc_svc_process(rqstp->rq_server, cb, rqstp); + dprintk("bc_svc_process() returned w/ error code= %d\n", + error); + return; + } +#endif + } EXPORT_SYMBOL_GPL(svc_recv); diff --git a/net/sunrpc/xprtrdma/backchannel.c b/net/sunrpc/xprtrdma/backchannel.c index e4d84a13c566..f1e1d4909434 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, &bc_serv->sv_pools[0]); r_xprt->rx_stats.bcall_count++; return; From patchwork Tue Jul 18 06:38:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: NeilBrown X-Patchwork-Id: 13316785 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BC1FDEB64DA for ; Tue, 18 Jul 2023 06:39:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230506AbjGRGjz (ORCPT ); Tue, 18 Jul 2023 02:39:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45172 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229811AbjGRGjy (ORCPT ); Tue, 18 Jul 2023 02:39:54 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2CBB210FE for ; Mon, 17 Jul 2023 23:39:46 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id E01A81FDBC; Tue, 18 Jul 2023 06:39:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1689662384; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ptHijwubIK6TysBj5IR9ifg7rya3VzhHR3kVMBZpwKQ=; b=pjkpyvViyWKFCo1a7orm/sB9T8chz2xWx1vilrL6p/g7hWDXHHQgykkMhX2ciywcfx/bCD H/oJXqciOPVcgVD8kvTKiOgoQMYJTprtqMciEoUHGktpH/GzSClefvx0GL2V85M50XxTgW v7XvCCHnU61Dy09TlyITOoGzvWESnR4= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1689662384; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ptHijwubIK6TysBj5IR9ifg7rya3VzhHR3kVMBZpwKQ=; b=usIw9n0mfAki344gUve2v2w6519luS889rHDb9VnGH+l0C/X8r82hyry+0wxEqlPbC/BWb jCEPaXXKGtLD/6Ag== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 928D913494; Tue, 18 Jul 2023 06:39:43 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id ZLlBEa8ztmSkDAAAMHmgww (envelope-from ); Tue, 18 Jul 2023 06:39:43 +0000 Subject: [PATCH 09/14] SUNRPC: change how svc threads are asked to exit. From: NeilBrown To: Chuck Lever , Jeff Layton Cc: linux-nfs@vger.kernel.org Date: Tue, 18 Jul 2023 16:38:08 +1000 Message-ID: <168966228865.11075.10638610963240650169.stgit@noble.brown> In-Reply-To: <168966227838.11075.2974227708495338626.stgit@noble.brown> References: <168966227838.11075.2974227708495338626.stgit@noble.brown> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org svc threads are currently stopped using kthread_stop(). This requires identifying a specific thread. However we don't care which thread stops, just as long as one does. So instead, set a flag in the svc_pool to say that a thread needs to die, and have each thread check this flag instead of calling kthread_should_stop(). The first to find it clear the flag and moves towards shutting down. This removes an explicit dependency on sp_all_threads which will make a future patch simpler. Signed-off-by: NeilBrown --- fs/lockd/svc.c | 4 ++-- fs/lockd/svclock.c | 4 ++-- fs/nfs/callback.c | 2 +- fs/nfsd/nfs4proc.c | 8 +++++--- fs/nfsd/nfssvc.c | 2 +- include/linux/lockd/lockd.h | 2 +- include/linux/sunrpc/svc.h | 22 +++++++++++++++++++++- include/trace/events/sunrpc.h | 5 +++-- net/sunrpc/svc.c | 39 +++++++++++++++++---------------------- net/sunrpc/svc_xprt.c | 8 +++----- 10 files changed, 56 insertions(+), 40 deletions(-) diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 4f55cd42c2e6..30543edd2309 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -134,12 +134,12 @@ lockd(void *vrqstp) * The main request loop. We don't terminate until the last * NFS mount or NFS daemon has gone away. */ - while (!kthread_should_stop()) { + while (!svc_thread_should_stop(rqstp)) { /* update sv_maxconn if it has changed */ rqstp->rq_server->sv_maxconn = nlm_max_connections; - nlmsvc_retry_blocked(); + nlmsvc_retry_blocked(rqstp); /* * Find any work to do, such as a socket with data available, diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index 3d7bd5c04b36..fd399c9bea5c 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c @@ -1009,13 +1009,13 @@ retry_deferred_block(struct nlm_block *block) * be retransmitted. */ void -nlmsvc_retry_blocked(void) +nlmsvc_retry_blocked(struct svc_rqst *rqstp) { unsigned long timeout = MAX_SCHEDULE_TIMEOUT; struct nlm_block *block; spin_lock(&nlm_blocked_lock); - while (!list_empty(&nlm_blocked) && !kthread_should_stop()) { + while (!list_empty(&nlm_blocked) && !svc_thread_should_stop(rqstp)) { block = list_entry(nlm_blocked.next, struct nlm_block, b_list); if (block->b_when == NLM_NEVER) diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 660cec36c45c..c58ec2e66aaf 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -78,7 +78,7 @@ nfs4_callback_svc(void *vrqstp) set_freezable(); - while (!kthread_should_stop()) { + while (!svc_thread_should_stop(rqstp)) { /* * Listen for a request on the socket */ diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 157488290676..66024ed06181 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1306,7 +1306,8 @@ extern void nfs_sb_deactive(struct super_block *sb); * setup a work entry in the ssc delayed unmount list. */ static __be32 nfsd4_ssc_setup_dul(struct nfsd_net *nn, char *ipaddr, - struct nfsd4_ssc_umount_item **nsui) + struct nfsd4_ssc_umount_item **nsui, + struct svc_rqst *rqstp) { struct nfsd4_ssc_umount_item *ni = NULL; struct nfsd4_ssc_umount_item *work = NULL; @@ -1329,7 +1330,7 @@ static __be32 nfsd4_ssc_setup_dul(struct nfsd_net *nn, char *ipaddr, spin_unlock(&nn->nfsd_ssc_lock); /* allow 20secs for mount/unmount for now - revisit */ - if (kthread_should_stop() || + if (svc_thread_should_stop(rqstp) || (schedule_timeout(20*HZ) == 0)) { finish_wait(&nn->nfsd_ssc_waitq, &wait); kfree(work); @@ -1445,7 +1446,7 @@ nfsd4_interssc_connect(struct nl4_server *nss, struct svc_rqst *rqstp, goto out_free_rawdata; snprintf(dev_name, len + 5, "%s%s%s:/", startsep, ipaddr, endsep); - status = nfsd4_ssc_setup_dul(nn, ipaddr, nsui); + status = nfsd4_ssc_setup_dul(nn, ipaddr, nsui, rqstp); if (status) goto out_free_devname; if ((*nsui)->nsui_vfsmount) @@ -1620,6 +1621,7 @@ static ssize_t _nfsd_copy_file_range(struct nfsd4_copy *copy, if (bytes_total == 0) bytes_total = ULLONG_MAX; do { + /* Only async copies can be stopped here */ if (kthread_should_stop()) break; bytes_copied = nfsd_copy_file_range(src, src_pos, dst, dst_pos, diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index b536b254c59e..9b282c89ea87 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -971,7 +971,7 @@ nfsd(void *vrqstp) /* * The main request loop */ - while (!kthread_should_stop()) { + while (!svc_thread_should_stop(rqstp)) { /* Update sv_maxconn if it has changed */ rqstp->rq_server->sv_maxconn = nn->max_connections; diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index 0f016d69c996..9f565416d186 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h @@ -282,7 +282,7 @@ __be32 nlmsvc_testlock(struct svc_rqst *, struct nlm_file *, struct nlm_host *, struct nlm_lock *, struct nlm_lock *, struct nlm_cookie *); __be32 nlmsvc_cancel_blocked(struct net *net, struct nlm_file *, struct nlm_lock *); -void nlmsvc_retry_blocked(void); +void nlmsvc_retry_blocked(struct svc_rqst *rqstp); void nlmsvc_traverse_blocks(struct nlm_host *, struct nlm_file *, nlm_host_match_fn_t match); void nlmsvc_grant_reply(struct nlm_cookie *, __be32); diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 15d468d852b5..ea3ce1315416 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -51,6 +51,8 @@ struct svc_pool { enum { SP_TASK_PENDING, /* still work to do even if no xprt is queued */ SP_CONGESTED, /* all threads are busy, none idle */ + SP_NEED_VICTIM, /* One thread needs to agree to exit */ + SP_VICTIM_REMAINS, /* One thread needs to actually exit */ }; /* @@ -275,7 +277,7 @@ enum { RQ_DROPME, /* drop current reply */ RQ_SPLICE_OK, /* turned off in gss privacy to prevent encrypting page * cache pages */ - RQ_VICTIM, /* about to be shut down */ + RQ_VICTIM, /* Have agreed to shut down */ RQ_BUSY, /* request is busy */ RQ_DATA, /* request has data */ }; @@ -315,6 +317,24 @@ static inline struct sockaddr *svc_daddr(const struct svc_rqst *rqst) return (struct sockaddr *) &rqst->rq_daddr; } +/** + * svc_thread_should_stop - check if this thread should stop + * @rqstp: the thread that might need to stop + * + * To stop an svc thread, the pool flags SP_NEED_VICTIM and SP_VICTIM_REMAINS + * are set. The firs thread which sees SP_NEED_VICTIM clear it becoming + * the victim using this function. It should then promptly call + * svc_exit_thread() which completes the process, clearing SP_VICTIM_REMAINS + * so the task waiting for a thread to exit can wake and continue. + */ +static inline bool svc_thread_should_stop(struct svc_rqst *rqstp) +{ + if (test_and_clear_bit(SP_NEED_VICTIM, &rqstp->rq_pool->sp_flags)) + set_bit(RQ_VICTIM, &rqstp->rq_flags); + + return test_bit(RQ_VICTIM, &rqstp->rq_flags); +} + struct svc_deferred_req { u32 prot; /* protocol (UDP or TCP) */ struct svc_xprt *xprt; diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h index 60c8e03268d4..c79375e37dc2 100644 --- a/include/trace/events/sunrpc.h +++ b/include/trace/events/sunrpc.h @@ -2041,8 +2041,9 @@ TRACE_EVENT(svc_xprt_enqueue, #define show_svc_pool_flags(x) \ __print_flags(x, "|", \ { BIT(SP_TASK_PENDING), "TASK_PENDING" }, \ - { BIT(SP_CONGESTED), "CONGESTED" }) - + { BIT(SP_CONGESTED), "CONGESTED" }, \ + { BIT(SP_NEED_VICTIM), "NEED_VICTIM" }, \ + { BIT(SP_VICTIM_REMAINS), "VICTIM_REMAINS" }) DECLARE_EVENT_CLASS(svc_pool_scheduler_class, TP_PROTO( const struct svc_rqst *rqstp diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 56b4a88776d5..b18175ef74ec 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -731,19 +731,22 @@ svc_pool_next(struct svc_serv *serv, struct svc_pool *pool, unsigned int *state) return pool ? pool : &serv->sv_pools[(*state)++ % serv->sv_nrpools]; } -static struct task_struct * +static struct svc_pool * svc_pool_victim(struct svc_serv *serv, struct svc_pool *pool, unsigned int *state) { unsigned int i; - struct task_struct *task = NULL; if (pool != NULL) { spin_lock_bh(&pool->sp_lock); + if (pool->sp_nrthreads) + goto found_pool; + spin_unlock_bh(&pool->sp_lock); + return NULL; } else { for (i = 0; i < serv->sv_nrpools; i++) { pool = &serv->sv_pools[--(*state) % serv->sv_nrpools]; spin_lock_bh(&pool->sp_lock); - if (!list_empty(&pool->sp_all_threads)) + if (pool->sp_nrthreads) goto found_pool; spin_unlock_bh(&pool->sp_lock); } @@ -751,16 +754,10 @@ svc_pool_victim(struct svc_serv *serv, struct svc_pool *pool, unsigned int *stat } found_pool: - if (!list_empty(&pool->sp_all_threads)) { - struct svc_rqst *rqstp; - - rqstp = list_entry(pool->sp_all_threads.next, struct svc_rqst, rq_all); - set_bit(RQ_VICTIM, &rqstp->rq_flags); - list_del_rcu(&rqstp->rq_all); - task = rqstp->rq_task; - } + set_bit(SP_VICTIM_REMAINS, &pool->sp_flags); + set_bit(SP_NEED_VICTIM, &pool->sp_flags); spin_unlock_bh(&pool->sp_lock); - return task; + return pool; } static int @@ -801,18 +798,16 @@ svc_start_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs) static int svc_stop_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs) { - struct svc_rqst *rqstp; - struct task_struct *task; unsigned int state = serv->sv_nrthreads-1; + struct svc_pool *vpool; do { - task = svc_pool_victim(serv, pool, &state); - if (task == NULL) + vpool = svc_pool_victim(serv, pool, &state); + if (!vpool) break; - rqstp = kthread_data(task); - /* Did we lose a race to svo_function threadfn? */ - if (kthread_stop(task) == -EINTR) - svc_exit_thread(rqstp); + svc_pool_wake_idle_thread(serv, vpool); + wait_on_bit(&vpool->sp_flags, SP_VICTIM_REMAINS, + TASK_IDLE); nrservs++; } while (nrservs < 0); return 0; @@ -932,8 +927,6 @@ svc_exit_thread(struct svc_rqst *rqstp) spin_lock_bh(&pool->sp_lock); pool->sp_nrthreads--; - if (!test_and_set_bit(RQ_VICTIM, &rqstp->rq_flags)) - list_del_rcu(&rqstp->rq_all); spin_unlock_bh(&pool->sp_lock); spin_lock_bh(&serv->sv_lock); @@ -941,6 +934,8 @@ svc_exit_thread(struct svc_rqst *rqstp) spin_unlock_bh(&serv->sv_lock); svc_sock_update_bufs(serv); + if (svc_thread_should_stop(rqstp)) + clear_and_wake_up_bit(SP_VICTIM_REMAINS, &pool->sp_flags); svc_rqst_free(rqstp); svc_put(serv); diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 4fdf1aaa514b..948605e7043b 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -595,8 +595,6 @@ void svc_wake_up(struct svc_serv *serv) smp_wmb(); return; } - - trace_svc_wake_up(rqstp); } EXPORT_SYMBOL_GPL(svc_wake_up); @@ -688,7 +686,7 @@ static bool svc_alloc_arg(struct svc_rqst *rqstp) continue; set_current_state(TASK_IDLE); - if (kthread_should_stop()) { + if (svc_thread_should_stop(rqstp)) { set_current_state(TASK_RUNNING); return false; } @@ -726,7 +724,7 @@ rqst_should_sleep(struct svc_rqst *rqstp) return false; /* are we shutting down? */ - if (kthread_should_stop()) + if (svc_thread_should_stop(rqstp)) return false; /* are we freezing? */ @@ -787,7 +785,7 @@ static void svc_wait_for_work(struct svc_rqst *rqstp) } #endif - if (!kthread_should_stop()) + if (!svc_thread_should_stop(rqstp)) percpu_counter_inc(&pool->sp_threads_no_work); return; out_found: From patchwork Tue Jul 18 06:38:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: NeilBrown X-Patchwork-Id: 13316786 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6FCBAEB64DC for ; Tue, 18 Jul 2023 06:39:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229852AbjGRGj6 (ORCPT ); Tue, 18 Jul 2023 02:39:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45306 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231320AbjGRGj5 (ORCPT ); Tue, 18 Jul 2023 02:39:57 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0007818D for ; Mon, 17 Jul 2023 23:39:50 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id B652921958; Tue, 18 Jul 2023 06:39:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1689662389; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=s3rS0Fzh/IEriQML3zezsBkppTenxYtL7izNLfLsUoU=; b=VsaW3rkHRdew68WLttKkwR9KYrg0NKakZOUmWvBXMHFhU2SeuzFg2d6iPzgKRRFXd34VPl +Db+zIRTgzmSICoU5LRz7ggtFht7Hy4oUAstkRBL3gd3rf83glbRPm7JZG7ML/iwPvTe/u Nx7zVKFU3vLlryDQs95qlTBLnPoju94= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1689662389; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=s3rS0Fzh/IEriQML3zezsBkppTenxYtL7izNLfLsUoU=; b=YRBQvNYGF7m08sJfdZtyGxQfSPyPPESgV+YE78JcNMNNocbMtlLT/6SCRSVTHMZDnskxw6 rP68GzVl8CN+jhBw== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 7759D13494; Tue, 18 Jul 2023 06:39:48 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id YBDPCrQztmSsDAAAMHmgww (envelope-from ); Tue, 18 Jul 2023 06:39:48 +0000 Subject: [PATCH 10/14] SUNRPC: change svc_pool_wake_idle_thread() to return nothing. From: NeilBrown To: Chuck Lever , Jeff Layton Cc: linux-nfs@vger.kernel.org Date: Tue, 18 Jul 2023 16:38:08 +1000 Message-ID: <168966228866.11075.18415964365983945832.stgit@noble.brown> In-Reply-To: <168966227838.11075.2974227708495338626.stgit@noble.brown> References: <168966227838.11075.2974227708495338626.stgit@noble.brown> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org No callers of svc_pool_wake_idle_thread() care which thread was woken - except one that wants to trace the wakeup. For now we drop that tracepoint. One caller wants to know if anything was woken to set SP_CONGESTED, so set that inside the function instead. Now svc_pool_wake_idle_thread() can "return" void. Signed-off-by: NeilBrown --- include/linux/sunrpc/svc.h | 2 +- net/sunrpc/svc.c | 13 +++++-------- net/sunrpc/svc_xprt.c | 18 +++--------------- 3 files changed, 9 insertions(+), 24 deletions(-) diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index ea3ce1315416..b39c613fbe06 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -454,7 +454,7 @@ int svc_register(const struct svc_serv *, struct net *, const int, void svc_wake_up(struct svc_serv *); void svc_reserve(struct svc_rqst *rqstp, int space); -struct svc_rqst *svc_pool_wake_idle_thread(struct svc_serv *serv, +void svc_pool_wake_idle_thread(struct svc_serv *serv, struct svc_pool *pool); struct svc_pool *svc_pool_for_cpu(struct svc_serv *serv); char * svc_print_addr(struct svc_rqst *, char *, size_t); diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index b18175ef74ec..fd49e7b12c94 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -696,13 +696,10 @@ svc_prepare_thread(struct svc_serv *serv, struct svc_pool *pool, int node) * @serv: RPC service * @pool: service thread pool * - * Returns an idle service thread (now marked BUSY), or NULL - * if no service threads are available. Finding an idle service - * thread and marking it BUSY is atomic with respect to other - * calls to svc_pool_wake_idle_thread(). + * Wake an idle thread if there is one, else mark the pool as congested. */ -struct svc_rqst *svc_pool_wake_idle_thread(struct svc_serv *serv, - struct svc_pool *pool) +void svc_pool_wake_idle_thread(struct svc_serv *serv, + struct svc_pool *pool) { struct svc_rqst *rqstp; @@ -715,13 +712,13 @@ struct svc_rqst *svc_pool_wake_idle_thread(struct svc_serv *serv, wake_up_process(rqstp->rq_task); rcu_read_unlock(); percpu_counter_inc(&pool->sp_threads_woken); - return rqstp; + return; } rcu_read_unlock(); trace_svc_pool_starved(serv, pool); percpu_counter_inc(&pool->sp_threads_starved); - return NULL; + set_bit(SP_CONGESTED, &pool->sp_flags); } EXPORT_SYMBOL_GPL(svc_pool_wake_idle_thread); diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 948605e7043b..964c97dbb36c 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -456,7 +456,6 @@ static bool svc_xprt_ready(struct svc_xprt *xprt) */ void svc_xprt_enqueue(struct svc_xprt *xprt) { - struct svc_rqst *rqstp; struct svc_pool *pool; if (!svc_xprt_ready(xprt)) @@ -477,13 +476,7 @@ void svc_xprt_enqueue(struct svc_xprt *xprt) list_add_tail(&xprt->xpt_ready, &pool->sp_sockets); spin_unlock_bh(&pool->sp_lock); - rqstp = svc_pool_wake_idle_thread(xprt->xpt_server, pool); - if (!rqstp) { - set_bit(SP_CONGESTED, &pool->sp_flags); - return; - } - - trace_svc_xprt_enqueue(xprt, rqstp); + svc_pool_wake_idle_thread(xprt->xpt_server, pool); } EXPORT_SYMBOL_GPL(svc_xprt_enqueue); @@ -587,14 +580,9 @@ static void svc_xprt_release(struct svc_rqst *rqstp) void svc_wake_up(struct svc_serv *serv) { struct svc_pool *pool = &serv->sv_pools[0]; - struct svc_rqst *rqstp; - rqstp = svc_pool_wake_idle_thread(serv, pool); - if (!rqstp) { - set_bit(SP_TASK_PENDING, &pool->sp_flags); - smp_wmb(); - return; - } + set_bit(SP_TASK_PENDING, &pool->sp_flags); + svc_pool_wake_idle_thread(serv, pool); } EXPORT_SYMBOL_GPL(svc_wake_up); From patchwork Tue Jul 18 06:38:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: NeilBrown X-Patchwork-Id: 13316787 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 92B72EB64DA for ; Tue, 18 Jul 2023 06:40:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231417AbjGRGkC (ORCPT ); Tue, 18 Jul 2023 02:40:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45304 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231320AbjGRGj7 (ORCPT ); Tue, 18 Jul 2023 02:39:59 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D95431B0 for ; Mon, 17 Jul 2023 23:39:55 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 9B74421941; Tue, 18 Jul 2023 06:39:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1689662394; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cSGNQZEHi++LUkhWW/OEbZIQi0ieTK4HhgMp8fiPYzU=; b=vaaQYiJhwSZPqDZHNlwigEoB7flylNFzcwUKRP4k5xJq4LKxTT8XQXt3AV2rE0GgjKIcoa B55eCwVr8aMbkNXrXxhapOuRNVev0l0E0s+rCqzDcdup0l15mDe3109scuMgonU/39IFrz cuKED7q2XPojyasWxvrlNweWXR7sDVg= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1689662394; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cSGNQZEHi++LUkhWW/OEbZIQi0ieTK4HhgMp8fiPYzU=; b=poIBWBs2r4Pyevt5eQxZ6j+29ceRPP4sQ2u+pVViaziSpXk4/Q6Lh1FlWiHa+uIhSrW6GC HvIQoDoAz0+LTrCw== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 5D07013494; Tue, 18 Jul 2023 06:39:53 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id 3F5vBLkztmSwDAAAMHmgww (envelope-from ); Tue, 18 Jul 2023 06:39:53 +0000 Subject: [PATCH 11/14] SUNRPC: add list of idle threads From: NeilBrown To: Chuck Lever , Jeff Layton Cc: linux-nfs@vger.kernel.org Date: Tue, 18 Jul 2023 16:38:08 +1000 Message-ID: <168966228866.11075.7106156297520815780.stgit@noble.brown> In-Reply-To: <168966227838.11075.2974227708495338626.stgit@noble.brown> References: <168966227838.11075.2974227708495338626.stgit@noble.brown> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org Rather than searching a list of threads to find an idle one, having a list of idle threads allows an idle thread to be found immediately. This adds some spin_lock calls which is not ideal, but as the hold-time is tiny it is still faster than searching a list. A future patch will remove them using llist.h. This involves some subtlety and so is left to a separate patch. Signed-off-by: NeilBrown --- include/linux/sunrpc/svc.h | 25 ++++++++++++++++++++++++- include/trace/events/sunrpc.h | 1 - net/sunrpc/svc.c | 13 ++++++++----- net/sunrpc/svc_xprt.c | 17 ++++++++++++----- 4 files changed, 44 insertions(+), 12 deletions(-) diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index b39c613fbe06..ec8088d5b57f 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -36,6 +36,7 @@ struct svc_pool { struct list_head sp_sockets; /* pending sockets */ unsigned int sp_nrthreads; /* # of threads in pool */ struct list_head sp_all_threads; /* all server threads */ + struct list_head sp_idle_threads; /* idle server threads */ /* statistics on pool operation */ struct percpu_counter sp_messages_arrived; @@ -199,6 +200,7 @@ extern u32 svc_max_payload(const struct svc_rqst *rqstp); */ struct svc_rqst { struct list_head rq_all; /* all threads list */ + struct list_head rq_idle; /* On the idle list */ struct rcu_head rq_rcu_head; /* for RCU deferred kfree */ struct svc_xprt * rq_xprt; /* transport ptr */ @@ -278,10 +280,31 @@ enum { RQ_SPLICE_OK, /* turned off in gss privacy to prevent encrypting page * cache pages */ RQ_VICTIM, /* Have agreed to shut down */ - RQ_BUSY, /* request is busy */ RQ_DATA, /* request has data */ }; +/** + * svc_thread_set_busy - mark a thread as busy + * @rqstp: the thread which is now busy + * + * If rq_idle is "empty", the thread must be busy. + */ +static inline void svc_thread_set_busy(struct svc_rqst *rqstp) +{ + INIT_LIST_HEAD(&rqstp->rq_idle); +} + +/** + * svc_thread_busy - check if a thread as busy + * @rqstp: the thread which might be busy + * + * If rq_idle is "empty", the thread must be busy. + */ +static inline bool svc_thread_busy(struct svc_rqst *rqstp) +{ + return list_empty(&rqstp->rq_idle); +} + #define SVC_NET(rqst) (rqst->rq_xprt ? rqst->rq_xprt->xpt_net : rqst->rq_bc_net) /* diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h index c79375e37dc2..dd0323c40ef5 100644 --- a/include/trace/events/sunrpc.h +++ b/include/trace/events/sunrpc.h @@ -1677,7 +1677,6 @@ DEFINE_SVCXDRBUF_EVENT(sendto); svc_rqst_flag(DROPME) \ svc_rqst_flag(SPLICE_OK) \ svc_rqst_flag(VICTIM) \ - svc_rqst_flag(BUSY) \ svc_rqst_flag_end(DATA) #undef svc_rqst_flag diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index fd49e7b12c94..028de8f662a8 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -644,7 +644,7 @@ svc_rqst_alloc(struct svc_serv *serv, struct svc_pool *pool, int node) folio_batch_init(&rqstp->rq_fbatch); - __set_bit(RQ_BUSY, &rqstp->rq_flags); + svc_thread_set_busy(rqstp); rqstp->rq_server = serv; rqstp->rq_pool = pool; @@ -704,10 +704,13 @@ void svc_pool_wake_idle_thread(struct svc_serv *serv, struct svc_rqst *rqstp; rcu_read_lock(); - list_for_each_entry_rcu(rqstp, &pool->sp_all_threads, rq_all) { - if (test_and_set_bit(RQ_BUSY, &rqstp->rq_flags)) - continue; - + spin_lock_bh(&pool->sp_lock); + rqstp = list_first_entry_or_null(&pool->sp_idle_threads, + struct svc_rqst, rq_idle); + if (rqstp) + list_del_init(&rqstp->rq_idle); + spin_unlock_bh(&pool->sp_lock); + if (rqstp) { WRITE_ONCE(rqstp->rq_qtime, ktime_get()); wake_up_process(rqstp->rq_task); rcu_read_unlock(); diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 964c97dbb36c..1d134415ae3f 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -736,18 +736,25 @@ static void svc_wait_for_work(struct svc_rqst *rqstp) set_current_state(TASK_IDLE); smp_mb__before_atomic(); clear_bit(SP_CONGESTED, &pool->sp_flags); - clear_bit(RQ_BUSY, &rqstp->rq_flags); - smp_mb__after_atomic(); + spin_lock_bh(&pool->sp_lock); + list_add(&rqstp->rq_idle, &pool->sp_idle_threads); + spin_unlock_bh(&pool->sp_lock); if (likely(rqst_should_sleep(rqstp))) schedule(); else __set_current_state(TASK_RUNNING); - try_to_freeze(); + /* We *must* be removed from the list before we can continue. + * If we were woken, this is already done + */ + if (!svc_thread_busy(rqstp)) { + spin_lock_bh(&pool->sp_lock); + list_del_init(&rqstp->rq_idle); + spin_unlock_bh(&pool->sp_lock); + } - set_bit(RQ_BUSY, &rqstp->rq_flags); - smp_mb__after_atomic(); + try_to_freeze(); rqstp->rq_xprt = svc_xprt_dequeue(pool); if (rqstp->rq_xprt) { From patchwork Tue Jul 18 06:38:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: NeilBrown X-Patchwork-Id: 13316788 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A2F6DC0015E for ; Tue, 18 Jul 2023 06:40:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231327AbjGRGkE (ORCPT ); Tue, 18 Jul 2023 02:40:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45408 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231419AbjGRGkB (ORCPT ); Tue, 18 Jul 2023 02:40:01 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C42E9198 for ; Mon, 17 Jul 2023 23:40:00 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 850B21FDBA; Tue, 18 Jul 2023 06:39:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1689662399; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+bfJ1VuW+ZT3TDo1UBsHK1TgxY9tHa4ugAu73odV2dQ=; b=AmS8CDarNCgUaH6jRl1nFAb052GWHG3JCsd/tsH3Y3J6vz/hx0DZEjQQL4yX+OHVERcSkV g76bjLBObtzytJLlKfTgEPiNRAKmtFtWuE1TwHNPrXjtrZcEwIx/vZgIGjszKsRBdTyWEv pvscoIRUB3IX4qdXYbg3sGZTCMj9NpI= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1689662399; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+bfJ1VuW+ZT3TDo1UBsHK1TgxY9tHa4ugAu73odV2dQ=; b=y7tTnybFywV8lCs+saeqyMUaUry6tQdP9xdEdxsxjgRBK12m5lRsTZv5SrVVkaCUq4mOh+ qTPTDc8j2wTmSNDQ== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 3D04E13494; Tue, 18 Jul 2023 06:39:57 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id blUfOL0ztmS/DAAAMHmgww (envelope-from ); Tue, 18 Jul 2023 06:39:57 +0000 Subject: [PATCH 12/14] SUNRPC: discard SP_CONGESTED From: NeilBrown To: Chuck Lever , Jeff Layton Cc: linux-nfs@vger.kernel.org Date: Tue, 18 Jul 2023 16:38:08 +1000 Message-ID: <168966228867.11075.5024166935997611658.stgit@noble.brown> In-Reply-To: <168966227838.11075.2974227708495338626.stgit@noble.brown> References: <168966227838.11075.2974227708495338626.stgit@noble.brown> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org We can tell if a pool is congested by checking if the idle list is empty. We don't need a separate flag. Signed-off-by: NeilBrown --- include/linux/sunrpc/svc.h | 1 - include/trace/events/sunrpc.h | 1 - net/sunrpc/svc.c | 1 - net/sunrpc/svc_xprt.c | 4 +--- 4 files changed, 1 insertion(+), 6 deletions(-) diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index ec8088d5b57f..f5b69e6da0f8 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -51,7 +51,6 @@ struct svc_pool { /* bits for sp_flags */ enum { SP_TASK_PENDING, /* still work to do even if no xprt is queued */ - SP_CONGESTED, /* all threads are busy, none idle */ SP_NEED_VICTIM, /* One thread needs to agree to exit */ SP_VICTIM_REMAINS, /* One thread needs to actually exit */ }; diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h index dd0323c40ef5..470c5ba07fba 100644 --- a/include/trace/events/sunrpc.h +++ b/include/trace/events/sunrpc.h @@ -2040,7 +2040,6 @@ TRACE_EVENT(svc_xprt_enqueue, #define show_svc_pool_flags(x) \ __print_flags(x, "|", \ { BIT(SP_TASK_PENDING), "TASK_PENDING" }, \ - { BIT(SP_CONGESTED), "CONGESTED" }, \ { BIT(SP_NEED_VICTIM), "NEED_VICTIM" }, \ { BIT(SP_VICTIM_REMAINS), "VICTIM_REMAINS" }) DECLARE_EVENT_CLASS(svc_pool_scheduler_class, diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 028de8f662a8..f6da390932cd 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -721,7 +721,6 @@ void svc_pool_wake_idle_thread(struct svc_serv *serv, trace_svc_pool_starved(serv, pool); percpu_counter_inc(&pool->sp_threads_starved); - set_bit(SP_CONGESTED, &pool->sp_flags); } EXPORT_SYMBOL_GPL(svc_pool_wake_idle_thread); diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 1d134415ae3f..b82a66f68f17 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -734,8 +734,6 @@ static void svc_wait_for_work(struct svc_rqst *rqstp) struct svc_pool *pool = rqstp->rq_pool; set_current_state(TASK_IDLE); - smp_mb__before_atomic(); - clear_bit(SP_CONGESTED, &pool->sp_flags); spin_lock_bh(&pool->sp_lock); list_add(&rqstp->rq_idle, &pool->sp_idle_threads); spin_unlock_bh(&pool->sp_lock); @@ -787,7 +785,7 @@ static void svc_wait_for_work(struct svc_rqst *rqstp) /* Normally we will wait up to 5 seconds for any required * cache information to be provided. */ - if (!test_bit(SP_CONGESTED, &pool->sp_flags)) + if (!list_empty(&pool->sp_idle_threads)) rqstp->rq_chandle.thread_wait = 5*HZ; else rqstp->rq_chandle.thread_wait = 1*HZ; From patchwork Tue Jul 18 06:38:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: NeilBrown X-Patchwork-Id: 13316789 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0B5D5EB64DA for ; Tue, 18 Jul 2023 06:40:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230451AbjGRGkK (ORCPT ); Tue, 18 Jul 2023 02:40:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45582 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230512AbjGRGkJ (ORCPT ); Tue, 18 Jul 2023 02:40:09 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 223FB18B for ; Mon, 17 Jul 2023 23:40:05 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 6D0731FDBC; Tue, 18 Jul 2023 06:40:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1689662404; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=k1/4gT7LMd1Y2NHFUexFp26CiG8lpSWxUIeJR9tPvB4=; b=Jt/19zwB1l16thGbuVGbPYLmda/YrwoiZ5+deiaxvQwt/F6jZIJ5j8cpsLuLGXVdfkY7px 5ocn4F75aau0mywYK0JGx75Wthejjkfen7kz9ePijwVw1yxILaD2SBv9zz2UC0iPnSQUsh rY3BfZriYZiYi8xHRKRyvRzWL2IBQVA= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1689662404; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=k1/4gT7LMd1Y2NHFUexFp26CiG8lpSWxUIeJR9tPvB4=; b=TZizD6vdNq9S38Nsk6OeA8mwSrymgJ3RWjvsg01WZ4dDpuuFybY8n3OO1Vs/nWp8UP+Fso ArOvZA2J5CPZRZAQ== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 2F14813494; Tue, 18 Jul 2023 06:40:02 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id e0XNNMIztmTTDAAAMHmgww (envelope-from ); Tue, 18 Jul 2023 06:40:02 +0000 Subject: [PATCH 13/14] SUNRPC: change service idle list to be an llist From: NeilBrown To: Chuck Lever , Jeff Layton Cc: linux-nfs@vger.kernel.org Date: Tue, 18 Jul 2023 16:38:08 +1000 Message-ID: <168966228868.11075.13775072041089806843.stgit@noble.brown> In-Reply-To: <168966227838.11075.2974227708495338626.stgit@noble.brown> References: <168966227838.11075.2974227708495338626.stgit@noble.brown> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org With an llist we don't need to take a lock to add a thread to the list, though we still need a lock to remove it. That will go in the next patch. Unlike double-linked lists, a thread cannot remove itself from the list. Only the first thread can be removed, and that can change asynchronously. So some care is needed. Firstly, we don't add ourselves to the list of there is more work to do - we just go ahead and do it. So we remain in the busy state. That already applied to xprts being ready, it now applies to all possible triggers. We DON'T keep the likely annotation on this test for "more work to do". It isn't particularly likely that there is no work to do, and there is definitely no need to optimise for that case. Secondly if we do find something needs to be done after adding ourselves to the list, we simply wake up the first thread on the list. If that was us, we have been removed and can continue. If it was some other thread, they will do the work that needs to be done. We can safely sleep until woken. With this a thread could call rqst_should_sleep() without actually proceeding to do work if told not to sleep. So that function mustn't clear SP_TASK_PENDING. The flag must stay set until some thread commits to not sleeping. We also remove the test on freezing() from rqst_should_sleep(). Instead we always try_to_freeze() before scheduling, which is needed as we now schedule() in a loop waiting to be removed from the idle queue. Signed-off-by: NeilBrown --- include/linux/sunrpc/svc.h | 14 +++++++----- net/sunrpc/svc.c | 11 +++++---- net/sunrpc/svc_xprt.c | 51 ++++++++++++++++++++++++++------------------ 3 files changed, 44 insertions(+), 32 deletions(-) diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index f5b69e6da0f8..5941b8a8e754 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -36,7 +36,7 @@ struct svc_pool { struct list_head sp_sockets; /* pending sockets */ unsigned int sp_nrthreads; /* # of threads in pool */ struct list_head sp_all_threads; /* all server threads */ - struct list_head sp_idle_threads; /* idle server threads */ + struct llist_head sp_idle_threads; /* idle server threads */ /* statistics on pool operation */ struct percpu_counter sp_messages_arrived; @@ -199,7 +199,7 @@ extern u32 svc_max_payload(const struct svc_rqst *rqstp); */ struct svc_rqst { struct list_head rq_all; /* all threads list */ - struct list_head rq_idle; /* On the idle list */ + struct llist_node rq_idle; /* On the idle list */ struct rcu_head rq_rcu_head; /* for RCU deferred kfree */ struct svc_xprt * rq_xprt; /* transport ptr */ @@ -286,22 +286,24 @@ enum { * svc_thread_set_busy - mark a thread as busy * @rqstp: the thread which is now busy * - * If rq_idle is "empty", the thread must be busy. + * By convention a thread is busy if rq_idle.next points to rq_idle. + * This ensures it is not on the idle list. */ static inline void svc_thread_set_busy(struct svc_rqst *rqstp) { - INIT_LIST_HEAD(&rqstp->rq_idle); + smp_store_release(&rqstp->rq_idle.next, &rqstp->rq_idle); } /** * svc_thread_busy - check if a thread as busy * @rqstp: the thread which might be busy * - * If rq_idle is "empty", the thread must be busy. + * By convention a thread is busy if rq_idle.next points to rq_idle. + * This ensures it is not on the idle list. */ static inline bool svc_thread_busy(struct svc_rqst *rqstp) { - return list_empty(&rqstp->rq_idle); + return smp_load_acquire(&rqstp->rq_idle.next) == &rqstp->rq_idle; } #define SVC_NET(rqst) (rqst->rq_xprt ? rqst->rq_xprt->xpt_net : rqst->rq_bc_net) diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index f6da390932cd..9287a08250b2 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -702,15 +702,16 @@ void svc_pool_wake_idle_thread(struct svc_serv *serv, struct svc_pool *pool) { struct svc_rqst *rqstp; + struct llist_node *ln; rcu_read_lock(); spin_lock_bh(&pool->sp_lock); - rqstp = list_first_entry_or_null(&pool->sp_idle_threads, - struct svc_rqst, rq_idle); - if (rqstp) - list_del_init(&rqstp->rq_idle); + ln = llist_del_first(&pool->sp_idle_threads); spin_unlock_bh(&pool->sp_lock); - if (rqstp) { + if (ln) { + rqstp = llist_entry(ln, struct svc_rqst, rq_idle); + svc_thread_set_busy(rqstp); + WRITE_ONCE(rqstp->rq_qtime, ktime_get()); wake_up_process(rqstp->rq_task); rcu_read_unlock(); diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index b82a66f68f17..eb8d345641b2 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -704,7 +704,7 @@ rqst_should_sleep(struct svc_rqst *rqstp) struct svc_pool *pool = rqstp->rq_pool; /* did someone call svc_wake_up? */ - if (test_and_clear_bit(SP_TASK_PENDING, &pool->sp_flags)) + if (test_bit(SP_TASK_PENDING, &pool->sp_flags)) return false; /* was a socket queued? */ @@ -715,10 +715,6 @@ rqst_should_sleep(struct svc_rqst *rqstp) if (svc_thread_should_stop(rqstp)) return false; - /* are we freezing? */ - if (freezing(current)) - return false; - #if defined(CONFIG_SUNRPC_BACKCHANNEL) if (svc_is_backchannel(rqstp)) { if (!list_empty(&rqstp->rq_server->sv_cb_list)) @@ -733,27 +729,40 @@ static void svc_wait_for_work(struct svc_rqst *rqstp) { struct svc_pool *pool = rqstp->rq_pool; - set_current_state(TASK_IDLE); - spin_lock_bh(&pool->sp_lock); - list_add(&rqstp->rq_idle, &pool->sp_idle_threads); - spin_unlock_bh(&pool->sp_lock); + if (rqst_should_sleep(rqstp)) { + set_current_state(TASK_IDLE); + llist_add(&rqstp->rq_idle, &pool->sp_idle_threads); + + if (unlikely(!rqst_should_sleep(rqstp))) + /* maybe there were no idle threads when some work + * became ready and so nothing was woken. We've just + * become idle so someone can to the work - maybe us. + * But we cannot reliably remove ourselves from the + * idle list - we can only remove the first task which + * might be us, and might not. + * So remove and wake it, then schedule(). If it was + * us, we won't sleep. If it is some other thread, they + * will do the work. + */ + svc_pool_wake_idle_thread(rqstp->rq_server, pool); - if (likely(rqst_should_sleep(rqstp))) - schedule(); - else + /* We mustn't continue while on the idle list, and we + * cannot remove outselves reliably. The only "work" + * we can do while on the idle list is to freeze. + * So loop until someone removes us + */ + while (!svc_thread_busy(rqstp)) { + try_to_freeze(); + schedule(); + set_current_state(TASK_IDLE); + } __set_current_state(TASK_RUNNING); - - /* We *must* be removed from the list before we can continue. - * If we were woken, this is already done - */ - if (!svc_thread_busy(rqstp)) { - spin_lock_bh(&pool->sp_lock); - list_del_init(&rqstp->rq_idle); - spin_unlock_bh(&pool->sp_lock); } try_to_freeze(); + clear_bit(SP_TASK_PENDING, &pool->sp_flags); + rqstp->rq_xprt = svc_xprt_dequeue(pool); if (rqstp->rq_xprt) { trace_svc_pool_awoken(rqstp); @@ -785,7 +794,7 @@ static void svc_wait_for_work(struct svc_rqst *rqstp) /* Normally we will wait up to 5 seconds for any required * cache information to be provided. */ - if (!list_empty(&pool->sp_idle_threads)) + if (pool->sp_idle_threads.first != NULL) rqstp->rq_chandle.thread_wait = 5*HZ; else rqstp->rq_chandle.thread_wait = 1*HZ; From patchwork Tue Jul 18 06:38:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: NeilBrown X-Patchwork-Id: 13316790 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 40F78EB64DA for ; Tue, 18 Jul 2023 06:40:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231449AbjGRGkX (ORCPT ); Tue, 18 Jul 2023 02:40:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45640 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231169AbjGRGkP (ORCPT ); Tue, 18 Jul 2023 02:40:15 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A95EB18B for ; Mon, 17 Jul 2023 23:40:10 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 58DD71FDC1; Tue, 18 Jul 2023 06:40:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1689662409; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BjUQYpH35umZqu/ECBB1/OwerONCDdBCFUC3u+CWa48=; b=jdRW0I8rNfkw1XauM2GVsfc1zyZ/gocR2DU/nVH2iAHv3K2z7KKpK2P02LWeCf4uyYHLo6 1JF4vMIGSr+7w7QH0O5MZbJ0Q4qQLh5dLCAy6rSEBhi5+YbWe1FeUNJIxQmpcjj5J7PkXo IZSs3aBATfE74E54N3WAZzuaDd8+dMg= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1689662409; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BjUQYpH35umZqu/ECBB1/OwerONCDdBCFUC3u+CWa48=; b=BEt/svcqSQUjo+blrgj4S3Yk4Rk6xrLeHAFxIC/sFi7jAFbGiHPXjQP/O3ay7ET400rced PkY/uupfxHis8WBg== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 14CC313494; Tue, 18 Jul 2023 06:40:07 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id CtMwLscztmTlDAAAMHmgww (envelope-from ); Tue, 18 Jul 2023 06:40:07 +0000 Subject: [PATCH 14/14] SUNRPC: only have one thread waking up at a time From: NeilBrown To: Chuck Lever , Jeff Layton Cc: linux-nfs@vger.kernel.org Date: Tue, 18 Jul 2023 16:38:08 +1000 Message-ID: <168966228868.11075.4709327436093326197.stgit@noble.brown> In-Reply-To: <168966227838.11075.2974227708495338626.stgit@noble.brown> References: <168966227838.11075.2974227708495338626.stgit@noble.brown> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org Currently if several items of work become available in quick succession, that number of threads (if available) will be woken. By the time some of them wake up another thread that was already cache-warm might have come along and completed the work. Anecdotal evidence suggests as many as 15% of wakes find nothing to do once they get to the point of looking. This patch changes svc_pool_wake_idle_thread() to wake the first thread on the queue but NOT remove it. Subsequent calls will wake the same thread. Once that thread starts it will dequeue itself and after dequeuing some work to do, it will wake the next thread if there is more work ready. This results in a more orderly increase in the number of busy threads. As a bonus, this allows us to reduce locking around the idle queue. svc_pool_wake_idle_thread() no longer needs to take a lock (beyond rcu_read_lock()) as it doesn't manipulate the queue, just looks at the first item. The thread itself can avoid locking by using the new llist_del_first_this() interface. This will safely remove the thread itself if it is the head. If it isn't the head, it will do nothing. If multiple threads call this concurrently only one will succeed. The others will do nothing, so no corruption can result. If a thread wakes up and find that it cannot dequeue itself that mean either - that it wasn't woken because it was the head of the queue. Maybe the freezer woke it. In that case it can go back to sleep (after trying to freeze of course). - some other thread found there was nothing to do very recently, and placed itself on the head of the queue in front of this thread. It must check again after placing itself there, so it can be deemed to be responsible for any pending work, and this thread can go back to sleep until woken. Signed-off-by: NeilBrown --- include/linux/llist.h | 2 ++ lib/llist.c | 27 +++++++++++++++++++++++++++ net/sunrpc/svc.c | 12 +++++------- net/sunrpc/svc_xprt.c | 39 +++++++++++++++++++++------------------ 4 files changed, 55 insertions(+), 25 deletions(-) diff --git a/include/linux/llist.h b/include/linux/llist.h index 85bda2d02d65..d8b1b73f3df0 100644 --- a/include/linux/llist.h +++ b/include/linux/llist.h @@ -248,6 +248,8 @@ static inline struct llist_node *__llist_del_all(struct llist_head *head) } extern struct llist_node *llist_del_first(struct llist_head *head); +extern struct llist_node *llist_del_first_this(struct llist_head *head, + struct llist_node *this); struct llist_node *llist_reverse_order(struct llist_node *head); diff --git a/lib/llist.c b/lib/llist.c index 6e668fa5a2c6..7e8a13a13586 100644 --- a/lib/llist.c +++ b/lib/llist.c @@ -65,6 +65,33 @@ struct llist_node *llist_del_first(struct llist_head *head) } EXPORT_SYMBOL_GPL(llist_del_first); +/** + * llist_del_first_this - delete given entry of lock-less list if it is first + * @head: the head for your lock-less list + * @this: a list entry. + * + * If head of the list is given entry, delete and return it, else + * return %NULL. + * + * Providing the caller has exclusive access to @this, multiple callers can + * safely call this concurrently with multiple llist_add() callers. + */ +struct llist_node *llist_del_first_this(struct llist_head *head, + struct llist_node *this) +{ + struct llist_node *entry, *next; + + entry = smp_load_acquire(&head->first); + do { + if (entry != this) + return NULL; + next = READ_ONCE(entry->next); + } while (!try_cmpxchg(&head->first, &entry, next)); + + return entry; +} +EXPORT_SYMBOL_GPL(llist_del_first_this); + /** * llist_reverse_order - reverse order of a llist chain * @head: first item of the list to be reversed diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 9287a08250b2..43f29f7380db 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -705,17 +705,15 @@ void svc_pool_wake_idle_thread(struct svc_serv *serv, struct llist_node *ln; rcu_read_lock(); - spin_lock_bh(&pool->sp_lock); - ln = llist_del_first(&pool->sp_idle_threads); - spin_unlock_bh(&pool->sp_lock); + ln = READ_ONCE(pool->sp_idle_threads.first); if (ln) { rqstp = llist_entry(ln, struct svc_rqst, rq_idle); - svc_thread_set_busy(rqstp); - WRITE_ONCE(rqstp->rq_qtime, ktime_get()); - wake_up_process(rqstp->rq_task); + if (!task_is_running(rqstp->rq_task)) { + wake_up_process(rqstp->rq_task); + percpu_counter_inc(&pool->sp_threads_woken); + } rcu_read_unlock(); - percpu_counter_inc(&pool->sp_threads_woken); return; } rcu_read_unlock(); diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index eb8d345641b2..fa945cbf174a 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -732,31 +732,29 @@ static void svc_wait_for_work(struct svc_rqst *rqstp) if (rqst_should_sleep(rqstp)) { set_current_state(TASK_IDLE); llist_add(&rqstp->rq_idle, &pool->sp_idle_threads); + /* maybe there were no idle threads when some work + * became ready and so nothing was woken. We've just + * become idle so someone can do the work - maybe us. + * So check again for work to do. + */ + if (likely(rqst_should_sleep(rqstp))) { + try_to_freeze(); + schedule(); + } - if (unlikely(!rqst_should_sleep(rqstp))) - /* maybe there were no idle threads when some work - * became ready and so nothing was woken. We've just - * become idle so someone can to the work - maybe us. - * But we cannot reliably remove ourselves from the - * idle list - we can only remove the first task which - * might be us, and might not. - * So remove and wake it, then schedule(). If it was - * us, we won't sleep. If it is some other thread, they - * will do the work. + while (llist_del_first_this(&pool->sp_idle_threads, + &rqstp->rq_idle) == NULL) { + /* Cannot remove myself, some other thread + * must have queued themselves after finding + * no work to do, so they have taken reponsibility + * for any outstanding work. */ - svc_pool_wake_idle_thread(rqstp->rq_server, pool); - - /* We mustn't continue while on the idle list, and we - * cannot remove outselves reliably. The only "work" - * we can do while on the idle list is to freeze. - * So loop until someone removes us - */ - while (!svc_thread_busy(rqstp)) { try_to_freeze(); schedule(); set_current_state(TASK_IDLE); } __set_current_state(TASK_RUNNING); + svc_thread_set_busy(rqstp); } try_to_freeze(); @@ -798,6 +796,11 @@ static void svc_wait_for_work(struct svc_rqst *rqstp) rqstp->rq_chandle.thread_wait = 5*HZ; else rqstp->rq_chandle.thread_wait = 1*HZ; + + if (!rqst_should_sleep(rqstp)) + /* More work pending after I dequeued some, + * wake another worker */ + svc_pool_wake_idle_thread(rqstp->rq_server, pool); } static void svc_add_new_temp_xprt(struct svc_serv *serv, struct svc_xprt *newxpt)