|
|
Log in / Subscribe / Register

FUSE and io_uring

This article brought to you by LWN subscribers

Subscribers to LWN.net made this article — and everything that surrounds it — possible. If you appreciate our content, please buy a subscription and make the next set of articles possible.

By Jake Edge
May 19, 2023

LSFMM+BPF

Bernd Schubert led a session at the 2023 Linux Storage, Filesystem, Memory-Management and BPF Summit on the intersection of FUSE and io_uring. He works for DDN Storage, which is using FUSE for two network-storage products; he has found FUSE to be a bottleneck for those filesystems. That could perhaps be improved by using io_uring, which is something he has been working on and wanted to discuss.

[Bernd Schubert]

He noted that Boaz Harrosh had developed the zero-copy user-mode filesystem (ZUFS) in 2018, but it did not go upstream in part due to concerns about its overlap with FUSE. Meanwhile, Miklos Szeredi started working on FUSE2, but that has languished as well. Schubert briefly looked at both, but the FUSE2 Git tree was hard to review since it is a single big patch rather than being broken into reviewable pieces.

Last year, he was working on atomic open operations and noticed some problems; Szeredi asked for some benchmarks, which turned out to be confusing. Multiple threads were reading from /dev/fuse, which caused the confusing results; switching to a single thread made the results consistent. He also realized that performing a polling loop before adding an operation to the wait queue greatly improved the filesystem performance.

He was also looking at an NVMe driver that his company uses, wondering why it was able to avoid the bottlenecks that he was seeing; it used io_uring, but in the "wrong" direction, from user space to the kernel, while FUSE needed to go the other way. Around that time, the IORING_OP_URING_CMD support for io_uring was added, which is being used in the ublk user-space block driver in the right direction, from the kernel to user space. That provides a model for doing something similar in FUSE, which is what Schubert has been working on.

He explained the inner workings of the work he has done to make FUSE use io_uring. There is one thread per core, each with its own ring buffer; there is a shared memory buffer with the FUSE queue ID used as the offset for user space to mmap() its region. Libfuse initiates operations with an IORING_OP_URING_CMD, which is the core idea taken from ublk. For debugging purposes, there is a mode with a single thread and ring buffer.

Amir Goldstein asked whether user space really needed to be aware of the underlying implementation. Schubert replied that his goal was to make it transparent, so that existing filesystem implementations could gain the performance benefits without having to change their code.

He is unhappy with using the queue ID to identify the user-space buffer (via the mmap() offset), but was unable to find the corresponding buffer in the kernel without it. There was some discussion of ways to get the kernel and user-space in sync on the buffer location directly. Jan Kara suggested looking in the VMA associated with the user-space virtual address to find where in kernel memory the buffer was located; he said that he could help Schubert find the right calls to make for that.

Schubert showed some performance benchmarks, but noted that he needs to find a way to keep the scheduler from migrating the application processes to other CPUs. For example, direct I/O reads showed moderate improvements for io_uring over regular FUSE, but much larger improvements when migration was disabled. Kara cautioned that CPU migration can be a problem at the start of a test like this, but may not actually be problematic over the long term; meanwhile, there are other workloads that may benefit from the migration.

But Schubert said that FUSE is particularly affected by this because most of the I/O work is being handed off to another process; once it completes, it is best if the application process is still running on that same CPU. Kara said that it is not a simple problem and that the scheduler may lack the information it needs to make the right decision. The scheduler developers are aware that there may be problems in scheduling for io_uring and are working on some solutions; he recommended that Schubert work with those developers.


Index entries for this article
KernelFilesystems/In user space
Kernelio_uring
ConferenceStorage, Filesystem, Memory-Management and BPF Summit/2023


to post comments

FUSE and io_uring

Posted May 19, 2023 17:46 UTC (Fri) by aakef (guest, #38030) [Link]

>He is unhappy with using the queue ID to identify the user-space buffer (via >the mmap() offset), but was unable to find the corresponding buffer in the >kernel without it. There was some discussion of ways to get the kernel and >user-space in sync on

Not entirely exact :) The kernel address is mapped to userspace - we have the kernel address. And then vma->vm_start is the user address (in the new fuse_uring_mmap function - file_operations::mmap). Except that printk result differed from what I see in userspace - I had assumed the address is obfuscated before being send to userspace. After discussing with Jan and and looking at the the code together, it turned out that it is actually printk %p that obfuscates the printed result - problem solved - offset parameter to identify the queue ID can be avoided.

FUSE and io_uring

Posted May 19, 2023 18:00 UTC (Fri) by aakef (guest, #38030) [Link] (2 responses)

>He was also looking at an NVMe driver that his company uses, wondering >why it was able to avoid the bottlenecks that he was seeing; it used io_uring, >but in the "wrong" direction, from user space to the kernel, while FUSE >needed to go the

I probably should have skipped that comment/background explanation.
We are not using io_uring for our nvme driver, but our own driver implementation. Nvme rings in general made think about a ring solution for fuse. Next step was then to think about io_uring.

FUSE and io_uring

Posted May 23, 2023 12:30 UTC (Tue) by gmgod (guest, #143864) [Link] (1 responses)

As a simple end-user with little clue of what is going on, how far would these changes potentially position FUSE with respect to in-kernel FS drivers (assuming the user-space part of the FUSE driver is decently optimised)?

FUSE and io_uring

Posted May 24, 2023 8:55 UTC (Wed) by aakef (guest, #38030) [Link]

The answer really depends a bit on what your fuse 'driver' (daemon) is doing.
Outstanding is zero copy support, I will look into that once I'm through with the scheduler. Zero copy will help with overlay and anything you don't need to access the IO buffer yourself - ZC is worked on by the ublk developer is not handing out the application buffer to the daemon, but is splice like approach were the buffer stays in the kernel. So if need the buffer (as we do), you will need to pay the penalty of a memory copy - a bit latency and possibly limited by system memory bandwidth (quite high, though) - we run into it in HPC, desktop systems might not. If you don't need the buffer, ZC has the overhead of a message (CQE) from kernel to daemon and back (SQE) - IOPs are the limit. And there it gets difficult to answer the question again for async (like buffered reads/writes). With the ring a single kernel/userspace submission can handle multiple requests - ring queue size and iosize from the mm system then matter.

A bit easier to answer are synchronous meta data requests, take a single threaded application creating files, like bonnie++ with a zero file size, file creates/s increase from about 2000 - 2500 creates/s to about 9000 to 9500 creates/s, with an overlay to xfs. XFS native on my system is about 16000 to 21000 creates/s. Absolute numbers depend on run time (the longer the higher - due to cpu freq increase) and cpu frequency govenor (default is 'convervative' - plain fuse really has an issue with it, /dev/fuse numbers are better in 'performance' mode, but native xfs and fuse-uring do not show much of a difference).

FUSE and io_uring

Posted May 19, 2023 18:09 UTC (Fri) by aakef (guest, #38030) [Link]

For the reference, discussion about cpu migration is ongoing here:
https://lore.kernel.org/lkml/d0ed1dbd-1b7e-bf98-65c0-7f61...


Copyright © 2023, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds