* [PATCH v3 0/1] fuse: dynamically configure max pages limit through sysctl
@ 2024-09-23 17:13 Joanne Koong
2024-09-23 17:13 ` [PATCH v3 1/1] fuse: enable dynamic configuration of fuse max pages limit (FUSE_MAX_MAX_PAGES) Joanne Koong
0 siblings, 1 reply; 4+ messages in thread
From: Joanne Koong @ 2024-09-23 17:13 UTC (permalink / raw)
To: miklos, linux-fsdevel
Cc: josef, bernd.schubert, sweettea-kernel, jefflexu, kernel-team
The motivation behind this patch is to increase the max buffer size allowed
for a write request. Currently, this is gated by FUSE_MAX_MAX_PAGES which is
statically set to 256 pages. As such, this limits the buffer size on a write
request to 1 MiB on a 4k-page system. Perf improvements have been seen [1] with
larger write buffer size limits.
This patch adds a sysctl for allowing system administrators to dynamically
configure the max number of pages that can be used for servicing requests in
FUSE. The default value is the original limit (256 pages).
[1] https://lore.kernel.org/linux-fsdevel/20240124070512.52207-1-jefflexu@linux.alibaba.com/T/#u
v2 -> v3:
* Gate sysctl.o behind CONFIG_SYSCTL in Makefile (kernel test robot)
* Reword commit message
v2:
https://lore.kernel.org/linux-fsdevel/20240702014627.4068146-1-joannelkoong@gmail.com/
https://lore.kernel.org/linux-fsdevel/20240905174541.392785-1-joannelkoong@gmail.com/
v1 -> v2:
* Rename fuse_max_max_pages to fuse_max_pages_limit internally
* Rename /proc/sys/fs/fuse/fuse_max_max_pages to
/proc/sys/fs/fuse/max_pages_limit
* Restrict fuse max_pages_limit sysctl values to between 1 and 65535
(inclusive)
v1: https://lore.kernel.org/linux-fsdevel/20240628001355.243805-1-joannelkoong@gmail.com/
Joanne Koong (1):
fuse: Enable dynamic configuration of fuse max pages limit
(FUSE_MAX_MAX_PAGES)
Documentation/admin-guide/sysctl/fs.rst | 10 +++++++
fs/fuse/Makefile | 1 +
fs/fuse/fuse_i.h | 14 +++++++--
fs/fuse/inode.c | 11 ++++++-
fs/fuse/ioctl.c | 4 ++-
fs/fuse/sysctl.c | 40 +++++++++++++++++++++++++
6 files changed, 75 insertions(+), 5 deletions(-)
create mode 100644 fs/fuse/sysctl.c
--
2.43.5
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v3 1/1] fuse: enable dynamic configuration of fuse max pages limit (FUSE_MAX_MAX_PAGES)
2024-09-23 17:13 [PATCH v3 0/1] fuse: dynamically configure max pages limit through sysctl Joanne Koong
@ 2024-09-23 17:13 ` Joanne Koong
2024-09-24 9:43 ` Miklos Szeredi
0 siblings, 1 reply; 4+ messages in thread
From: Joanne Koong @ 2024-09-23 17:13 UTC (permalink / raw)
To: miklos, linux-fsdevel
Cc: josef, bernd.schubert, sweettea-kernel, jefflexu, kernel-team
Introduce the capability to dynamically configure the max pages limit
(FUSE_MAX_MAX_PAGES) through a sysctl. This allows system administrators
to dynamically set the maximum number of pages that can be used for
servicing requests in fuse.
Previously, this is gated by FUSE_MAX_MAX_PAGES which is statically set
to 256 pages. One result of this is that the buffer size for a write
request is limited to 1 MiB on a 4k-page system.
The default value for this sysctl is the original limit (256 pages).
$ sysctl -a | grep max_pages_limit
fs.fuse.max_pages_limit = 256
$ sysctl -n fs.fuse.max_pages_limit
256
$ echo 1024 | sudo tee /proc/sys/fs/fuse/max_pages_limit
1024
$ sysctl -n fs.fuse.max_pages_limit
1024
$ echo 65536 | sudo tee /proc/sys/fs/fuse/max_pages_limit
tee: /proc/sys/fs/fuse/max_pages_limit: Invalid argument
$ echo 0 | sudo tee /proc/sys/fs/fuse/max_pages_limit
tee: /proc/sys/fs/fuse/max_pages_limit: Invalid argument
$ echo 65535 | sudo tee /proc/sys/fs/fuse/max_pages_limit
65535
$ sysctl -n fs.fuse.max_pages_limit
65535
Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
---
Documentation/admin-guide/sysctl/fs.rst | 10 +++++++
fs/fuse/Makefile | 1 +
fs/fuse/fuse_i.h | 14 +++++++--
fs/fuse/inode.c | 11 ++++++-
fs/fuse/ioctl.c | 4 ++-
fs/fuse/sysctl.c | 40 +++++++++++++++++++++++++
6 files changed, 75 insertions(+), 5 deletions(-)
create mode 100644 fs/fuse/sysctl.c
diff --git a/Documentation/admin-guide/sysctl/fs.rst b/Documentation/admin-guide/sysctl/fs.rst
index 47499a1742bd..fa25d7e718b3 100644
--- a/Documentation/admin-guide/sysctl/fs.rst
+++ b/Documentation/admin-guide/sysctl/fs.rst
@@ -332,3 +332,13 @@ Each "watch" costs roughly 90 bytes on a 32-bit kernel, and roughly 160 bytes
on a 64-bit one.
The current default value for ``max_user_watches`` is 4% of the
available low memory, divided by the "watch" cost in bytes.
+
+5. /proc/sys/fs/fuse - Configuration options for FUSE filesystems
+=====================================================================
+
+This directory contains the following configuration options for FUSE
+filesystems:
+
+``/proc/sys/fs/fuse/max_pages_limit`` is a read/write file for
+setting/getting the maximum number of pages that can be used for servicing
+requests in FUSE.
diff --git a/fs/fuse/Makefile b/fs/fuse/Makefile
index ce0ff7a9007b..2c372180d631 100644
--- a/fs/fuse/Makefile
+++ b/fs/fuse/Makefile
@@ -14,5 +14,6 @@ fuse-y := dev.o dir.o file.o inode.o control.o xattr.o acl.o readdir.o ioctl.o
fuse-y += iomode.o
fuse-$(CONFIG_FUSE_DAX) += dax.o
fuse-$(CONFIG_FUSE_PASSTHROUGH) += passthrough.o
+fuse-$(CONFIG_SYSCTL) += sysctl.o
virtiofs-y := virtio_fs.o
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index e6cc3d552b13..7ff00bae4a84 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -35,9 +35,6 @@
/** Default max number of pages that can be used in a single read request */
#define FUSE_DEFAULT_MAX_PAGES_PER_REQ 32
-/** Maximum of max_pages received in init_out */
-#define FUSE_MAX_MAX_PAGES 256
-
/** Bias for fi->writectr, meaning new writepages must not be sent */
#define FUSE_NOWRITE INT_MIN
@@ -47,6 +44,9 @@
/** Number of dentries for each connection in the control filesystem */
#define FUSE_CTL_NUM_DENTRIES 5
+/** Maximum of max_pages received in init_out */
+extern unsigned int fuse_max_pages_limit;
+
/** List of active connections */
extern struct list_head fuse_conn_list;
@@ -1480,4 +1480,12 @@ ssize_t fuse_passthrough_splice_write(struct pipe_inode_info *pipe,
size_t len, unsigned int flags);
ssize_t fuse_passthrough_mmap(struct file *file, struct vm_area_struct *vma);
+#ifdef CONFIG_SYSCTL
+extern int fuse_sysctl_register(void);
+extern void fuse_sysctl_unregister(void);
+#else
+#define fuse_sysctl_register() (0)
+#define fuse_sysctl_unregister() do { } while (0)
+#endif /* CONFIG_SYSCTL */
+
#endif /* _FS_FUSE_I_H */
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index fd3321e29a3e..30a95cd9f497 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -35,6 +35,8 @@ DEFINE_MUTEX(fuse_mutex);
static int set_global_limit(const char *val, const struct kernel_param *kp);
+unsigned int fuse_max_pages_limit = 256;
+
unsigned max_user_bgreq;
module_param_call(max_user_bgreq, set_global_limit, param_get_uint,
&max_user_bgreq, 0644);
@@ -944,7 +946,7 @@ void fuse_conn_init(struct fuse_conn *fc, struct fuse_mount *fm,
fc->pid_ns = get_pid_ns(task_active_pid_ns(current));
fc->user_ns = get_user_ns(user_ns);
fc->max_pages = FUSE_DEFAULT_MAX_PAGES_PER_REQ;
- fc->max_pages_limit = FUSE_MAX_MAX_PAGES;
+ fc->max_pages_limit = fuse_max_pages_limit;
if (IS_ENABLED(CONFIG_FUSE_PASSTHROUGH))
fuse_backing_files_init(fc);
@@ -2063,8 +2065,14 @@ static int __init fuse_fs_init(void)
if (err)
goto out3;
+ err = fuse_sysctl_register();
+ if (err)
+ goto out4;
+
return 0;
+ out4:
+ unregister_filesystem(&fuse_fs_type);
out3:
unregister_fuseblk();
out2:
@@ -2077,6 +2085,7 @@ static void fuse_fs_cleanup(void)
{
unregister_filesystem(&fuse_fs_type);
unregister_fuseblk();
+ fuse_sysctl_unregister();
/*
* Make sure all delayed rcu free inodes are flushed before we
diff --git a/fs/fuse/ioctl.c b/fs/fuse/ioctl.c
index 572ce8a82ceb..a6c8ee551635 100644
--- a/fs/fuse/ioctl.c
+++ b/fs/fuse/ioctl.c
@@ -10,6 +10,8 @@
#include <linux/fileattr.h>
#include <linux/fsverity.h>
+#define FUSE_VERITY_ENABLE_ARG_MAX_PAGES 256
+
static ssize_t fuse_send_ioctl(struct fuse_mount *fm, struct fuse_args *args,
struct fuse_ioctl_out *outarg)
{
@@ -140,7 +142,7 @@ static int fuse_setup_enable_verity(unsigned long arg, struct iovec *iov,
{
struct fsverity_enable_arg enable;
struct fsverity_enable_arg __user *uarg = (void __user *)arg;
- const __u32 max_buffer_len = FUSE_MAX_MAX_PAGES * PAGE_SIZE;
+ const __u32 max_buffer_len = FUSE_VERITY_ENABLE_ARG_MAX_PAGES * PAGE_SIZE;
if (copy_from_user(&enable, uarg, sizeof(enable)))
return -EFAULT;
diff --git a/fs/fuse/sysctl.c b/fs/fuse/sysctl.c
new file mode 100644
index 000000000000..b272bb333005
--- /dev/null
+++ b/fs/fuse/sysctl.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/fs/fuse/fuse_sysctl.c
+ *
+ * Sysctl interface to fuse parameters
+ */
+#include <linux/sysctl.h>
+
+#include "fuse_i.h"
+
+static struct ctl_table_header *fuse_table_header;
+
+/* Bound by fuse_init_out max_pages, which is a u16 */
+static unsigned int sysctl_fuse_max_pages_limit = 65535;
+
+static struct ctl_table fuse_sysctl_table[] = {
+ {
+ .procname = "max_pages_limit",
+ .data = &fuse_max_pages_limit,
+ .maxlen = sizeof(fuse_max_pages_limit),
+ .mode = 0644,
+ .proc_handler = proc_douintvec_minmax,
+ .extra1 = SYSCTL_ONE,
+ .extra2 = &sysctl_fuse_max_pages_limit,
+ },
+};
+
+int fuse_sysctl_register(void)
+{
+ fuse_table_header = register_sysctl("fs/fuse", fuse_sysctl_table);
+ if (!fuse_table_header)
+ return -ENOMEM;
+ return 0;
+}
+
+void fuse_sysctl_unregister(void)
+{
+ unregister_sysctl_table(fuse_table_header);
+ fuse_table_header = NULL;
+}
--
2.43.5
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v3 1/1] fuse: enable dynamic configuration of fuse max pages limit (FUSE_MAX_MAX_PAGES)
2024-09-23 17:13 ` [PATCH v3 1/1] fuse: enable dynamic configuration of fuse max pages limit (FUSE_MAX_MAX_PAGES) Joanne Koong
@ 2024-09-24 9:43 ` Miklos Szeredi
2024-09-24 21:32 ` Joanne Koong
0 siblings, 1 reply; 4+ messages in thread
From: Miklos Szeredi @ 2024-09-24 9:43 UTC (permalink / raw)
To: Joanne Koong
Cc: linux-fsdevel, josef, bernd.schubert, sweettea-kernel, jefflexu,
kernel-team
On Mon, 23 Sept 2024 at 19:13, Joanne Koong <joannelkoong@gmail.com> wrote:
>
> Introduce the capability to dynamically configure the max pages limit
> (FUSE_MAX_MAX_PAGES) through a sysctl. This allows system administrators
> to dynamically set the maximum number of pages that can be used for
> servicing requests in fuse.
Applied (with a minor update, see below), thanks.
> @@ -2077,6 +2085,7 @@ static void fuse_fs_cleanup(void)
> {
> unregister_filesystem(&fuse_fs_type);
> unregister_fuseblk();
> + fuse_sysctl_unregister();
I moved this to the top of the function to make the order of the
cleanups reverse that of the setups. I haven't tested this, but I
guess it shouldn't make a difference, so this is just an aesthetic
fix.
Thanks,
Miklos
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v3 1/1] fuse: enable dynamic configuration of fuse max pages limit (FUSE_MAX_MAX_PAGES)
2024-09-24 9:43 ` Miklos Szeredi
@ 2024-09-24 21:32 ` Joanne Koong
0 siblings, 0 replies; 4+ messages in thread
From: Joanne Koong @ 2024-09-24 21:32 UTC (permalink / raw)
To: Miklos Szeredi
Cc: linux-fsdevel, josef, bernd.schubert, sweettea-kernel, jefflexu,
kernel-team
On Tue, Sep 24, 2024 at 2:44 AM Miklos Szeredi <miklos@szeredi.hu> wrote:
>
> On Mon, 23 Sept 2024 at 19:13, Joanne Koong <joannelkoong@gmail.com> wrote:
> >
> > Introduce the capability to dynamically configure the max pages limit
> > (FUSE_MAX_MAX_PAGES) through a sysctl. This allows system administrators
> > to dynamically set the maximum number of pages that can be used for
> > servicing requests in fuse.
>
> Applied (with a minor update, see below), thanks.
>
> > @@ -2077,6 +2085,7 @@ static void fuse_fs_cleanup(void)
> > {
> > unregister_filesystem(&fuse_fs_type);
> > unregister_fuseblk();
> > + fuse_sysctl_unregister();
>
> I moved this to the top of the function to make the order of the
> cleanups reverse that of the setups. I haven't tested this, but I
> guess it shouldn't make a difference, so this is just an aesthetic
> fix.
This update looks great to me. Thanks, Miklos!
>
> Thanks,
> Miklos
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2024-09-24 21:32 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-23 17:13 [PATCH v3 0/1] fuse: dynamically configure max pages limit through sysctl Joanne Koong
2024-09-23 17:13 ` [PATCH v3 1/1] fuse: enable dynamic configuration of fuse max pages limit (FUSE_MAX_MAX_PAGES) Joanne Koong
2024-09-24 9:43 ` Miklos Szeredi
2024-09-24 21:32 ` Joanne Koong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).