2021-08-11 17:16:44

by Thiago Rafael Becker

[permalink] [raw]
Subject: [RFC PATCH] nfs: add rasize mount option to control read ahead

Limiting nfs to 128kB of read ahead is performing poorly in high volume
mounts. Add the rasize option to set the read ahead to a more suitable
value.

Signed-off-by: Thiago Rafael Becker <[email protected]>
---
fs/nfs/client.c | 3 +++
fs/nfs/fs_context.c | 11 ++++++++++-
fs/nfs/internal.h | 1 +
fs/nfs/nfs4client.c | 2 ++
fs/nfs/super.c | 2 ++
include/linux/nfs_fs_sb.h | 1 +
include/uapi/linux/nfs4_mount.h | 1 +
include/uapi/linux/nfs_mount.h | 1 +
8 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 330f65727c45..042677cd82f5 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -713,6 +713,8 @@ static int nfs_init_server(struct nfs_server *server,
server->rsize = nfs_block_size(ctx->rsize, NULL);
if (ctx->wsize)
server->wsize = nfs_block_size(ctx->wsize, NULL);
+ if (ctx->rasize)
+ server->rasize = ctx->rasize;

server->acregmin = ctx->acregmin * HZ;
server->acregmax = ctx->acregmax * HZ;
@@ -869,6 +871,7 @@ void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *sour
{
target->flags = source->flags;
target->rsize = source->rsize;
+ target->rasize = source->rasize;
target->wsize = source->wsize;
target->acregmin = source->acregmin;
target->acregmax = source->acregmax;
diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c
index d95c9a39bc70..8dcf14864d22 100644
--- a/fs/nfs/fs_context.c
+++ b/fs/nfs/fs_context.c
@@ -65,6 +65,7 @@ enum nfs_param {
Opt_proto,
Opt_rdirplus,
Opt_rdma,
+ Opt_rasize,
Opt_resvport,
Opt_retrans,
Opt_retry,
@@ -162,6 +163,7 @@ static const struct fs_parameter_spec nfs_fs_parameters[] = {
fsparam_u32 ("port", Opt_port),
fsparam_flag_no("posix", Opt_posix),
fsparam_string("proto", Opt_proto),
+ fsparam_u32 ("rasize", Opt_rasize),
fsparam_flag_no("rdirplus", Opt_rdirplus),
fsparam_flag ("rdma", Opt_rdma),
fsparam_flag_no("resvport", Opt_resvport),
@@ -476,7 +478,6 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
int ret, opt;

dfprintk(MOUNT, "NFS: parsing nfs mount option '%s'\n", param->key);
-
opt = fs_parse(fc, nfs_fs_parameters, param, &result);
if (opt < 0)
return ctx->sloppy ? 1 : opt;
@@ -824,6 +825,9 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
goto out_invalid_value;
}
break;
+ case Opt_rasize:
+ ctx->rasize = result.uint_32;
+ break;

/*
* Special options
@@ -1012,6 +1016,7 @@ static int nfs23_parse_monolithic(struct fs_context *fc,
ctx->flags |= extra_flags;
ctx->rsize = data->rsize;
ctx->wsize = data->wsize;
+ ctx->rasize = data->rasize;
ctx->timeo = data->timeo;
ctx->retrans = data->retrans;
ctx->acregmin = data->acregmin;
@@ -1145,6 +1150,7 @@ struct compat_nfs4_mount_data_v1 {
compat_int_t proto;
compat_int_t auth_flavourlen;
compat_uptr_t auth_flavours;
+ compat_int_t rasize;
};

static void nfs4_compat_mount_data_conv(struct nfs4_mount_data *data)
@@ -1169,6 +1175,7 @@ static void nfs4_compat_mount_data_conv(struct nfs4_mount_data *data)
data->timeo = compat->timeo;
data->wsize = compat->wsize;
data->rsize = compat->rsize;
+ data->rasize = compat->rasize;
data->flags = compat->flags;
data->version = compat->version;
}
@@ -1247,6 +1254,7 @@ static int nfs4_parse_monolithic(struct fs_context *fc,
ctx->flags = data->flags & NFS4_MOUNT_FLAGMASK;
ctx->rsize = data->rsize;
ctx->wsize = data->wsize;
+ ctx->rasize = data->rasize;
ctx->timeo = data->timeo;
ctx->retrans = data->retrans;
ctx->acregmin = data->acregmin;
@@ -1508,6 +1516,7 @@ static int nfs_init_fs_context(struct fs_context *fc)
ctx->flags = nfss->flags;
ctx->rsize = nfss->rsize;
ctx->wsize = nfss->wsize;
+ ctx->rasize = nfss->rasize;
ctx->retrans = nfss->client->cl_timeout->to_retries;
ctx->selected_flavor = nfss->client->cl_auth->au_flavor;
ctx->acregmin = nfss->acregmin / HZ;
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index a36af04188c2..975f49a03de6 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -97,6 +97,7 @@ struct nfs_fs_context {
unsigned short protofamily;
unsigned short mountfamily;
bool has_sec_mnt_opts;
+ unsigned int rasize;

struct {
union {
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 28431acd1230..f3cb9e9ff656 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -1130,6 +1130,8 @@ static int nfs4_init_server(struct nfs_server *server, struct fs_context *fc)
server->rsize = nfs_block_size(ctx->rsize, NULL);
if (ctx->wsize)
server->wsize = nfs_block_size(ctx->wsize, NULL);
+ if (ctx->rasize)
+ server->rasize = ctx->rasize;

server->acregmin = ctx->acregmin * HZ;
server->acregmax = ctx->acregmax * HZ;
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index fe58525cfed4..df5d27931ee6 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -456,6 +456,7 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
seq_printf(m, ",wsize=%u", nfss->wsize);
if (nfss->bsize != 0)
seq_printf(m, ",bsize=%u", nfss->bsize);
+ seq_printf(m, ",rasize=%lu", nfss->super->s_bdi->ra_pages * PAGE_SIZE);
seq_printf(m, ",namlen=%u", nfss->namelen);
if (nfss->acregmin != NFS_DEF_ACREGMIN*HZ || showdefaults)
seq_printf(m, ",acregmin=%u", nfss->acregmin/HZ);
@@ -1281,6 +1282,7 @@ int nfs_get_tree_common(struct fs_context *fc)
if (error)
goto error_splat_super;
s->s_bdi->io_pages = server->rpages;
+ s->s_bdi->ra_pages = server->rasize / PAGE_SIZE;
server->super = s;
}

diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index d71a0e90faeb..fe7469ce81e1 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -162,6 +162,7 @@ struct nfs_server {
unsigned int rpages; /* read size (in pages) */
unsigned int wsize; /* write size */
unsigned int wpages; /* write size (in pages) */
+ unsigned int rasize; /* read ahead size */
unsigned int wtmult; /* server disk block size */
unsigned int dtsize; /* readdir size */
unsigned short port; /* "port=" setting */
diff --git a/include/uapi/linux/nfs4_mount.h b/include/uapi/linux/nfs4_mount.h
index d20bb869bb99..f9799fdccf06 100644
--- a/include/uapi/linux/nfs4_mount.h
+++ b/include/uapi/linux/nfs4_mount.h
@@ -54,6 +54,7 @@ struct nfs4_mount_data {
/* Pseudo-flavours to use for authentication. See RFC2623 */
int auth_flavourlen; /* 1 */
int __user *auth_flavours; /* 1 */
+ int rasize; /* 1 */
};

/* bits in the flags field */
diff --git a/include/uapi/linux/nfs_mount.h b/include/uapi/linux/nfs_mount.h
index e3bcfc6aa3b0..0a5f40e986cf 100644
--- a/include/uapi/linux/nfs_mount.h
+++ b/include/uapi/linux/nfs_mount.h
@@ -44,6 +44,7 @@ struct nfs_mount_data {
struct nfs3_fh root; /* 4 */
int pseudoflavor; /* 5 */
char context[NFS_MAX_CONTEXT_LEN + 1]; /* 6 */
+ int rasize; /* 1 */
};

/* bits in the flags field visible to user space */
--
2.31.1


2021-08-11 18:39:41

by Trond Myklebust

[permalink] [raw]
Subject: Re: [RFC PATCH] nfs: add rasize mount option to control read ahead

On Wed, 2021-08-11 at 14:14 -0300, Thiago Rafael Becker wrote:
> Limiting nfs to 128kB of read ahead is performing poorly in high
> volume
> mounts. Add the rasize option to set the read ahead to a more
> suitable
> value.
>

NACK. This is another mount option.

--
Trond Myklebust
Linux NFS client maintainer, Hammerspace
[email protected]