From: Mike Snitzer <snitzer@kernel.org>
To: linux-nfs@vger.kernel.org
Cc: Anna Schumaker <anna@kernel.org>,
Trond Myklebust <trondmy@hammerspace.com>,
Chuck Lever <chuck.lever@oracle.com>,
Jeff Layton <jlayton@kernel.org>, NeilBrown <neilb@suse.de>
Subject: [for-6.13 PATCH 19/19] nfs: probe for LOCALIO when v3 client reconnects to server
Date: Fri, 8 Nov 2024 18:40:02 -0500 [thread overview]
Message-ID: <20241108234002.16392-20-snitzer@kernel.org> (raw)
In-Reply-To: <20241108234002.16392-1-snitzer@kernel.org>
Re-enabling NFSv3 LOCALIO is made more complex (than NFSv4) because v3
is stateless. As such, the hueristic used to identify a LOCALIO probe
point is more adhoc by nature: if/when NFSv3 client IO begins to
complete again in terms of normal RPC-based NFSv3 server IO, attempt
nfs_local_probe_async().
Care is taken to throttle the frequency of nfs_local_probe_async(),
otherwise there could be a flood of repeat calls to
nfs_local_probe_async().
Signed-off-by: Mike Snitzer <snitzer@kernel.org>
---
fs/nfs/internal.h | 5 +++++
fs/nfs/localio.c | 11 +++++++++++
fs/nfs/nfs3proc.c | 34 +++++++++++++++++++++++++++++++---
fs/nfs_common/nfslocalio.c | 4 ++++
include/linux/nfs_fs_sb.h | 1 +
include/linux/nfslocalio.h | 4 +++-
6 files changed, 55 insertions(+), 4 deletions(-)
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index efd42efd9405..fb1ab7cee6b9 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -470,6 +470,7 @@ extern int nfs_local_commit(struct nfsd_file *,
struct nfs_commit_data *,
const struct rpc_call_ops *, int);
extern bool nfs_server_is_local(const struct nfs_client *clp);
+extern bool nfs_server_was_local(const struct nfs_client *clp);
#else /* CONFIG_NFS_LOCALIO */
static inline void nfs_local_disable(struct nfs_client *clp) {}
@@ -499,6 +500,10 @@ static inline bool nfs_server_is_local(const struct nfs_client *clp)
{
return false;
}
+static inline bool nfs_server_was_local(const struct nfs_client *clp)
+{
+ return false;
+}
#endif /* CONFIG_NFS_LOCALIO */
/* super.c */
diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c
index 710e537b3402..1559dc2f1850 100644
--- a/fs/nfs/localio.c
+++ b/fs/nfs/localio.c
@@ -64,6 +64,17 @@ bool nfs_server_is_local(const struct nfs_client *clp)
}
EXPORT_SYMBOL_GPL(nfs_server_is_local);
+static inline bool nfs_client_was_local(const struct nfs_client *clp)
+{
+ return !!test_bit(NFS_CS_LOCAL_IO_CAPABLE, &clp->cl_flags);
+}
+
+bool nfs_server_was_local(const struct nfs_client *clp)
+{
+ return nfs_client_was_local(clp) && localio_enabled;
+}
+EXPORT_SYMBOL_GPL(nfs_server_was_local);
+
/*
* UUID_IS_LOCAL XDR functions
*/
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 1566163c6d85..4d2018760e9b 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -844,6 +844,29 @@ nfs3_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
return status;
}
+static void nfs3_local_probe(struct nfs_server *server)
+{
+#if IS_ENABLED(CONFIG_NFS_LOCALIO)
+ struct nfs_client *clp = server->nfs_client;
+ nfs_uuid_t *nfs_uuid = &clp->cl_uuid;
+
+ if (likely(!nfs_server_was_local(clp)))
+ return;
+ /*
+ * Try re-enabling LOCALIO if it was previously enabled, but
+ * was disabled due to server restart, and IO has successfully
+ * completed in terms of normal RPC.
+ */
+ mutex_lock(&nfs_uuid->local_probe_mutex);
+ /* Arbitrary throttle to reduce nfs_local_probe_async() frequency */
+ if ((nfs_uuid->local_probe_count++ & 255) == 0) {
+ if (unlikely(!nfs_server_is_local(clp) && nfs_server_was_local(clp)))
+ nfs_local_probe_async(clp);
+ }
+ mutex_unlock(&nfs_uuid->local_probe_mutex);
+#endif
+}
+
static int nfs3_read_done(struct rpc_task *task, struct nfs_pgio_header *hdr)
{
struct inode *inode = hdr->inode;
@@ -855,8 +878,11 @@ static int nfs3_read_done(struct rpc_task *task, struct nfs_pgio_header *hdr)
if (nfs3_async_handle_jukebox(task, inode))
return -EAGAIN;
- if (task->tk_status >= 0 && !server->read_hdrsize)
- cmpxchg(&server->read_hdrsize, 0, hdr->res.replen);
+ if (task->tk_status >= 0) {
+ if (!server->read_hdrsize)
+ cmpxchg(&server->read_hdrsize, 0, hdr->res.replen);
+ nfs3_local_probe(server);
+ }
nfs_invalidate_atime(inode);
nfs_refresh_inode(inode, &hdr->fattr);
@@ -886,8 +912,10 @@ static int nfs3_write_done(struct rpc_task *task, struct nfs_pgio_header *hdr)
if (nfs3_async_handle_jukebox(task, inode))
return -EAGAIN;
- if (task->tk_status >= 0)
+ if (task->tk_status >= 0) {
nfs_writeback_update_inode(hdr);
+ nfs3_local_probe(NFS_SERVER(inode));
+ }
return 0;
}
diff --git a/fs/nfs_common/nfslocalio.c b/fs/nfs_common/nfslocalio.c
index fb376d38ac9a..852ba8fd73f3 100644
--- a/fs/nfs_common/nfslocalio.c
+++ b/fs/nfs_common/nfslocalio.c
@@ -43,6 +43,8 @@ void nfs_uuid_init(nfs_uuid_t *nfs_uuid)
INIT_LIST_HEAD(&nfs_uuid->list);
INIT_LIST_HEAD(&nfs_uuid->files);
spin_lock_init(&nfs_uuid->lock);
+ mutex_init(&nfs_uuid->local_probe_mutex);
+ nfs_uuid->local_probe_count = 0;
}
EXPORT_SYMBOL_GPL(nfs_uuid_init);
@@ -143,6 +145,8 @@ void nfs_localio_enable_client(struct nfs_client *clp)
spin_lock(&nfs_uuid->lock);
set_bit(NFS_CS_LOCAL_IO, &clp->cl_flags);
+ /* Also set hint that client and server are LOCALIO capable */
+ set_bit(NFS_CS_LOCAL_IO_CAPABLE, &clp->cl_flags);
trace_nfs_localio_enable_client(clp);
spin_unlock(&nfs_uuid->lock);
}
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 63d7e0f478d8..45906c402c98 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -51,6 +51,7 @@ struct nfs_client {
#define NFS_CS_REUSEPORT 8 /* - reuse src port on reconnect */
#define NFS_CS_PNFS 9 /* - Server used for pnfs */
#define NFS_CS_LOCAL_IO 10 /* - client is local */
+#define NFS_CS_LOCAL_IO_CAPABLE 11 /* - client was previously local */
struct sockaddr_storage cl_addr; /* server identifier */
size_t cl_addrlen;
char * cl_hostname; /* hostname of server */
diff --git a/include/linux/nfslocalio.h b/include/linux/nfslocalio.h
index c68a529230c1..3dfef0bb18fe 100644
--- a/include/linux/nfslocalio.h
+++ b/include/linux/nfslocalio.h
@@ -27,7 +27,9 @@ struct nfs_file_localio;
*/
typedef struct {
uuid_t uuid;
- /* sadly this struct is just over a cacheline, avoid bouncing */
+ struct mutex local_probe_mutex;
+ unsigned local_probe_count;
+ /* sadly this struct is over a cacheline, avoid bouncing */
spinlock_t ____cacheline_aligned lock;
struct list_head list;
spinlock_t *list_lock; /* nn->local_clients_lock */
--
2.44.0
next prev parent reply other threads:[~2024-11-08 23:40 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-08 23:39 [for-6.13 PATCH 00/19] nfs/nfsd: fixes and improvements for LOCALIO Mike Snitzer
2024-11-08 23:39 ` [for-6.13 PATCH 01/19] nfs/localio: must clear res.replen in nfs_local_read_done Mike Snitzer
2024-11-11 0:36 ` NeilBrown
2024-11-08 23:39 ` [for-6.13 PATCH 02/19] nfs_common: must not hold RCU while calling nfsd_file_put_local Mike Snitzer
2024-11-11 1:01 ` NeilBrown
2024-11-13 14:58 ` Jeff Layton
2024-11-13 16:51 ` Mike Snitzer
2024-11-08 23:39 ` [for-6.13 PATCH 03/19] nfs/localio: remove redundant suid/sgid handling Mike Snitzer
2024-11-11 1:09 ` NeilBrown
2024-11-08 23:39 ` [for-6.13 PATCH 04/19] nfs/localio: eliminate unnecessary kref in nfs_local_fsync_ctx Mike Snitzer
2024-11-11 1:15 ` NeilBrown
2024-11-08 23:39 ` [for-6.13 PATCH 05/19] nfs/localio: remove extra indirect nfs_to call to check {read,write}_iter Mike Snitzer
2024-11-11 1:20 ` NeilBrown
2024-11-11 15:09 ` Mike Snitzer
2024-11-08 23:39 ` [for-6.13 PATCH 06/19] nfs/localio: eliminate need for nfs_local_fsync_work forward declaration Mike Snitzer
2024-11-11 1:21 ` NeilBrown
2024-11-08 23:39 ` [for-6.13 PATCH 07/19] nfs/localio: add direct IO enablement with sync and async IO support Mike Snitzer
2024-11-11 1:31 ` NeilBrown
2024-11-12 14:31 ` Chuck Lever
2024-11-08 23:39 ` [for-6.13 PATCH 08/19] nfsd: add nfsd_file_{get,put} to 'nfs_to' nfsd_localio_operations Mike Snitzer
2024-11-08 23:39 ` [for-6.13 PATCH 09/19] nfs_common: rename functions that invalidate LOCALIO nfs_clients Mike Snitzer
2024-11-11 1:32 ` NeilBrown
2024-11-08 23:39 ` [for-6.13 PATCH 10/19] nfs_common: move localio_lock to new lock member of nfs_uuid_t Mike Snitzer
2024-11-11 1:55 ` NeilBrown
2024-11-11 15:33 ` Mike Snitzer
2024-11-11 20:35 ` NeilBrown
2024-11-11 22:27 ` Mike Snitzer
2024-11-11 23:23 ` NeilBrown
2024-11-12 0:16 ` Mike Snitzer
2024-11-12 0:49 ` NeilBrown
2024-11-12 14:36 ` Chuck Lever
2024-11-12 23:13 ` NeilBrown
2024-11-13 0:07 ` Chuck Lever III
2024-11-13 0:32 ` NeilBrown
2024-11-08 23:39 ` [for-6.13 PATCH 11/19] nfs: cache all open LOCALIO nfsd_file(s) in client Mike Snitzer
2024-11-08 23:39 ` [for-6.13 PATCH 12/19] nfsd: update percpu_ref to manage references on nfsd_net Mike Snitzer
2024-11-08 23:39 ` [for-6.13 PATCH 13/19] nfsd: rename nfsd_serv_ prefixed methods and variables with nfsd_net_ Mike Snitzer
2024-11-08 23:39 ` [for-6.13 PATCH 14/19] nfsd: nfsd_file_acquire_local no longer returns GC'd nfsd_file Mike Snitzer
2024-11-08 23:39 ` [for-6.13 PATCH 15/19] nfs_common: rename nfslocalio nfs_uuid_lock to nfs_uuids_lock Mike Snitzer
2024-11-08 23:39 ` [for-6.13 PATCH 16/19] nfs_common: track all open nfsd_files per LOCALIO nfs_client Mike Snitzer
2024-11-08 23:40 ` [for-6.13 PATCH 17/19] nfs_common: add nfs_localio trace events Mike Snitzer
2024-11-08 23:40 ` [for-6.13 PATCH 18/19] nfs: probe for LOCALIO when v4 client reconnects to server Mike Snitzer
2024-11-08 23:40 ` Mike Snitzer [this message]
2024-11-11 3:06 ` [for-6.13 PATCH 19/19] nfs: probe for LOCALIO when v3 " NeilBrown
2024-11-10 15:49 ` [for-6.13 PATCH 00/19] nfs/nfsd: fixes and improvements for LOCALIO Chuck Lever III
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241108234002.16392-20-snitzer@kernel.org \
--to=snitzer@kernel.org \
--cc=anna@kernel.org \
--cc=chuck.lever@oracle.com \
--cc=jlayton@kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=neilb@suse.de \
--cc=trondmy@hammerspace.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.