On 22.10.25 14:53, Kevin Wolf wrote:
Am 01.07.2025 um 13:44 hat Hanna Czenczek geschrieben:
Make fuse_process_request() a coroutine_fn (fuse_co_process_request())
and have read_from_fuse_fd() launch it inside of a newly created
coroutine instead of running it synchronously. This way, we can process
requests in parallel.
These are the benchmark results, compared to (a) the original results
with libfuse, and (b) the results after switching away from libfuse
(i.e. before this patch):
file: (vs. libfuse / vs. no libfuse)
read:
seq aio: 120.6k ±1.1k (+ 53 % / + 58 %)
rand aio: 113.3k ±5.9k (+188 % / +325 %)
seq sync: 52.4k ±0.4k (+ 61 % / + 10 %)
rand sync: 10.4k ±0.4k (+ 6 % / + 3 %)
write:
seq aio: 79.8k ±0.8k (+ 29 % / + 37 %)
rand aio: 79.0k ±0.6k (+ 29 % / + 36 %)
seq sync: 41.5k ±0.3k (+ 49 % / + 15 %)
rand sync: 41.4k ±0.2k (+ 50 % / + 15 %)
null:
read:
seq aio: 266.1k ±1.5k (+ 24 % / - 1 %)
rand aio: 264.1k ±2.5k (+ 24 % / ± 0 %)
seq sync: 135.6k ±3.2k (+ 50 % / + 1 %)
rand sync: 134.7k ±3.0k (+ 50 % / + 2 %)
write:
seq aio: 281.0k ±1.8k (+ 38 % / + 2 %)
rand aio: 288.1k ±6.1k (+ 43 % / + 6 %)
seq sync: 142.2k ±3.1k (+ 65 % / + 9 %)
rand sync: 141.1k ±2.9k (+ 66 % / + 11 %)
So for non-AIO cases (and the null driver, which does not yield), there
is little change; but for file AIO, results greatly improve, resolving
the performance issue we saw before (when switching away from libfuse).
Reviewed-by: Stefan Hajnoczi <[email protected]>
Signed-off-by: Hanna Czenczek <[email protected]>
---
block/export/fuse.c | 194 ++++++++++++++++++++++++++------------------
1 file changed, 113 insertions(+), 81 deletions(-)
diff --git a/block/export/fuse.c b/block/export/fuse.c
index 8ea590ba67..0648b5bc7d 100644
--- a/block/export/fuse.c
+++ b/block/export/fuse.c
@@ -27,6 +27,7 @@
#include "block/qapi.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-block.h"
+#include "qemu/coroutine.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "system/block-backend.h"
@@ -86,6 +87,12 @@ typedef struct FuseExport {
gid_t st_gid;
} FuseExport;
+/* Parameters to the request processing coroutine */
+typedef struct FuseRequestCoParam {
+ FuseExport *exp;
+ int got_request;
+} FuseRequestCoParam;
This type is unused.
Ha, true. Thanks.
Hanna