Commit 92cc9acf authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull fuse updates from Miklos Szeredi:
 "Add support for io-uring communication between kernel and userspace
  using IORING_OP_URING_CMD (Bernd Schubert). Following features enable
  gains in performance compared to the regular interface:

   - Allow processing multiple requests with less syscall overhead

   - Combine commit of old and fetch of new fuse request

   - CPU/NUMA affinity of queues

  Patches were reviewed by several people, including Pavel Begunkov,
  io-uring co-maintainer"

* tag 'fuse-update-6.14' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse:
  fuse: prevent disabling io-uring on active connections
  fuse: enable fuse-over-io-uring
  fuse: block request allocation until io-uring init is complete
  fuse: {io-uring} Prevent mount point hang on fuse-server termination
  fuse: Allow to queue bg requests through io-uring
  fuse: Allow to queue fg requests through io-uring
  fuse: {io-uring} Make fuse_dev_queue_{interrupt,forget} non-static
  fuse: {io-uring} Handle teardown of ring entries
  fuse: Add io-uring sqe commit and fetch support
  fuse: {io-uring} Make hash-list req unique finding functions non-static
  fuse: Add fuse-io-uring handling into fuse_copy
  fuse: Make fuse_copy non static
  fuse: {io-uring} Handle SQEs - register commands
  fuse: make args->in_args[0] to be always the header
  fuse: Add fuse-io-uring design documentation
  fuse: Move request bits
  fuse: Move fuse_get_dev to header file
  fuse: rename to fuse_dev_end_requests and make non-static
parents 27560b37 2d4fde59
Loading
Loading
Loading
Loading
+99 −0
Original line number Diff line number Diff line
.. SPDX-License-Identifier: GPL-2.0

=======================================
FUSE-over-io-uring design documentation
=======================================

This documentation covers basic details how the fuse
kernel/userspace communication through io-uring is configured
and works. For generic details about FUSE see fuse.rst.

This document also covers the current interface, which is
still in development and might change.

Limitations
===========
As of now not all requests types are supported through io-uring, userspace
is required to also handle requests through /dev/fuse after io-uring setup
is complete. Specifically notifications (initiated from the daemon side)
and interrupts.

Fuse io-uring configuration
===========================

Fuse kernel requests are queued through the classical /dev/fuse
read/write interface - until io-uring setup is complete.

In order to set up fuse-over-io-uring fuse-server (user-space)
needs to submit SQEs (opcode = IORING_OP_URING_CMD) to the /dev/fuse
connection file descriptor. Initial submit is with the sub command
FUSE_URING_REQ_REGISTER, which will just register entries to be
available in the kernel.

Once at least one entry per queue is submitted, kernel starts
to enqueue to ring queues.
Note, every CPU core has its own fuse-io-uring queue.
Userspace handles the CQE/fuse-request and submits the result as
subcommand FUSE_URING_REQ_COMMIT_AND_FETCH - kernel completes
the requests and also marks the entry available again. If there are
pending requests waiting the request will be immediately submitted
to the daemon again.

Initial SQE
-----------::

 |                                    |  FUSE filesystem daemon
 |                                    |
 |                                    |  >io_uring_submit()
 |                                    |   IORING_OP_URING_CMD /
 |                                    |   FUSE_URING_CMD_REGISTER
 |                                    |  [wait cqe]
 |                                    |   >io_uring_wait_cqe() or
 |                                    |   >io_uring_submit_and_wait()
 |                                    |
 |  >fuse_uring_cmd()                 |
 |   >fuse_uring_register()           |


Sending requests with CQEs
--------------------------::

 |                                           |  FUSE filesystem daemon
 |                                           |  [waiting for CQEs]
 |  "rm /mnt/fuse/file"                      |
 |                                           |
 |  >sys_unlink()                            |
 |    >fuse_unlink()                         |
 |      [allocate request]                   |
 |      >fuse_send_one()                     |
 |        ...                                |
 |       >fuse_uring_queue_fuse_req          |
 |        [queue request on fg queue]        |
 |         >fuse_uring_add_req_to_ring_ent() |
 |         ...                               |
 |          >fuse_uring_copy_to_ring()       |
 |          >io_uring_cmd_done()             |
 |       >request_wait_answer()              |
 |         [sleep on req->waitq]             |
 |                                           |  [receives and handles CQE]
 |                                           |  [submit result and fetch next]
 |                                           |  >io_uring_submit()
 |                                           |   IORING_OP_URING_CMD/
 |                                           |   FUSE_URING_CMD_COMMIT_AND_FETCH
 |  >fuse_uring_cmd()                        |
 |   >fuse_uring_commit_fetch()              |
 |    >fuse_uring_commit()                   |
 |     >fuse_uring_copy_from_ring()          |
 |      [ copy the result to the fuse req]   |
 |     >fuse_uring_req_end()                 |
 |      >fuse_request_end()                  |
 |       [wake up req->waitq]                |
 |    >fuse_uring_next_fuse_req              |
 |       [wait or handle next req]           |
 |                                           |
 |       [req->waitq woken up]               |
 |    <fuse_unlink()                         |
 |  <sys_unlink()                            |


+1 −0
Original line number Diff line number Diff line
@@ -98,6 +98,7 @@ Documentation for filesystem implementations.
   hpfs
   fuse
   fuse-io
   fuse-io-uring
   inotify
   isofs
   nilfs2
+12 −0
Original line number Diff line number Diff line
@@ -63,3 +63,15 @@ config FUSE_PASSTHROUGH
	  to be performed directly on a backing file.

	  If you want to allow passthrough operations, answer Y.

config FUSE_IO_URING
	bool "FUSE communication over io-uring"
	default y
	depends on FUSE_FS
	depends on IO_URING
	help
	  This allows sending FUSE requests over the io-uring interface and
          also adds request core affinity.

	  If you want to allow fuse server/client communication through io-uring,
	  answer Y
+1 −0
Original line number Diff line number Diff line
@@ -15,5 +15,6 @@ fuse-y += iomode.o
fuse-$(CONFIG_FUSE_DAX) += dax.o
fuse-$(CONFIG_FUSE_PASSTHROUGH) += passthrough.o
fuse-$(CONFIG_SYSCTL) += sysctl.o
fuse-$(CONFIG_FUSE_IO_URING) += dev_uring.o

virtiofs-y := virtio_fs.o
+6 −5
Original line number Diff line number Diff line
@@ -240,11 +240,12 @@ static int fuse_send_removemapping(struct inode *inode,

	args.opcode = FUSE_REMOVEMAPPING;
	args.nodeid = fi->nodeid;
	args.in_numargs = 2;
	args.in_args[0].size = sizeof(*inargp);
	args.in_args[0].value = inargp;
	args.in_args[1].size = inargp->count * sizeof(*remove_one);
	args.in_args[1].value = remove_one;
	args.in_numargs = 3;
	fuse_set_zero_arg0(&args);
	args.in_args[1].size = sizeof(*inargp);
	args.in_args[1].value = inargp;
	args.in_args[2].size = inargp->count * sizeof(*remove_one);
	args.in_args[2].value = remove_one;
	return fuse_simple_request(fm, &args);
}

Loading