]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
fuse: add simple request tracepoints
authorJosef Bacik <josef@toxicpanda.com>
Wed, 3 Jul 2024 14:38:42 +0000 (10:38 -0400)
committerMiklos Szeredi <mszeredi@redhat.com>
Thu, 29 Aug 2024 09:43:13 +0000 (11:43 +0200)
I've been timing various fuse operations and it's quite annoying to do
with kprobes.  Add two tracepoints for sending and ending fuse requests
to make it easier to debug and time various operations.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Bernd Schubert <bschubert@ddn.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/fuse/Makefile
fs/fuse/dev.c
fs/fuse/fuse_trace.h [new file with mode: 0644]

index 6e0228c6d0cba9541c8668efb86b83094751d469..ce0ff7a9007b94b4ab246b5271f227d126c768e8 100644 (file)
@@ -3,6 +3,9 @@
 # Makefile for the FUSE filesystem.
 #
 
+# Needed for trace events
+ccflags-y = -I$(src)
+
 obj-$(CONFIG_FUSE_FS) += fuse.o
 obj-$(CONFIG_CUSE) += cuse.o
 obj-$(CONFIG_VIRTIO_FS) += virtiofs.o
index 2364df0324f7d51d422a08ef62dd0bc5cbc4f481..1b6088288a16893701b58344acc96da7dd2f608e 100644 (file)
@@ -22,6 +22,9 @@
 #include <linux/splice.h>
 #include <linux/sched.h>
 
+#define CREATE_TRACE_POINTS
+#include "fuse_trace.h"
+
 MODULE_ALIAS_MISCDEV(FUSE_MINOR);
 MODULE_ALIAS("devname:fuse");
 
@@ -289,6 +292,7 @@ static void fuse_send_one(struct fuse_iqueue *fiq, struct fuse_req *req)
        req->in.h.len = sizeof(struct fuse_in_header) +
                fuse_len_args(req->args->in_numargs,
                              (struct fuse_arg *) req->args->in_args);
+       trace_fuse_request_send(req);
        fiq->ops->send_req(fiq, req);
 }
 
@@ -335,6 +339,7 @@ void fuse_request_end(struct fuse_req *req)
        if (test_and_set_bit(FR_FINISHED, &req->flags))
                goto put_request;
 
+       trace_fuse_request_end(req);
        /*
         * test_and_set_bit() implies smp_mb() between bit
         * changing and below FR_INTERRUPTED check. Pairs with
diff --git a/fs/fuse/fuse_trace.h b/fs/fuse/fuse_trace.h
new file mode 100644 (file)
index 0000000..bbe9ddd
--- /dev/null
@@ -0,0 +1,132 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM fuse
+
+#if !defined(_TRACE_FUSE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_FUSE_H
+
+#include <linux/tracepoint.h>
+
+#define OPCODES                                                        \
+       EM( FUSE_LOOKUP,                "FUSE_LOOKUP")          \
+       EM( FUSE_FORGET,                "FUSE_FORGET")          \
+       EM( FUSE_GETATTR,               "FUSE_GETATTR")         \
+       EM( FUSE_SETATTR,               "FUSE_SETATTR")         \
+       EM( FUSE_READLINK,              "FUSE_READLINK")        \
+       EM( FUSE_SYMLINK,               "FUSE_SYMLINK")         \
+       EM( FUSE_MKNOD,                 "FUSE_MKNOD")           \
+       EM( FUSE_MKDIR,                 "FUSE_MKDIR")           \
+       EM( FUSE_UNLINK,                "FUSE_UNLINK")          \
+       EM( FUSE_RMDIR,                 "FUSE_RMDIR")           \
+       EM( FUSE_RENAME,                "FUSE_RENAME")          \
+       EM( FUSE_LINK,                  "FUSE_LINK")            \
+       EM( FUSE_OPEN,                  "FUSE_OPEN")            \
+       EM( FUSE_READ,                  "FUSE_READ")            \
+       EM( FUSE_WRITE,                 "FUSE_WRITE")           \
+       EM( FUSE_STATFS,                "FUSE_STATFS")          \
+       EM( FUSE_RELEASE,               "FUSE_RELEASE")         \
+       EM( FUSE_FSYNC,                 "FUSE_FSYNC")           \
+       EM( FUSE_SETXATTR,              "FUSE_SETXATTR")        \
+       EM( FUSE_GETXATTR,              "FUSE_GETXATTR")        \
+       EM( FUSE_LISTXATTR,             "FUSE_LISTXATTR")       \
+       EM( FUSE_REMOVEXATTR,           "FUSE_REMOVEXATTR")     \
+       EM( FUSE_FLUSH,                 "FUSE_FLUSH")           \
+       EM( FUSE_INIT,                  "FUSE_INIT")            \
+       EM( FUSE_OPENDIR,               "FUSE_OPENDIR")         \
+       EM( FUSE_READDIR,               "FUSE_READDIR")         \
+       EM( FUSE_RELEASEDIR,            "FUSE_RELEASEDIR")      \
+       EM( FUSE_FSYNCDIR,              "FUSE_FSYNCDIR")        \
+       EM( FUSE_GETLK,                 "FUSE_GETLK")           \
+       EM( FUSE_SETLK,                 "FUSE_SETLK")           \
+       EM( FUSE_SETLKW,                "FUSE_SETLKW")          \
+       EM( FUSE_ACCESS,                "FUSE_ACCESS")          \
+       EM( FUSE_CREATE,                "FUSE_CREATE")          \
+       EM( FUSE_INTERRUPT,             "FUSE_INTERRUPT")       \
+       EM( FUSE_BMAP,                  "FUSE_BMAP")            \
+       EM( FUSE_DESTROY,               "FUSE_DESTROY")         \
+       EM( FUSE_IOCTL,                 "FUSE_IOCTL")           \
+       EM( FUSE_POLL,                  "FUSE_POLL")            \
+       EM( FUSE_NOTIFY_REPLY,          "FUSE_NOTIFY_REPLY")    \
+       EM( FUSE_BATCH_FORGET,          "FUSE_BATCH_FORGET")    \
+       EM( FUSE_FALLOCATE,             "FUSE_FALLOCATE")       \
+       EM( FUSE_READDIRPLUS,           "FUSE_READDIRPLUS")     \
+       EM( FUSE_RENAME2,               "FUSE_RENAME2")         \
+       EM( FUSE_LSEEK,                 "FUSE_LSEEK")           \
+       EM( FUSE_COPY_FILE_RANGE,       "FUSE_COPY_FILE_RANGE") \
+       EM( FUSE_SETUPMAPPING,          "FUSE_SETUPMAPPING")    \
+       EM( FUSE_REMOVEMAPPING,         "FUSE_REMOVEMAPPING")   \
+       EM( FUSE_SYNCFS,                "FUSE_SYNCFS")          \
+       EM( FUSE_TMPFILE,               "FUSE_TMPFILE")         \
+       EM( FUSE_STATX,                 "FUSE_STATX")           \
+       EMe(CUSE_INIT,                  "CUSE_INIT")
+
+/*
+ * This will turn the above table into TRACE_DEFINE_ENUM() for each of the
+ * entries.
+ */
+#undef EM
+#undef EMe
+#define EM(a, b)       TRACE_DEFINE_ENUM(a);
+#define EMe(a, b)      TRACE_DEFINE_ENUM(a);
+
+OPCODES
+
+/* Now we redfine it with the table that __print_symbolic needs. */
+#undef EM
+#undef EMe
+#define EM(a, b)       {a, b},
+#define EMe(a, b)      {a, b}
+
+TRACE_EVENT(fuse_request_send,
+       TP_PROTO(const struct fuse_req *req),
+
+       TP_ARGS(req),
+
+       TP_STRUCT__entry(
+               __field(dev_t,                  connection)
+               __field(uint64_t,               unique)
+               __field(enum fuse_opcode,       opcode)
+               __field(uint32_t,               len)
+       ),
+
+       TP_fast_assign(
+               __entry->connection     =       req->fm->fc->dev;
+               __entry->unique         =       req->in.h.unique;
+               __entry->opcode         =       req->in.h.opcode;
+               __entry->len            =       req->in.h.len;
+       ),
+
+       TP_printk("connection %u req %llu opcode %u (%s) len %u ",
+                 __entry->connection, __entry->unique, __entry->opcode,
+                 __print_symbolic(__entry->opcode, OPCODES), __entry->len)
+);
+
+TRACE_EVENT(fuse_request_end,
+       TP_PROTO(const struct fuse_req *req),
+
+       TP_ARGS(req),
+
+       TP_STRUCT__entry(
+               __field(dev_t,          connection)
+               __field(uint64_t,       unique)
+               __field(uint32_t,       len)
+               __field(int32_t,        error)
+       ),
+
+       TP_fast_assign(
+               __entry->connection     =       req->fm->fc->dev;
+               __entry->unique         =       req->in.h.unique;
+               __entry->len            =       req->out.h.len;
+               __entry->error          =       req->out.h.error;
+       ),
+
+       TP_printk("connection %u req %llu len %u error %d", __entry->connection,
+                 __entry->unique, __entry->len, __entry->error)
+);
+
+#endif /* _TRACE_FUSE_H */
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE fuse_trace
+#include <trace/define_trace.h>