Linux EXT4 FS development
 help / color / mirror / Atom feed
* Re: [patch 33/38] powerpc: Select ARCH_HAS_RANDOM_ENTROPY
From: Christophe Leroy (CS GROUP) @ 2026-04-15  6:47 UTC (permalink / raw)
  To: Thomas Gleixner, LKML
  Cc: Michael Ellerman, linuxppc-dev, Arnd Bergmann, x86, Lu Baolu,
	iommu, Michael Grzeschik, netdev, linux-wireless, Herbert Xu,
	linux-crypto, Vlastimil Babka, linux-mm, David Woodhouse,
	Bernie Thompson, linux-fbdev, Theodore Tso, linux-ext4,
	Andrew Morton, Uladzislau Rezki, Marco Elver, Dmitry Vyukov,
	kasan-dev, Andrey Ryabinin, Thomas Sailer, linux-hams,
	Jason A. Donenfeld, Richard Henderson, linux-alpha, Russell King,
	linux-arm-kernel, Catalin Marinas, Huacai Chen, loongarch,
	Geert Uytterhoeven, linux-m68k, Dinh Nguyen, Jonas Bonn,
	linux-openrisc, Helge Deller, linux-parisc, Paul Walmsley,
	linux-riscv, Heiko Carstens, linux-s390, David S. Miller,
	sparclinux
In-Reply-To: <20260410120319.789114053@kernel.org>



Le 10/04/2026 à 14:21, Thomas Gleixner a écrit :
> The only remaining usage of get_cycles() is to provide random_get_entropy().
> 
> Switch powerpc over to the new scheme of selecting ARCH_HAS_RANDOM_ENTROPY
> and providing random_get_entropy() in asm/random.h.
> 
> Remove asm/timex.h as it has no functionality anymore.
> 
> Signed-off-by: Thomas Gleixner <tglx@kernel.org>
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: linuxppc-dev@lists.ozlabs.org

Reviewed-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>

> ---
>   arch/powerpc/Kconfig              |    1 +
>   arch/powerpc/include/asm/random.h |   13 +++++++++++++
>   arch/powerpc/include/asm/timex.h  |   21 ---------------------
>   3 files changed, 14 insertions(+), 21 deletions(-)
> 
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -150,6 +150,7 @@ config PPC
>   	select ARCH_HAS_PREEMPT_LAZY
>   	select ARCH_HAS_PTDUMP
>   	select ARCH_HAS_PTE_SPECIAL
> +	select ARCH_HAS_RANDOM_ENTROPY
>   	select ARCH_HAS_SCALED_CPUTIME		if VIRT_CPU_ACCOUNTING_NATIVE && PPC_BOOK3S_64
>   	select ARCH_HAS_SET_MEMORY
>   	select ARCH_HAS_STRICT_KERNEL_RWX	if (PPC_BOOK3S || PPC_8xx) && !HIBERNATION
> --- /dev/null
> +++ b/arch/powerpc/include/asm/random.h
> @@ -0,0 +1,13 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _ASM_POWERPC_RANDOM_H
> +#define _ASM_POWERPC_RANDOM_H
> +
> +#include <asm/cputable.h>
> +#include <asm/vdso/timebase.h>
> +
> +static inline unsigned long random_get_entropy(void)
> +{
> +	return mftb();
> +}
> +
> +#endif	/* _ASM_POWERPC_RANDOM_H */
> --- a/arch/powerpc/include/asm/timex.h
> +++ b/arch/powerpc/include/asm/timex.h
> @@ -1,21 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> -#ifndef _ASM_POWERPC_TIMEX_H
> -#define _ASM_POWERPC_TIMEX_H
> -
> -#ifdef __KERNEL__
> -
> -/*
> - * PowerPC architecture timex specifications
> - */
> -
> -#include <asm/cputable.h>
> -#include <asm/vdso/timebase.h>
> -
> -ostatic inline cycles_t get_cycles(void)
> -{
> -	return mftb();
> -}
> -#define get_cycles get_cycles
> -
> -#endif	/* __KERNEL__ */
> -#endif	/* _ASM_POWERPC_TIMEX_H */
> 
> 


^ permalink raw reply

* Re: [RFC PATCH] iomap: add fast read path for small direct I/O
From: Christoph Hellwig @ 2026-04-15  7:14 UTC (permalink / raw)
  To: Fengnan Chang
  Cc: brauner, djwong, linux-xfs, linux-fsdevel, linux-ext4, lidiangang,
	Fengnan Chang
In-Reply-To: <20260414122647.15686-1-changfengnan@bytedance.com>

On Tue, Apr 14, 2026 at 08:26:47PM +0800, Fengnan Chang wrote:
> 1. Allocating the `bio` and `struct iomap_dio` together to avoid a
>    separate kmalloc. However, because `struct iomap_dio` is relatively
>    large and the main path is complex, this yielded almost no
>    performance improvement.

One interesting bit here would be a slab for struct iomap_dio, and
the previously discussed per-cpu allocation of some form.

> 2. Reducing unnecessary state resets in the iomap state machine (e.g.,
>    skipping `iomap_iter_reset_iomap` where safe). This provided a ~5%
>    IOPS boost, which is helpful but still falls far short of closing
>    the gap with the raw block device.

But it already is a major improvement, and one that would apply outside
of narrow special cases.  So I'd really like to see that patch.

> The fast path is triggered when the request satisfies:
> - Asynchronous READ request only for now.

I think you really should handle synchronous reads as well.

> - I/O size is <= inode blocksize (fits in a single block, no splits).

Makes sense, and I suspect this is the main source of speedups.

> - Aligned to the block device's logical block size.

All direct I/O requires this.

> - No bounce buffering, fscrypt, or fsverity involved.
> - No custom `iomap_dio_ops` (dops) registered by the filesystem.

I'm really curious at what difference this makes.  It removes a few
branches, but should not have much of an effect while limiting the
applicability a lot.

> After this optimization, the heavy generic functions disappear from the
> profile, replaced by a single streamlined execution path:
>   4.83%  [kernel]  [k] iomap_dio_fast_read_async.isra.31
> 
> With this patch, 4K random read IOPS on ext4 increases from 1.9M to
> 2.3M.

That is still a lot slower than the block device path.  A big part of
it should be the extent lookup and locking associated with it, but
I'd expect things to be a bit better.  Do you have XFS version as well?

> However, I am submitting this patch to validate whether this
> optimization direction is correct and worth pursuing. I would appreciate
> feedback on how to better integrate these ideas into the main iomap
> execution path.

I think a <= block size fast path makes a lot of sense, just like we
have a simple version on the block device, but it needs more work.

> +struct iomap_dio_fast_read {
> +	struct kiocb	*iocb;
> +	size_t		size;
> +	bool		should_dirty;
> +	struct work_struct	work;
> +	struct bio	bio ____cacheline_aligned_in_smp;

Does the cache line alignment matter here?  If yes, can you explain why
in a comment?

> +static struct bio_set iomap_dio_fast_read_pool;

In general I'd prefer to stick to simple as in the block device version
instead of fast.

> +static void iomap_dio_fast_read_complete_work(struct work_struct *work)
> +{
> +	struct iomap_dio_fast_read *fr =
> +		container_of(work, struct iomap_dio_fast_read, work);
> +	struct kiocb *iocb = fr->iocb;
> +	struct inode *inode = file_inode(iocb->ki_filp);
> +	bool should_dirty = fr->should_dirty;
> +	struct bio *bio = &fr->bio;
> +	ssize_t ret;
> +
> +	WRITE_ONCE(iocb->private, NULL);
> +
> +	if (likely(!bio->bi_status)) {
> +		ret = fr->size;
> +		iocb->ki_pos += ret;
> +	} else {
> +		ret = blk_status_to_errno(bio->bi_status);
> +		fserror_report_io(inode, FSERR_DIRECTIO_READ, iocb->ki_pos,
> +				  fr->size, ret, GFP_NOFS);
> +	}
> +
> +	if (should_dirty) {
> +		bio_check_pages_dirty(bio);
> +	} else {
> +		bio_release_pages(bio, false);
> +		bio_put(bio);
> +	}
> +
> +	inode_dio_end(inode);
> +
> +	trace_iomap_dio_complete(iocb, ret < 0 ? ret : 0, ret > 0 ? ret : 0);
> +	iocb->ki_complete(iocb, ret);

This is a lot of duplicate cork.  Can we somehow share it by passing
more arguments or embedding the simple context into the bigger one?

> +static inline bool iomap_dio_fast_read_supported(struct kiocb *iocb,
> +					  struct iov_iter *iter,
> +					  unsigned int dio_flags,
> +					  size_t done_before)

Please stick to two-tab indents for prototype continuations, which is
both more readable and easier to modify later.

> +	if (count < bdev_logical_block_size(inode->i_sb->s_bdev))
> +		return false;

Sub-sector reads (unlike writes) don't require any special handling, so
I don't see why they are excluded.

> +	if (dio_flags & IOMAP_DIO_FSBLOCK_ALIGNED)
> +		alignment = i_blocksize(inode);
> +	else
> +		alignment = bdev_logical_block_size(inode->i_sb->s_bdev);
> +
> +	if ((iocb->ki_pos | count) & (alignment - 1))
> +		return false;

Factor this into a helper?

> +	inode_dio_begin(inode);
> +
> +	ret = ops->iomap_begin(inode, iomi.pos, count, iomi.flags,
> +			       &iomi.iomap, &iomi.srcmap);
> +	if (ret) {
> +		inode_dio_end(inode);
> +		return ret;
> +	}

If we can I'd much prefer avoiding the open coded iomap_begin
invocation, as that is a real maintenance burden.

> +
> +	if (iomi.iomap.type != IOMAP_MAPPED ||
> +	    iomi.iomap.offset > iomi.pos ||
> +	    iomi.iomap.offset + iomi.iomap.length < iomi.pos + count ||
> +	    (iomi.iomap.flags & IOMAP_F_ANON_WRITE)) {

IOMAP_F_ANON_WRITE (as the name implies) only applies to writes.

> +		ret = -EAGAIN;

-EAGAIN is a bad status code, as we already use to indicate that a
non-blocking read blocks.

> +	ret = bio_iov_iter_get_pages(bio, iter,
> +				     bdev_logical_block_size(iomi.iomap.bdev) - 1);

Overly long line.  Also this needs to use the calculated alignment
value.

> +	if (unlikely(ret)) {
> +		bio_put(bio);
> +		goto out_iomap_end;
> +	}
> +
> +	if (bio->bi_iter.bi_size != count) {
> +		iov_iter_revert(iter, bio->bi_iter.bi_size);
> +		bio_release_pages(bio, false);
> +		bio_put(bio);
> +		ret = -EAGAIN;
> +		goto out_iomap_end;
> +	}

Share the bio_put with a new goto label, and maybe also move all
the other cleanup code out of the main path into a label?

> +	if (!dops && iomap_dio_fast_read_supported(iocb, iter, dio_flags, done_before)) {

Overly long line.  But we should not make the fast path conditional
on an option anyway.


^ permalink raw reply

* [PATCH v2 2/4] ext4: skip cursor node in ext4_orphan_del()
From: Ye Bin @ 2026-04-15 10:55 UTC (permalink / raw)
  To: tytso, adilger.kernel, linux-ext4; +Cc: jack
In-Reply-To: <20260415105505.342358-1-yebin@huaweicloud.com>

From: Ye Bin <yebin10@huawei.com>

This patch is prepared for displaying orphan_list information. Because
temporary nodes may be inserted when the orphan_list is traversed and
displayed, these temporary nodes need to be skipped.

Signed-off-by: Ye Bin <yebin10@huawei.com>
---
 fs/ext4/orphan.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/fs/ext4/orphan.c b/fs/ext4/orphan.c
index f7e7f77e021e..a6bffe67ef75 100644
--- a/fs/ext4/orphan.c
+++ b/fs/ext4/orphan.c
@@ -220,6 +220,23 @@ static int ext4_orphan_file_del(handle_t *handle, struct inode *inode)
 	return ret;
 }
 
+static inline bool ext4_is_cursor(struct inode *inode)
+{
+	return (inode->i_ino == 0);
+}
+
+static inline struct list_head *ext4_orphan_prev_node(
+					struct ext4_inode_info *pos,
+					struct list_head *head)
+{
+	list_for_each_entry_continue_reverse(pos, head, i_orphan) {
+		if (likely(!ext4_is_cursor(&pos->vfs_inode)))
+			return &pos->i_orphan;
+	}
+
+	return head;
+}
+
 /*
  * ext4_orphan_del() removes an unlinked or truncated inode from the list
  * of such inodes stored on disk, because it is finally being cleaned up.
@@ -253,7 +270,8 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
 	mutex_lock(&sbi->s_orphan_lock);
 	ext4_debug("remove inode %llu from orphan list\n", inode->i_ino);
 
-	prev = ei->i_orphan.prev;
+	prev = ext4_orphan_prev_node(ei, &sbi->s_orphan);
+
 	list_del_init(&ei->i_orphan);
 
 	/* If we're on an error path, we may not have a valid
-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 1/4] ext4: register 'orphan_list' procfs
From: Ye Bin @ 2026-04-15 10:55 UTC (permalink / raw)
  To: tytso, adilger.kernel, linux-ext4; +Cc: jack
In-Reply-To: <20260415105505.342358-1-yebin@huaweicloud.com>

From: Ye Bin <yebin10@huawei.com>

This patch register '/proc/fs/ext4/XXX/orphan_list' procfs for show inode
orphan list about EXT4 file system.
In actual production environments, there may be inconsistencies in df/du,
sometimes due to kernel occupation, making it difficult to find such files,
and it is also difficult to operate in the current network environment. So
add "orphan_list" procfs to quickly query files that have been deleted but
are occupied.

Signed-off-by: Ye Bin <yebin10@huawei.com>
---
 fs/ext4/ext4.h   |  1 +
 fs/ext4/orphan.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++
 fs/ext4/sysfs.c  |  2 ++
 3 files changed, 80 insertions(+)

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 0cf68f85dfd1..ccb0fd1e63e7 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -3875,6 +3875,7 @@ extern void ext4_stop_mmpd(struct ext4_sb_info *sbi);
 extern const struct fsverity_operations ext4_verityops;
 
 /* orphan.c */
+extern const struct proc_ops ext4_orphan_proc_ops;
 extern int ext4_orphan_add(handle_t *, struct inode *);
 extern int ext4_orphan_del(handle_t *, struct inode *);
 extern void ext4_orphan_cleanup(struct super_block *sb,
diff --git a/fs/ext4/orphan.c b/fs/ext4/orphan.c
index 64ea47624233..f7e7f77e021e 100644
--- a/fs/ext4/orphan.c
+++ b/fs/ext4/orphan.c
@@ -4,6 +4,8 @@
 #include <linux/fs.h>
 #include <linux/quotaops.h>
 #include <linux/buffer_head.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 
 #include "ext4.h"
 #include "ext4_jbd2.h"
@@ -657,3 +659,78 @@ int ext4_orphan_file_empty(struct super_block *sb)
 			return 0;
 	return 1;
 }
+
+struct ext4_proc_orphan {
+	struct ext4_inode_info cursor;
+};
+
+static void *ext4_orphan_seq_start(struct seq_file *seq, loff_t *pos)
+{
+	return NULL;
+}
+
+static void *ext4_orphan_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+	return NULL;
+}
+
+static int ext4_orphan_seq_show(struct seq_file *seq, void *v)
+{
+	return 0;
+}
+
+static void ext4_orphan_seq_stop(struct seq_file *seq, void *v)
+{
+}
+
+const struct seq_operations ext4_orphan_seq_ops = {
+	.start  = ext4_orphan_seq_start,
+	.next   = ext4_orphan_seq_next,
+	.stop   = ext4_orphan_seq_stop,
+	.show   = ext4_orphan_seq_show,
+};
+
+static int ext4_seq_orphan_open(struct inode *inode, struct file *file)
+{
+	int rc;
+	struct seq_file *m;
+	struct ext4_proc_orphan *private;
+
+	rc = seq_open_private(file, &ext4_orphan_seq_ops,
+			      sizeof(struct ext4_proc_orphan));
+	if (!rc) {
+		m = file->private_data;
+		private = m->private;
+		INIT_LIST_HEAD(&private->cursor.i_orphan);
+		private->cursor.vfs_inode.i_ino = 0;
+	}
+
+	return rc;
+}
+
+static int ext4_seq_orphan_release(struct inode *inode, struct file *file)
+{
+	struct seq_file *seq = file->private_data;
+	struct ext4_proc_orphan *s = seq->private;
+	struct ext4_sb_info *sbi = EXT4_SB(pde_data(inode));
+
+	/*
+	 * The function close_pdeo() is called when deleting the procfs
+	 * in ext4_unregister_sysfs(), and this function is used to remove
+	 * the entry from the 'pde->pde_openers' list. Therefore, when the
+	 * file is closed, proc_reg_release() will not call close_pdeo()
+	 * again because it cannot find the node on the 'pde->pde_openers'
+	 * list. This prevents the UAF issue from occurring.
+	 */
+	mutex_lock(&sbi->s_orphan_lock);
+	list_del(&s->cursor.i_orphan);
+	mutex_unlock(&sbi->s_orphan_lock);
+
+	return seq_release_private(inode, file);
+}
+
+const struct proc_ops ext4_orphan_proc_ops = {
+	.proc_open      = ext4_seq_orphan_open,
+	.proc_read      = seq_read,
+	.proc_release   = ext4_seq_orphan_release,
+};
diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c
index 923b375e017f..b40a934e30c9 100644
--- a/fs/ext4/sysfs.c
+++ b/fs/ext4/sysfs.c
@@ -639,6 +639,8 @@ int ext4_register_sysfs(struct super_block *sb)
 				ext4_seq_mb_stats_show, sb);
 		proc_create_seq_data("mb_structs_summary", 0444, sbi->s_proc,
 				&ext4_mb_seq_structs_summary_ops, sb);
+		proc_create_data("orphan_list", 0400, sbi->s_proc,
+				 &ext4_orphan_proc_ops, sb);
 	}
 	return 0;
 }
-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 0/4] show orphan file inode detail info
From: Ye Bin @ 2026-04-15 10:55 UTC (permalink / raw)
  To: tytso, adilger.kernel, linux-ext4; +Cc: jack

From: Ye Bin <yebin10@huawei.com>

Diffs v2 vs v1:
(1) Fix sashiko review issues:
https://sashiko.dev/#/patchset/20260403082507.1882703-1-yebin%40huaweicloud.com
(2) Change "orphan_list" file mode from 0444 to 0400;
(3) The display format of the "orphan_list" file is modified according
    to Andreas' suggestions.
Fault injection tests have been conducted to address the issues raised
in the sashik review. There is no UAF issue in the ext4_seq_orphan_release()
function. The reason for this has already been explained in the code comments.
In addition to the fault injection tests, we also performed a stress test by
observing the /proc/fs/ext4/XX/orphan_list and the concurrent processes of
adding and removing orphan nodes, and no issues were found so far.


In actual production environments, the issue of inconsistency between
df and du is frequently encountered. In many cases, the cause of the
problem can be identified through the use of lsof. However, when
overlayfs is combined with project quota configuration, the issue becomes
more complex and troublesome to diagnose. First, to determine the project
ID, one needs to obtain orphaned nodes using `fsck.ext4 -fn /dev/xx`, and
then retrieve file information through `debugfs`. However, the file names
cannot always be obtained, and it is often unclear which files they are.
To identify which files these are, one would need to use crash for online
debugging or use kprobe to gather information incrementally. However, some
customers in production environments do not agree to upload any tools, and
online debugging might impact the business. There are also scenarios where
files are opened in kernel mode, which do not generate file descriptors(fds),
making it impossible to identify which files were deleted but still have
references through lsof. This patchset adds a procfs interface to query
information about orphaned nodes, which can assist in the analysis and
localization of such issues.

Ye Bin (4):
  ext4: register 'orphan_list' procfs
  ext4: skip cursor node in ext4_orphan_del()
  ext4: show inode orphan list detail information
  ext4: show orphan file inode detail info

 fs/ext4/ext4.h   |   1 +
 fs/ext4/orphan.c | 326 ++++++++++++++++++++++++++++++++++++++++++++++-
 fs/ext4/sysfs.c  |   2 +
 3 files changed, 328 insertions(+), 1 deletion(-)

-- 
2.34.1


^ permalink raw reply

* [PATCH v2 3/4] ext4: show inode orphan list detail information
From: Ye Bin @ 2026-04-15 10:55 UTC (permalink / raw)
  To: tytso, adilger.kernel, linux-ext4; +Cc: jack
In-Reply-To: <20260415105505.342358-1-yebin@huaweicloud.com>

From: Ye Bin <yebin10@huawei.com>

Some inodes added to the orphan list are due to truncation, while others
are due to deletion.Therefore, we printed the information of inode as
follows: inode number/i_nlink/i_size/i_blocks/projid/file path. By using
this information, it is possible to quickly identify files that have been
deleted but are still being referenced.

Signed-off-by: Ye Bin <yebin10@huawei.com>
---
 fs/ext4/orphan.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 126 insertions(+), 2 deletions(-)

diff --git a/fs/ext4/orphan.c b/fs/ext4/orphan.c
index a6bffe67ef75..4d6f8c9edaeb 100644
--- a/fs/ext4/orphan.c
+++ b/fs/ext4/orphan.c
@@ -682,23 +682,147 @@ struct ext4_proc_orphan {
 	struct ext4_inode_info cursor;
 };
 
-static void *ext4_orphan_seq_start(struct seq_file *seq, loff_t *pos)
+static struct inode *ext4_list_next(struct ext4_proc_orphan *s,
+				    struct list_head *head,
+				    struct list_head *p)
 {
+	list_for_each_continue(p, head) {
+		struct ext4_inode_info *ei;
+		struct inode *inode;
+
+		ei = list_entry(p, typeof(*ei), i_orphan);
+		inode = &ei->vfs_inode;
+
+		/*
+		 * It is safe to insert a cursor into the orphan list
+		 * because ext4_orphan_del() will skip cursor. When the
+		 * orphan list is processed in ext4_put_super(),
+		 * ext4_seq_orphan_release() must have already been called,
+		 * so the cursor must have already been removed from the
+		 * orphan list.Therefore, there will be no access to a
+		 * stale cursor.
+		 */
+		list_move(&s->cursor.i_orphan, &ei->i_orphan);
+
+		/*
+		 * Because the cursor has moved to the node after the
+		 * current node, the traversal cannot continue from the
+		 * current node. Instead, the traversal should continue
+		 * from the cursor.
+		 */
+		p = &s->cursor.i_orphan;
+
+		if (ext4_is_cursor(inode))
+			continue;
+
+		if (!igrab(inode))
+			continue;
+
+		return inode;
+	}
+
 	return NULL;
 }
 
+static void *ext4_orphan_seq_start(struct seq_file *seq, loff_t *pos)
+{
+	struct ext4_proc_orphan *s = seq->private;
+	struct super_block *sb = pde_data(file_inode(seq->file));
+	struct ext4_sb_info *sbi = EXT4_SB(sb);
+	struct list_head *prev;
+
+	mutex_lock(&sbi->s_orphan_lock);
+
+	if (!*pos) {
+		prev = &sbi->s_orphan;
+	} else {
+		prev = &s->cursor.i_orphan;
+		if (list_empty(prev))
+			return NULL;
+	}
+
+	return ext4_list_next(s, &sbi->s_orphan, prev);
+}
+
 static void *ext4_orphan_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-	return NULL;
+	struct super_block *sb = pde_data(file_inode(seq->file));
+	struct ext4_sb_info *sbi = EXT4_SB(sb);
+	struct ext4_proc_orphan *s = seq->private;
+	struct inode *inode = v;
+
+	++*pos;
+
+	/*
+	 * To prevent the deadlock caused by orphan node deletion when the
+	 * last inode reference count is released, the inode reference
+	 * count needs to be released in the unlocked state.
+	 */
+	mutex_unlock(&sbi->s_orphan_lock);
+	iput(inode);
+	mutex_lock(&sbi->s_orphan_lock);
+
+	return ext4_list_next(s, &sbi->s_orphan, &s->cursor.i_orphan);
+}
+
+static void ext4_show_filename(struct seq_file *seq, struct inode *inode)
+{
+	struct dentry *dentry;
+
+	dentry = d_find_alias(inode);
+	if (!dentry)
+		dentry = d_find_any_alias(inode);
+
+	if (dentry)
+		seq_dentry(seq, dentry, " \t\n\\");
+	else
+		seq_puts(seq, "unknown");
+
+	seq_puts(seq, "\"\n");
+
+	/*
+	 * Since igrab() has already been called in ext4_list_next(), the
+	 * inode will not be released here, so there will be no deadlock.
+	 */
+	dput(dentry);
 }
 
 static int ext4_orphan_seq_show(struct seq_file *seq, void *v)
 {
+	struct inode *inode = v;
+
+	/*
+	 * Print the original data without differentiating namespaces.
+	 */
+	seq_printf(seq, "ino: %llu, link: %u, size: %llu, blocks: %llu, proj: %u, path: \"",
+		   inode->i_ino, inode->i_nlink,
+		   i_size_read(inode), inode->i_blocks,
+		   __kprojid_val(EXT4_I(inode)->i_projid));
+
+	ext4_show_filename(seq, inode);
+
 	return 0;
 }
 
 static void ext4_orphan_seq_stop(struct seq_file *seq, void *v)
 {
+	struct super_block *sb = pde_data(file_inode(seq->file));
+	struct ext4_sb_info *sbi = EXT4_SB(sb);
+	struct ext4_proc_orphan *s = seq->private;
+	struct inode *inode = v;
+
+	/*
+	 * stop() is called when the cache is full, so the traversal
+	 * position needs to be moved back to the front of the current
+	 * inode.
+	 */
+	if (v)
+		list_move_tail(&s->cursor.i_orphan,
+			       &EXT4_I(inode)->i_orphan);
+
+	mutex_unlock(&sbi->s_orphan_lock);
+
+	iput(inode);
 }
 
 const struct seq_operations ext4_orphan_seq_ops = {
-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 4/4] ext4: show orphan file inode detail info
From: Ye Bin @ 2026-04-15 10:55 UTC (permalink / raw)
  To: tytso, adilger.kernel, linux-ext4; +Cc: jack
In-Reply-To: <20260415105505.342358-1-yebin@huaweicloud.com>

From: Ye Bin <yebin10@huawei.com>

Support show inode information in orphan file.

Signed-off-by: Ye Bin <yebin10@huawei.com>
---
 fs/ext4/orphan.c | 179 ++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 146 insertions(+), 33 deletions(-)

diff --git a/fs/ext4/orphan.c b/fs/ext4/orphan.c
index 4d6f8c9edaeb..715d04e386d0 100644
--- a/fs/ext4/orphan.c
+++ b/fs/ext4/orphan.c
@@ -680,6 +680,11 @@ int ext4_orphan_file_empty(struct super_block *sb)
 
 struct ext4_proc_orphan {
 	struct ext4_inode_info cursor;
+	struct ext4_orphan_info *oi;
+	int inodes_per_ob;
+	int block_idx;
+	int offset;
+	bool orphan_file;
 };
 
 static struct inode *ext4_list_next(struct ext4_proc_orphan *s,
@@ -724,24 +729,94 @@ static struct inode *ext4_list_next(struct ext4_proc_orphan *s,
 	return NULL;
 }
 
+static struct inode *ext4_orphan_file_next(struct ext4_proc_orphan *s,
+					   struct super_block *sb)
+{
+	struct inode *inode = NULL;
+	struct ext4_orphan_info *oi = s->oi;
+
+	for (; s->block_idx < oi->of_blocks; s->block_idx++) {
+		int idx = s->block_idx;
+		struct ext4_orphan_block *binfo = &oi->of_binfo[idx];
+		__le32 *bdata = (__le32 *)(binfo->ob_bh->b_data);
+
+		if (atomic_read(&binfo->ob_free_entries) ==
+				s->inodes_per_ob) {
+			s->offset = 0;
+			continue;
+		}
+		for (; s->offset < s->inodes_per_ob; s->offset++) {
+			u64 ino = le32_to_cpu(bdata[s->offset]);
+
+			if (!ino)
+				continue;
+			/*
+			 * Orphan nodes in the running state are those
+			 * inodes that are still in use, so here we get
+			 * them from the cache if available.
+			 */
+			inode = ilookup(sb, ino);
+			if (!inode)
+				continue;
+
+			if (!ext4_test_inode_state(inode,
+						EXT4_STATE_ORPHAN_FILE)) {
+				iput(inode);
+				continue;
+			}
+
+			s->offset++;
+			if (s->offset == s->inodes_per_ob) {
+				s->offset = 0;
+				s->block_idx++;
+			}
+			return inode;
+		}
+
+		s->offset = 0;
+	}
+
+	return NULL;
+}
+
 static void *ext4_orphan_seq_start(struct seq_file *seq, loff_t *pos)
 {
 	struct ext4_proc_orphan *s = seq->private;
 	struct super_block *sb = pde_data(file_inode(seq->file));
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
 	struct list_head *prev;
+	void *ret;
 
-	mutex_lock(&sbi->s_orphan_lock);
+	if (!s->orphan_file) {
+		mutex_lock(&sbi->s_orphan_lock);
+		if (!*pos)
+			prev = &sbi->s_orphan;
+		else
+			prev = &s->cursor.i_orphan;
 
-	if (!*pos) {
-		prev = &sbi->s_orphan;
-	} else {
-		prev = &s->cursor.i_orphan;
-		if (list_empty(prev))
+		/*
+		 * Here, the code checks whether the linked list is empty
+		 * because when the orphan_file feature is supported, the
+		 * cursor is removed from the linked list after the orphan
+		 * list is traversed. If the orphan_file feature is not
+		 * enabled, calling ext4_orphan_seq_start() again would
+		 * cause an infinite loop.
+		 */
+		if (!list_empty(prev)) {
+			ret = ext4_list_next(s, &sbi->s_orphan, prev);
+			if (ret)
+				return ret;
+		}
+
+		if (!s->oi)
 			return NULL;
+
+		list_del_init(&s->cursor.i_orphan);
+		mutex_unlock(&sbi->s_orphan_lock);
+		s->orphan_file = true;
 	}
 
-	return ext4_list_next(s, &sbi->s_orphan, prev);
+	return ext4_orphan_file_next(s, sb);
 }
 
 static void *ext4_orphan_seq_next(struct seq_file *seq, void *v, loff_t *pos)
@@ -750,19 +825,36 @@ static void *ext4_orphan_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
 	struct ext4_proc_orphan *s = seq->private;
 	struct inode *inode = v;
+	void *ret;
 
 	++*pos;
 
-	/*
-	 * To prevent the deadlock caused by orphan node deletion when the
-	 * last inode reference count is released, the inode reference
-	 * count needs to be released in the unlocked state.
-	 */
-	mutex_unlock(&sbi->s_orphan_lock);
-	iput(inode);
-	mutex_lock(&sbi->s_orphan_lock);
+	if (!s->orphan_file) {
+		/*
+		 * To prevent the deadlock caused by orphan node deletion
+		 * when the last inode reference count is released, the
+		 * inode reference count needs to be released in the
+		 * unlocked state.
+		 */
+		mutex_unlock(&sbi->s_orphan_lock);
+		iput(inode);
+		mutex_lock(&sbi->s_orphan_lock);
+
+		ret = ext4_list_next(s, &sbi->s_orphan,
+				     &s->cursor.i_orphan);
+		if (ret)
+			return ret;
+		if (!s->oi)
+			return NULL;
+		list_del_init(&s->cursor.i_orphan);
+		mutex_unlock(&sbi->s_orphan_lock);
+		s->orphan_file = true;
+	} else {
+		iput(inode);
+	}
+
 
-	return ext4_list_next(s, &sbi->s_orphan, &s->cursor.i_orphan);
+	return ext4_orphan_file_next(s, sb);
 }
 
 static void ext4_show_filename(struct seq_file *seq, struct inode *inode)
@@ -811,16 +903,28 @@ static void ext4_orphan_seq_stop(struct seq_file *seq, void *v)
 	struct ext4_proc_orphan *s = seq->private;
 	struct inode *inode = v;
 
-	/*
-	 * stop() is called when the cache is full, so the traversal
-	 * position needs to be moved back to the front of the current
-	 * inode.
-	 */
-	if (v)
-		list_move_tail(&s->cursor.i_orphan,
-			       &EXT4_I(inode)->i_orphan);
+	if (!s->orphan_file) {
+		/*
+		 * stop() is called when the cache is full, so the
+		 * traversal position needs to be moved back to the
+		 * front of the current inode. If stop() due to EOF
+		 * then remove cursor from orphan list.
+		 */
+		if (inode)
+			list_move_tail(&s->cursor.i_orphan,
+				       &EXT4_I(inode)->i_orphan);
+		else
+			list_del_init(&s->cursor.i_orphan);
 
-	mutex_unlock(&sbi->s_orphan_lock);
+		mutex_unlock(&sbi->s_orphan_lock);
+	} else if (inode) {
+		if (s->offset) {
+			s->offset--;
+		} else if (s->block_idx) {
+			s->block_idx--;
+			s->offset = s->inodes_per_ob - 1;
+		}
+	}
 
 	iput(inode);
 }
@@ -836,15 +940,21 @@ static int ext4_seq_orphan_open(struct inode *inode, struct file *file)
 {
 	int rc;
 	struct seq_file *m;
-	struct ext4_proc_orphan *private;
+	struct ext4_proc_orphan *s;
 
 	rc = seq_open_private(file, &ext4_orphan_seq_ops,
 			      sizeof(struct ext4_proc_orphan));
 	if (!rc) {
+		struct super_block *sb = pde_data(file_inode(file));
 		m = file->private_data;
-		private = m->private;
-		INIT_LIST_HEAD(&private->cursor.i_orphan);
-		private->cursor.vfs_inode.i_ino = 0;
+		s = m->private;
+		INIT_LIST_HEAD(&s->cursor.i_orphan);
+		s->cursor.vfs_inode.i_ino = 0;
+		s->orphan_file = 0;
+		if (ext4_has_feature_orphan_file(sb)) {
+			s->oi = &EXT4_SB(sb)->s_orphan_info;
+			s->inodes_per_ob = ext4_inodes_per_orphan_block(sb);
+		}
 	}
 
 	return rc;
@@ -862,11 +972,14 @@ static int ext4_seq_orphan_release(struct inode *inode, struct file *file)
 	 * the entry from the 'pde->pde_openers' list. Therefore, when the
 	 * file is closed, proc_reg_release() will not call close_pdeo()
 	 * again because it cannot find the node on the 'pde->pde_openers'
-	 * list. This prevents the UAF issue from occurring.
+	 * list. This prevents the UAF issue from occurring. Maybe, cursor
+	 * already removed in stop().
 	 */
-	mutex_lock(&sbi->s_orphan_lock);
-	list_del(&s->cursor.i_orphan);
-	mutex_unlock(&sbi->s_orphan_lock);
+	if (!s->orphan_file) {
+		mutex_lock(&sbi->s_orphan_lock);
+		list_del(&s->cursor.i_orphan);
+		mutex_unlock(&sbi->s_orphan_lock);
+	}
 
 	return seq_release_private(inode, file);
 }
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH v2 0/4] show orphan file inode detail info
From: Jan Kara @ 2026-04-15 17:59 UTC (permalink / raw)
  To: Ye Bin; +Cc: tytso, adilger.kernel, linux-ext4, jack
In-Reply-To: <20260415105505.342358-1-yebin@huaweicloud.com>

Hello!

On Wed 15-04-26 18:55:01, Ye Bin wrote:
> From: Ye Bin <yebin10@huawei.com>
> 
> Diffs v2 vs v1:
> (1) Fix sashiko review issues:
> https://sashiko.dev/#/patchset/20260403082507.1882703-1-yebin%40huaweicloud.com
> (2) Change "orphan_list" file mode from 0444 to 0400;
> (3) The display format of the "orphan_list" file is modified according
>     to Andreas' suggestions.
> Fault injection tests have been conducted to address the issues raised
> in the sashik review. There is no UAF issue in the ext4_seq_orphan_release()
> function. The reason for this has already been explained in the code comments.
> In addition to the fault injection tests, we also performed a stress test by
> observing the /proc/fs/ext4/XX/orphan_list and the concurrent processes of
> adding and removing orphan nodes, and no issues were found so far.
> 
> 
> In actual production environments, the issue of inconsistency between
> df and du is frequently encountered. In many cases, the cause of the
> problem can be identified through the use of lsof. However, when
> overlayfs is combined with project quota configuration, the issue becomes
> more complex and troublesome to diagnose. First, to determine the project
> ID, one needs to obtain orphaned nodes using `fsck.ext4 -fn /dev/xx`, and
> then retrieve file information through `debugfs`. However, the file names
> cannot always be obtained, and it is often unclear which files they are.
> To identify which files these are, one would need to use crash for online
> debugging or use kprobe to gather information incrementally. However, some
> customers in production environments do not agree to upload any tools, and
> online debugging might impact the business. There are also scenarios where
> files are opened in kernel mode, which do not generate file descriptors(fds),
> making it impossible to identify which files were deleted but still have
> references through lsof. This patchset adds a procfs interface to query
> information about orphaned nodes, which can assist in the analysis and
> localization of such issues.

Ye, did you read my comments to the v1 of the patchset [1]? I didn't see
any reply from you. I don't think this is a good way how to expose orphan
information for a filesystem for reasons I've outlined in that email.

								Honza

[1] https://lore.kernel.org/all/n4sccudy5avcgnkdhc27rzofzoprxqtwhfrlmsh3yyrj6vbc6d@mmu73gmtawkq/

> 
> Ye Bin (4):
>   ext4: register 'orphan_list' procfs
>   ext4: skip cursor node in ext4_orphan_del()
>   ext4: show inode orphan list detail information
>   ext4: show orphan file inode detail info
> 
>  fs/ext4/ext4.h   |   1 +
>  fs/ext4/orphan.c | 326 ++++++++++++++++++++++++++++++++++++++++++++++-
>  fs/ext4/sysfs.c  |   2 +
>  3 files changed, 328 insertions(+), 1 deletion(-)
> 
> -- 
> 2.34.1
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply

* Re: [PATCH 4/6] generic/765: Ignore mkfs warning
From: Ojaswin Mujoo @ 2026-04-15 18:52 UTC (permalink / raw)
  To: Theodore Tso
  Cc: Darrick J. Wong, Zorro Lang, fstests, fdmanana, ritesh.list,
	naohiro.aota, wqu, Disha Goel, linux-ext4
In-Reply-To: <20260413204215.GA5461@macsyma-wired.lan>

On Mon, Apr 13, 2026 at 04:42:15PM -0400, Theodore Tso wrote:
> > > > > > The output can get corrupted with warnings like below because clustersize
> > > > > > more than 16xbs is experimental:
> > > > > > 
> > > > > > + 16 times the block size is considered experimental
> > > > > > 
> > > > > > Hence pipe these to seqres.full to avoid false negatives.
> 
> You could also suppress the warnings using the -q option, for example:
> 
> mke2fs -Fq -t ext4 -O bigalloc,quota -b 4096 -C 131072 /tmp/foo.img 4G
> 
> > > Futher, mke2fs has multiple instances where we print warnings to stderr,
> > > should we go and fix all of them as well?
> > 
> > "stderr" meaning "standard error", I'd say that errors are anything that
> > prohibits the format from completing, and only errors should go there.
> 
> Sure, I'll accept those changes.  But adding -q will allow the test to
> pass using older versions of e2fsprogs, while still allowing stderr to
> go out the expected output.

Okay cool, I'll send the patches.

thanks,
ojaswin

> 
> 					- Ted

^ permalink raw reply

* Re: [RFC PATCH] iomap: add fast read path for small direct I/O
From: Ojaswin Mujoo @ 2026-04-15 19:06 UTC (permalink / raw)
  To: Fengnan Chang
  Cc: brauner, djwong, linux-xfs, linux-fsdevel, linux-ext4, lidiangang,
	Fengnan Chang
In-Reply-To: <20260414122647.15686-1-changfengnan@bytedance.com>

On Tue, Apr 14, 2026 at 08:26:47PM +0800, Fengnan Chang wrote:
> When running 4K random read workloads on high-performance Gen5 NVMe
> SSDs, the software overhead in the iomap direct I/O path
> (__iomap_dio_rw) becomes a significant bottleneck.
> 
> Using io_uring with poll mode for a 4K randread test on a raw block
> device:
> taskset -c 30 ./t/io_uring -p1 -d512 -b4096 -s32 -c32 -F1 -B1 -R1 -X1
> -n1 -P1 /dev/nvme10n1
> Result: ~3.2M IOPS
> 
> Running the exact same workload on ext4 and XFS:
> taskset -c 30 ./t/io_uring -p1 -d512 -b4096 -s32 -c32 -F1 -B1 -R1 -X1
> -n1 -P1 /mnt/testfile
> Result: ~1.9M IOPS

Hi Fengnan, interesting optimization! 
Which test suite are you using here for the io_uring tests? 
> 
> Profiling the ext4 workload reveals that a significant portion of CPU
> time is spent on memory allocation and the iomap state machine
> iteration:
>   5.33%  [kernel]  [k] __iomap_dio_rw
>   3.26%  [kernel]  [k] iomap_iter
>   2.37%  [kernel]  [k] iomap_dio_bio_iter
>   2.35%  [kernel]  [k] kfree
>   1.33%  [kernel]  [k] iomap_dio_complete

Hmm read is usually under a shared lock for inode as well as extent
lookup so we should ideally not be blocking too much there. Can you
share a bit more detailed perf report. I'd be interested to see where
in iomap_iter() are you seeing the regression?
> 
> I attempted several incremental optimizations in the __iomap_dio_rw()
> path to close the gap:
> 1. Allocating the `bio` and `struct iomap_dio` together to avoid a
>    separate kmalloc. However, because `struct iomap_dio` is relatively
>    large and the main path is complex, this yielded almost no
>    performance improvement.
> 2. Reducing unnecessary state resets in the iomap state machine (e.g.,
>    skipping `iomap_iter_reset_iomap` where safe). This provided a ~5%
>    IOPS boost, which is helpful but still falls far short of closing
>    the gap with the raw block device.
> 

<...>

>  
> +static bool iomap_dio_fast_read_enabled = true;
> +
> +struct iomap_dio_fast_read {
> +	struct kiocb	*iocb;
> +	size_t		size;
> +	bool		should_dirty;
> +	struct work_struct	work;
> +	struct bio	bio ____cacheline_aligned_in_smp;

As Christoph pointed out, were you seeing any performance loss due to
not aligning to cacheline? Architectures like powerpc have a 128byte
cacheline and we could end up wasting significant space here.

> +};
> +
> +static struct bio_set iomap_dio_fast_read_pool;
> +
> +static void iomap_dio_fast_read_complete_work(struct work_struct *work)
> +{

<...>

> +
> +static inline bool iomap_dio_fast_read_supported(struct kiocb *iocb,
> +					  struct iov_iter *iter,
> +					  unsigned int dio_flags,
> +					  size_t done_before)
> +{
> +	struct inode *inode = file_inode(iocb->ki_filp);
> +	size_t count = iov_iter_count(iter);
> +	unsigned int alignment;
> +
> +	if (!iomap_dio_fast_read_enabled)
> +		return false;
> +	if (iov_iter_rw(iter) != READ)
> +		return false;
> +
> +	/*
> +	 * Fast read is an optimization for small IO. Filter out large IO early
> +	 * as it's the most common case to fail for typical direct IO workloads.
> +	 */
> +	if (count > inode->i_sb->s_blocksize)
> +		return false;
> +
> +	if (is_sync_kiocb(iocb) || done_before)

Did you try this for sync reads as well? I think we should be seeing
similar benefits with sync reads too. Further, if the fast path helps us
reduce the critical section under inode lock, it could be a good win for
mixed read write workloads.

> +		return false;
> +	if (dio_flags & (IOMAP_DIO_FORCE_WAIT | IOMAP_DIO_BOUNCE))
> +		return false;
> +	if (iocb->ki_pos + count > i_size_read(inode))
> +		return false;
> +	if (IS_ENCRYPTED(inode) || fsverity_active(inode))
> +		return false;
> +
> +	if (count < bdev_logical_block_size(inode->i_sb->s_bdev))
> +		return false;
> +
> +	if (dio_flags & IOMAP_DIO_FSBLOCK_ALIGNED)
> +		alignment = i_blocksize(inode);
> +	else
> +		alignment = bdev_logical_block_size(inode->i_sb->s_bdev);
> +
> +	if ((iocb->ki_pos | count) & (alignment - 1))
> +		return false;
> +
> +	return true;
> +}
> +
> +static ssize_t iomap_dio_fast_read_async(struct kiocb *iocb,

<...>

> +static ssize_t fast_read_enable_store(struct kobject *kobj,
> +				      struct kobj_attribute *attr,
> +				      const char *buf, size_t count)
> +{
> +	bool enable;
> +	int ret;
> +
> +	ret = kstrtobool(buf, &enable);
> +	if (ret)
> +		return ret;
> +
> +	iomap_dio_fast_read_enabled = enable;
> +	return count;
> +}
> +
> +static struct kobj_attribute fast_read_enable_attr =
> +	__ATTR(fast_read_enable, 0644, fast_read_enable_show, fast_read_enable_store);
> +
> +static struct kobject *iomap_kobj;
> +
> +static int __init iomap_dio_sysfs_init(void)

Since we do more than sysfs work here, maybe we can have a more generic
name like iomap_dio_init(void) or iomap_dio_fast/simple_read_init().


> +{
> +	int ret;
> +
> +	ret = bioset_init(&iomap_dio_fast_read_pool, 4,
> +			  offsetof(struct iomap_dio_fast_read, bio),
> +			  BIOSET_NEED_BVECS | BIOSET_PERCPU_CACHE);
> +	if (ret)
> +		return ret;
> +
> +	iomap_kobj = kobject_create_and_add("iomap", fs_kobj);
> +	if (!iomap_kobj) {
> +		bioset_exit(&iomap_dio_fast_read_pool);
> +		return -ENOMEM;
> +	}
> +
> +	if (sysfs_create_file(iomap_kobj, &fast_read_enable_attr.attr)) {
> +		kobject_put(iomap_kobj);
> +		bioset_exit(&iomap_dio_fast_read_pool);
> +		return -ENOMEM;
> +	}
> +
> +	return 0;
> +}
> +fs_initcall(iomap_dio_sysfs_init);
> -- 

Regards,
ojaswin

> 2.39.5 (Apple Git-154)
> 

^ permalink raw reply

* Re: [PATCH v1] ext4: add mb_stats_clear for mballoc statistics
From: Ojaswin Mujoo @ 2026-04-15 19:26 UTC (permalink / raw)
  To: Baolin Liu
  Cc: tytso, adilger.kernel, linux-ext4, linux-kernel, wangguanyu,
	Baolin Liu
In-Reply-To: <20260414100212.95209-1-liubaolin12138@163.com>

On Tue, Apr 14, 2026 at 06:02:11PM +0800, Baolin Liu wrote:
> From: Baolin Liu <liubaolin@kylinos.cn>
> 
> Add a write-only mb_stats_clear sysfs knob to reset ext4 mballoc
> runtime statistics.This makes it easier to inspect allocator
> activity for a specific workload instead of using counters
> accumulated since mount.
> 
> Signed-off-by: Baolin Liu <liubaolin@kylinos.cn>

The patch looks good to me Baolin. We just need to add documentation of
this to the Documentation/ABI/testing/sysfs-fs-ext4 file so that the
users know what it is and the fact that the only value we allow to write
is 1. 

Regards,
ojaswin


^ permalink raw reply

* Re: [PATCH v2 2/4] ext4: skip cursor node in ext4_orphan_del()
From: Darrick J. Wong @ 2026-04-15 23:56 UTC (permalink / raw)
  To: Ye Bin; +Cc: tytso, adilger.kernel, linux-ext4, jack
In-Reply-To: <20260415105505.342358-3-yebin@huaweicloud.com>

On Wed, Apr 15, 2026 at 06:55:03PM +0800, Ye Bin wrote:
> From: Ye Bin <yebin10@huawei.com>
> 
> This patch is prepared for displaying orphan_list information. Because
> temporary nodes may be inserted when the orphan_list is traversed and
> displayed, these temporary nodes need to be skipped.
> 
> Signed-off-by: Ye Bin <yebin10@huawei.com>
> ---
>  fs/ext4/orphan.c | 20 +++++++++++++++++++-
>  1 file changed, 19 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/ext4/orphan.c b/fs/ext4/orphan.c
> index f7e7f77e021e..a6bffe67ef75 100644
> --- a/fs/ext4/orphan.c
> +++ b/fs/ext4/orphan.c
> @@ -220,6 +220,23 @@ static int ext4_orphan_file_del(handle_t *handle, struct inode *inode)
>  	return ret;
>  }
>  
> +static inline bool ext4_is_cursor(struct inode *inode)
> +{
> +	return (inode->i_ino == 0);
> +}
> +
> +static inline struct list_head *ext4_orphan_prev_node(
> +					struct ext4_inode_info *pos,
> +					struct list_head *head)
> +{
> +	list_for_each_entry_continue_reverse(pos, head, i_orphan) {
> +		if (likely(!ext4_is_cursor(&pos->vfs_inode)))
> +			return &pos->i_orphan;
> +	}
> +
> +	return head;

Waitaminute, you inject the procfs file's cursor into the orphan list
with a phony ext4_inode_info??  That sounds like a landmine waiting to
go off the next time someone writes code that traverses the list, or
even wants to check that its non-empty.

--D

> +}
> +
>  /*
>   * ext4_orphan_del() removes an unlinked or truncated inode from the list
>   * of such inodes stored on disk, because it is finally being cleaned up.
> @@ -253,7 +270,8 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
>  	mutex_lock(&sbi->s_orphan_lock);
>  	ext4_debug("remove inode %llu from orphan list\n", inode->i_ino);
>  
> -	prev = ei->i_orphan.prev;
> +	prev = ext4_orphan_prev_node(ei, &sbi->s_orphan);
> +
>  	list_del_init(&ei->i_orphan);
>  
>  	/* If we're on an error path, we may not have a valid
> -- 
> 2.34.1
> 
> 

^ permalink raw reply

* Re: [PATCH v1] ext4: add mb_stats_clear for mballoc statistics
From: Andreas Dilger @ 2026-04-16  1:14 UTC (permalink / raw)
  To: Baolin Liu; +Cc: tytso, linux-ext4, linux-kernel, wangguanyu, Baolin Liu
In-Reply-To: <20260414100212.95209-1-liubaolin12138@163.com>

On Apr 14, 2026, at 04:02, Baolin Liu <liubaolin12138@163.com> wrote:
> 
> From: Baolin Liu <liubaolin@kylinos.cn>
> 
> Add a write-only mb_stats_clear sysfs knob to reset ext4 mballoc
> runtime statistics. This makes it easier to inspect allocator
> activity for a specific workload instead of using counters
> accumulated since mount.

Rather than having a read-only "mb_stats" procfs file and a separate
write-only "mb_stats_clear" sysfs file to clear "mb_stats", IMHO it
would be more obvious to write directly to "/proc/fs/ext4/DEV/mb_stats"
file to clear it.  Writing "0" would be logical to zero out the stats.

Cheers, Andreas

> 
> Signed-off-by: Baolin Liu <liubaolin@kylinos.cn>
> ---
> fs/ext4/ext4.h    |  1 +
> fs/ext4/mballoc.c | 31 +++++++++++++++++++++++++++++++
> fs/ext4/sysfs.c   | 24 ++++++++++++++++++++++++
> 3 files changed, 56 insertions(+)
> 
> diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
> index 7617e2d454ea..3a32e1a515dd 100644
> --- a/fs/ext4/ext4.h
> +++ b/fs/ext4/ext4.h
> @@ -2995,6 +2995,7 @@ int ext4_fc_record_regions(struct super_block *sb, int ino,
> extern const struct seq_operations ext4_mb_seq_groups_ops;
> extern const struct seq_operations ext4_mb_seq_structs_summary_ops;
> extern int ext4_seq_mb_stats_show(struct seq_file *seq, void *offset);
> +extern void ext4_mb_stats_clear(struct ext4_sb_info *sbi);
> extern int ext4_mb_init(struct super_block *);
> extern void ext4_mb_release(struct super_block *);
> extern ext4_fsblk_t ext4_mb_new_blocks(handle_t *,
> diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
> index bb58eafb87bc..382c91586b26 100644
> --- a/fs/ext4/mballoc.c
> +++ b/fs/ext4/mballoc.c
> @@ -3219,6 +3219,8 @@ int ext4_seq_mb_stats_show(struct seq_file *seq, void *offset)
> }
> seq_printf(seq, "\treqs: %u\n", atomic_read(&sbi->s_bal_reqs));
> seq_printf(seq, "\tsuccess: %u\n", atomic_read(&sbi->s_bal_success));
> + seq_printf(seq, "\tblocks_allocated: %u\n",
> +   atomic_read(&sbi->s_bal_allocated));
> 
> seq_printf(seq, "\tgroups_scanned: %u\n",
>   atomic_read(&sbi->s_bal_groups_scanned));
> @@ -4721,6 +4723,35 @@ static void ext4_mb_collect_stats(struct ext4_allocation_context *ac)
> trace_ext4_mballoc_prealloc(ac);
> }
> 
> +void ext4_mb_stats_clear(struct ext4_sb_info *sbi)
> +{
> + int i;
> +
> + atomic_set(&sbi->s_bal_reqs, 0);
> + atomic_set(&sbi->s_bal_success, 0);
> + atomic_set(&sbi->s_bal_allocated, 0);
> + atomic_set(&sbi->s_bal_groups_scanned, 0);
> +
> + for (i = 0; i < EXT4_MB_NUM_CRS; i++) {
> + atomic64_set(&sbi->s_bal_cX_hits[i], 0);
> + atomic64_set(&sbi->s_bal_cX_groups_considered[i], 0);
> + atomic_set(&sbi->s_bal_cX_ex_scanned[i], 0);
> + atomic64_set(&sbi->s_bal_cX_failed[i], 0);
> + }
> +
> + atomic_set(&sbi->s_bal_ex_scanned, 0);
> + atomic_set(&sbi->s_bal_goals, 0);
> + atomic_set(&sbi->s_bal_stream_goals, 0);
> + atomic_set(&sbi->s_bal_len_goals, 0);
> + atomic_set(&sbi->s_bal_2orders, 0);
> + atomic_set(&sbi->s_bal_breaks, 0);
> + atomic_set(&sbi->s_mb_lost_chunks, 0);
> + atomic_set(&sbi->s_mb_buddies_generated, 0);
> + atomic64_set(&sbi->s_mb_generation_time, 0);
> + atomic_set(&sbi->s_mb_preallocated, 0);
> + atomic_set(&sbi->s_mb_discarded, 0);
> +}
> +
> /*
>  * Called on failure; free up any blocks from the inode PA for this
>  * context.  We don't need this for MB_GROUP_PA because we only change
> diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c
> index 923b375e017f..a5bd88a99f22 100644
> --- a/fs/ext4/sysfs.c
> +++ b/fs/ext4/sysfs.c
> @@ -41,6 +41,7 @@ typedef enum {
> attr_pointer_atomic,
> attr_journal_task,
> attr_err_report_sec,
> + attr_mb_stats_clear,
> } attr_id_t;
> 
> typedef enum {
> @@ -161,6 +162,25 @@ static ssize_t err_report_sec_store(struct ext4_sb_info *sbi,
> return count;
> }
> 
> +static ssize_t mb_stats_clear_store(struct ext4_sb_info *sbi,
> +    const char *buf, size_t count)
> +{
> + int val;
> + int ret;
> +
> + if (!capable(CAP_SYS_ADMIN))
> + return -EPERM;
> +
> + ret = kstrtoint(skip_spaces(buf), 0, &val);
> + if (ret)
> + return ret;
> + if (val != 1)
> + return -EINVAL;
> +
> + ext4_mb_stats_clear(sbi);
> + return count;
> +}
> +
> static ssize_t journal_task_show(struct ext4_sb_info *sbi, char *buf)
> {
> if (!sbi->s_journal)
> @@ -251,6 +271,7 @@ EXT4_ATTR_OFFSET(mb_best_avail_max_trim_order, 0644, mb_order,
> EXT4_ATTR_OFFSET(err_report_sec, 0644, err_report_sec, ext4_sb_info, s_err_report_sec);
> EXT4_RW_ATTR_SBI_UI(inode_goal, s_inode_goal);
> EXT4_RW_ATTR_SBI_UI(mb_stats, s_mb_stats);
> +EXT4_ATTR(mb_stats_clear, 0200, mb_stats_clear);
> EXT4_RW_ATTR_SBI_UI(mb_max_to_scan, s_mb_max_to_scan);
> EXT4_RW_ATTR_SBI_UI(mb_min_to_scan, s_mb_min_to_scan);
> EXT4_RW_ATTR_SBI_UI(mb_order2_req, s_mb_order2_reqs);
> @@ -301,6 +322,7 @@ static struct attribute *ext4_attrs[] = {
> ATTR_LIST(inode_readahead_blks),
> ATTR_LIST(inode_goal),
> ATTR_LIST(mb_stats),
> + ATTR_LIST(mb_stats_clear),
> ATTR_LIST(mb_max_to_scan),
> ATTR_LIST(mb_min_to_scan),
> ATTR_LIST(mb_order2_req),
> @@ -561,6 +583,8 @@ static ssize_t ext4_attr_store(struct kobject *kobj,
> return trigger_test_error(sbi, buf, len);
> case attr_err_report_sec:
> return err_report_sec_store(sbi, buf, len);
> + case attr_mb_stats_clear:
> + return mb_stats_clear_store(sbi, buf, len);
> default:
> return ext4_generic_attr_store(a, sbi, buf, len);
> }
> -- 
> 2.51.0
> 


Cheers, Andreas






^ permalink raw reply

* Re: [PATCH] jbd2: enforce power-of-two default revoke hash size at compile time
From: Andreas Dilger @ 2026-04-16  1:35 UTC (permalink / raw)
  To: Jan Kara; +Cc: Milos Nikic, tytso, linux-ext4, linux-kernel
In-Reply-To: <cjtirtqozud4keiu2fqi6sj3o4moimloti7celc4y44eejsn2y@i2tz72chmm34>

On Apr 14, 2026, at 06:59, Jan Kara <jack@suse.cz> wrote:
> 
> On Mon 13-04-26 14:27:24, Milos Nikic wrote:
>> The jbd2 revoke table relies on bitwise AND operations for fast hash
>> indexing, which requires the hash table size to be a strict power of two.
>> 
>> Currently, this requirement is only enforced at runtime via a J_ASSERT
>> in jbd2_journal_init_revoke(). While this successfully catches invalid
>> dynamic allocations, it means a developer accidentally modifying the
>> hardcoded JOURNAL_REVOKE_DEFAULT_HASH macro will experience a system
>> panic upon mounting the filesystem during testing.
>> 
>> Add a BUILD_BUG_ON() in journal_init_common() to validate the default
>> macro at compile time. This acts as an immediate, zero-overhead
>> safeguard, preventing compilation entirely if the default hash size is
>> mathematically invalid.
>> 
>> Signed-off-by: Milos Nikic <nikic.milos@gmail.com>
> 
> Eh, if you modify JOURNAL_REVOKE_DEFAULT_HASH you should better know what
> you are doing and if you mess up, then the kernel failing with assertion
> isn't that difficult to diagnose. So sorry I don't think this "cleanup" is
> useful either.

Jan,
this is a BUILD_BUG_ON() so it won't cause any runtime assertion.

Cheers, Andreas 

> Honza
> 
>> ---
>> fs/jbd2/journal.c | 1 +
>> 1 file changed, 1 insertion(+)
>> 
>> diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
>> index 4f397fcdb13c..62b36a2fc4e2 100644
>> --- a/fs/jbd2/journal.c
>> +++ b/fs/jbd2/journal.c
>> @@ -1565,6 +1565,7 @@ static journal_t *journal_init_common(struct 
>>  	/* The journal is marked for error until we succeed with recovery! */
>>  	journal->j_flags = JBD2_ABORT;
>> 
>> +	BUILD_BUG_ON(!is_power_of_2(JOURNAL_REVOKE_DEFAULT_HASH));
>>  	/* Set up a default-sized revoke table for the new mount. */
>>  	err = jbd2_journal_init_revoke(journal, JOURNAL_REVOKE_DEFAULT_HASH);
>>  	if (err)
>> -- 
>> 2.53.0
>> 
> -- 
> Jan Kara <jack@suse.com>
> SUSE Labs, CR
> 


Cheers, Andreas






^ permalink raw reply

* Re: [PATCH v1] ext4: add mb_stats_clear for mballoc statistics
From: Ritesh Harjani @ 2026-04-16  1:44 UTC (permalink / raw)
  To: Baolin Liu, tytso, adilger.kernel
  Cc: liubaolin12138, linux-ext4, linux-kernel, wangguanyu, Baolin Liu
In-Reply-To: <20260414100212.95209-1-liubaolin12138@163.com>

Baolin Liu <liubaolin12138@163.com> writes:

> From: Baolin Liu <liubaolin@kylinos.cn>
>
> Add a write-only mb_stats_clear sysfs knob to reset ext4 mballoc
> runtime statistics.This makes it easier to inspect allocator
> activity for a specific workload instead of using counters
> accumulated since mount.
>
> Signed-off-by: Baolin Liu <liubaolin@kylinos.cn>

Make sense to me. The changes looks good and works fine at my end.
So please feel free to add:

Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>

^ permalink raw reply

* [PATCH] iomap: avoid memset iomap when iter is done
From: Fengnan Chang @ 2026-04-16  3:06 UTC (permalink / raw)
  To: brauner, djwong, hch, linux-xfs, linux-fsdevel, linux-ext4
  Cc: lidiangang, Fengnan Chang

When iomap_iter() finishes its iteration (returns <= 0), it is no longer
necessary to memset the entire iomap and srcmap structures.

In high-IOPS scenarios (like 4k randread NVMe polling with io_uring),
where the majority of I/Os complete in a single extent map, this wasted
memory write bandwidth, as the caller will just discard the iterator.

Use this command to test:
taskset -c 30 ./t/io_uring -p1 -d512 -b4096 -s32 -c32 -F1 -B1 -R1 -X1
-n1 -P1 /mnt/testfile
IOPS improve about 5% on ext4 and XFS.

However, we MUST still call iomap_iter_reset_iomap() to release the
folio_batch if IOMAP_F_FOLIO_BATCH is set, otherwise we leak page
references. Therefore, split the cleanup logic: always release the
folio_batch, but skip the memset() when ret <= 0.

Signed-off-by: Fengnan Chang <changfengnan@bytedance.com>
---
 fs/iomap/iter.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/fs/iomap/iter.c b/fs/iomap/iter.c
index c04796f6e57f..91eb5e6165ff 100644
--- a/fs/iomap/iter.c
+++ b/fs/iomap/iter.c
@@ -15,8 +15,6 @@ static inline void iomap_iter_reset_iomap(struct iomap_iter *iter)
 	}
 
 	iter->status = 0;
-	memset(&iter->iomap, 0, sizeof(iter->iomap));
-	memset(&iter->srcmap, 0, sizeof(iter->srcmap));
 }
 
 /* Advance the current iterator position and decrement the remaining length */
@@ -106,6 +104,9 @@ int iomap_iter(struct iomap_iter *iter, const struct iomap_ops *ops)
 	if (ret <= 0)
 		return ret;
 
+	memset(&iter->iomap, 0, sizeof(iter->iomap));
+	memset(&iter->srcmap, 0, sizeof(iter->srcmap));
+
 begin:
 	ret = ops->iomap_begin(iter->inode, iter->pos, iter->len, iter->flags,
 			       &iter->iomap, &iter->srcmap);
-- 
2.39.5 (Apple Git-154)


^ permalink raw reply related

* Re: [RFC PATCH] iomap: add fast read path for small direct I/O
From: changfengnan @ 2026-04-16  3:16 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Fengnan Chang, brauner, djwong, linux-xfs, linux-fsdevel,
	linux-ext4, lidiangang
In-Reply-To: <ad867C8dlaQGLS97@infradead.org>


> From: "Christoph Hellwig"<hch@infradead.org>
> Date:  Wed, Apr 15, 2026, 15:15
> Subject:  Re: [RFC PATCH] iomap: add fast read path for small direct I/O
> To: "Fengnan Chang"<fengnanchang@gmail.com>
> Cc: <brauner@kernel.org>, <djwong@kernel.org>, <linux-xfs@vger.kernel.org>, <linux-fsdevel@vger.kernel.org>, <linux-ext4@vger.kernel.org>, <lidiangang@bytedance.com>, "Fengnan Chang"<changfengnan@bytedance.com>
> On Tue, Apr 14, 2026 at 08:26:47PM +0800, Fengnan Chang wrote:
> > 1. Allocating the `bio` and `struct iomap_dio` together to avoid a
> >    separate kmalloc. However, because `struct iomap_dio` is relatively
> >    large and the main path is complex, this yielded almost no
> >    performance improvement.
> 
> One interesting bit here would be a slab for struct iomap_dio, and
> the previously discussed per-cpu allocation of some form.
Hi Christoph:
Thank you for your thorough review; it has given me greater confidence
that we are on the right path. This patch still needs a lot of work to be
perfected,  I hope it will be worth it.
Yes, but use a new slab for struct iomap_dio doesn't help.

> 
> > 2. Reducing unnecessary state resets in the iomap state machine (e.g.,
> >    skipping `iomap_iter_reset_iomap` where safe). This provided a ~5%
> >    IOPS boost, which is helpful but still falls far short of closing
> >    the gap with the raw block device.
> 
> But it already is a major improvement, and one that would apply outside
> of narrow special cases.  So I'd really like to see that patch.
You can see this in:
https://lore.kernel.org/linux-fsdevel/20260416030642.26744-1-changfengnan@bytedance.com/T/#u
> 
> > The fast path is triggered when the request satisfies:
> > - Asynchronous READ request only for now.
> 
> I think you really should handle synchronous reads as well.
I'll include support for it in the next version.
> 
> > - I/O size is <= inode blocksize (fits in a single block, no splits).
> 
> Makes sense, and I suspect this is the main source of speedups.
> 
> > - Aligned to the block device's logical block size.
> 
> All direct I/O requires this.
> 
> > - No bounce buffering, fscrypt, or fsverity involved.
> > - No custom `iomap_dio_ops` (dops) registered by the filesystem.
> 
> I'm really curious at what difference this makes.  It removes a few
> branches, but should not have much of an effect while limiting the
> applicability a lot.
Yes, the impact shouldn’t be significant. 
Since this is just a RFC version to confirm that I’m on the right path, there
are many aspects that haven’t been fully thought through yet. I haven’t
tested these scenarios yet, but I’ll add support for them later to
check  exactly what the impact is.
> 
> > After this optimization, the heavy generic functions disappear from the
> > profile, replaced by a single streamlined execution path:
> >   4.83%  [kernel]  [k] iomap_dio_fast_read_async.isra.31
> > 
> > With this patch, 4K random read IOPS on ext4 increases from 1.9M to
> > 2.3M.
> 
> That is still a lot slower than the block device path.  A big part of
> it should be the extent lookup and locking associated with it, but
> I'd expect things to be a bit better.  Do you have XFS version as well?
Yes, still a lot slower, I believe the other reason is due to the lookup of
the extent mapping.
XFS and ext4 perform similarly, 1.92M IOPS to 2.32M IOPS. 

> 
> > However, I am submitting this patch to validate whether this
> > optimization direction is correct and worth pursuing. I would appreciate
> > feedback on how to better integrate these ideas into the main iomap
> > execution path.
> 
> I think a <= block size fast path makes a lot of sense, just like we
> have a simple version on the block device, but it needs more work.
Agree, I came up with this patch after being inspired by the way block
devices are handled. 

> 
> > +struct iomap_dio_fast_read {
> > +        struct kiocb        *iocb;
> > +        size_t                size;
> > +        bool                should_dirty;
> > +        struct work_struct        work;
> > +        struct bio        bio ____cacheline_aligned_in_smp;
> 
> Does the cache line alignment matter here?  If yes, can you explain why
> in a comment?

I copy this from struct blkdev_dio , I'll do some test to verfiy. 
> 
> > +static struct bio_set iomap_dio_fast_read_pool;
> 
> In general I'd prefer to stick to simple as in the block device version
> instead of fast.

Simple is better name.
> 
> > +static void iomap_dio_fast_read_complete_work(struct work_struct *work)
> > +{
> > +        struct iomap_dio_fast_read *fr =
> > +                container_of(work, struct iomap_dio_fast_read, work);
> > +        struct kiocb *iocb = fr->iocb;
> > +        struct inode *inode = file_inode(iocb->ki_filp);
> > +        bool should_dirty = fr->should_dirty;
> > +        struct bio *bio = &fr->bio;
> > +        ssize_t ret;
> > +
> > +        WRITE_ONCE(iocb->private, NULL);
> > +
> > +        if (likely(!bio->bi_status)) {
> > +                ret = fr->size;
> > +                iocb->ki_pos += ret;
> > +        } else {
> > +                ret = blk_status_to_errno(bio->bi_status);
> > +                fserror_report_io(inode, FSERR_DIRECTIO_READ, iocb->ki_pos,
> > +                                  fr->size, ret, GFP_NOFS);
> > +        }
> > +
> > +        if (should_dirty) {
> > +                bio_check_pages_dirty(bio);
> > +        } else {
> > +                bio_release_pages(bio, false);
> > +                bio_put(bio);
> > +        }
> > +
> > +        inode_dio_end(inode);
> > +
> > +        trace_iomap_dio_complete(iocb, ret < 0 ? ret : 0, ret > 0 ? ret : 0);
> > +        iocb->ki_complete(iocb, ret);
> 
> This is a lot of duplicate cork.  Can we somehow share it by passing
> more arguments or embedding the simple context into the bigger one?

I'll try. There are still many issues below, which I will address in the next version.
> 
> > +static inline bool iomap_dio_fast_read_supported(struct kiocb *iocb,
> > +                                          struct iov_iter *iter,
> > +                                          unsigned int dio_flags,
> > +                                          size_t done_before)
> 
> Please stick to two-tab indents for prototype continuations, which is
> both more readable and easier to modify later.
Get.
> 
> > +        if (count < bdev_logical_block_size(inode->i_sb->s_bdev))
> > +                return false;
> 
> Sub-sector reads (unlike writes) don't require any special handling, so
> I don't see why they are excluded.
Agree, Sub-sector reads can handle too.

> 
> > +        if (dio_flags & IOMAP_DIO_FSBLOCK_ALIGNED)
> > +                alignment = i_blocksize(inode);
> > +        else
> > +                alignment = bdev_logical_block_size(inode->i_sb->s_bdev);
> > +
> > +        if ((iocb->ki_pos | count) & (alignment - 1))
> > +                return false;
> 
> Factor this into a helper?
Get.
> 
> > +        inode_dio_begin(inode);
> > +
> > +        ret = ops->iomap_begin(inode, iomi.pos, count, iomi.flags,
> > +                               &iomi.iomap, &iomi.srcmap);
> > +        if (ret) {
> > +                inode_dio_end(inode);
> > +                return ret;
> > +        }
> 
> If we can I'd much prefer avoiding the open coded iomap_begin
> invocation, as that is a real maintenance burden.
It seems we need introduce a new helper to do this.

> 
> > +
> > +        if (iomi.iomap.type != IOMAP_MAPPED ||
> > +            iomi.iomap.offset > iomi.pos ||
> > +            iomi.iomap.offset + iomi.iomap.length < iomi.pos + count ||
> > +            (iomi.iomap.flags & IOMAP_F_ANON_WRITE)) {
> 
> IOMAP_F_ANON_WRITE (as the name implies) only applies to writes.
> 
> > +                ret = -EAGAIN;
> 
> -EAGAIN is a bad status code, as we already use to indicate that a
> non-blocking read blocks.
Agree.

> 
> > +        ret = bio_iov_iter_get_pages(bio, iter,
> > +                                     bdev_logical_block_size(iomi.iomap.bdev) - 1);
> 
> Overly long line.  Also this needs to use the calculated alignment
> value.
Get.
> 
> > +        if (unlikely(ret)) {
> > +                bio_put(bio);
> > +                goto out_iomap_end;
> > +        }
> > +
> > +        if (bio->bi_iter.bi_size != count) {
> > +                iov_iter_revert(iter, bio->bi_iter.bi_size);
> > +                bio_release_pages(bio, false);
> > +                bio_put(bio);
> > +                ret = -EAGAIN;
> > +                goto out_iomap_end;
> > +        }
> 
> Share the bio_put with a new goto label, and maybe also move all
> the other cleanup code out of the main path into a label?
Get.
> 
> > +        if (!dops && iomap_dio_fast_read_supported(iocb, iter, dio_flags, done_before)) {
> 
> Overly long line.  But we should not make the fast path conditional
> on an option anyway.
Get.

^ permalink raw reply

* Re: [RFC PATCH] iomap: add fast read path for small direct I/O
From: changfengnan @ 2026-04-16  3:22 UTC (permalink / raw)
  To: Ojaswin Mujoo
  Cc: Fengnan Chang, brauner, djwong, linux-xfs, linux-fsdevel,
	linux-ext4, lidiangang
In-Reply-To: <ad_h0JMX2Jo-QODG@li-dc0c254c-257c-11b2-a85c-98b6c1322444.ibm.com>

[-- Attachment #1: Type: text/plain, Size: 8463 bytes --]


> From: "Ojaswin Mujoo"<ojaswin@linux.ibm.com>
> Date:  Thu, Apr 16, 2026, 03:07
> Subject:  Re: [RFC PATCH] iomap: add fast read path for small direct I/O
> To: "Fengnan Chang"<fengnanchang@gmail.com>
> Cc: <brauner@kernel.org>, <djwong@kernel.org>, <linux-xfs@vger.kernel.org>, <linux-fsdevel@vger.kernel.org>, <linux-ext4@vger.kernel.org>, <lidiangang@bytedance.com>, "Fengnan Chang"<changfengnan@bytedance.com>
> On Tue, Apr 14, 2026 at 08:26:47PM +0800, Fengnan Chang wrote:
> > When running 4K random read workloads on high-performance Gen5 NVMe
> > SSDs, the software overhead in the iomap direct I/O path
> > (__iomap_dio_rw) becomes a significant bottleneck.
> > 
> > Using io_uring with poll mode for a 4K randread test on a raw block
> > device:
> > taskset -c 30 ./t/io_uring -p1 -d512 -b4096 -s32 -c32 -F1 -B1 -R1 -X1
> > -n1 -P1 /dev/nvme10n1
> > Result: ~3.2M IOPS
> > 
> > Running the exact same workload on ext4 and XFS:
> > taskset -c 30 ./t/io_uring -p1 -d512 -b4096 -s32 -c32 -F1 -B1 -R1 -X1
> > -n1 -P1 /mnt/testfile
> > Result: ~1.9M IOPS
> 
> Hi Fengnan, interesting optimization! 
> Which test suite are you using here for the io_uring tests? 
This is test 4k randread with QD 512 in io_uring poll mode. 
If you use fio, almost like this, but ./t/io_uring  can get higher IOPS.
fio \
  --name=io_uring_test \
  --ioengine=io_uring \
  --filename=/mnt/testfile \
  --direct=1 \
  --rw=randread \
  --bs=4096 \
  --iodepth=512 \
  --iodepth_batch_submit=32 \
  --iodepth_batch_complete_min=32 \
  --hipri=1 \
  --fixedbufs=1 \
  --registerfiles=1 \
  --nonvectored=1 \
  --sqthread_poll=1

> > 
> > Profiling the ext4 workload reveals that a significant portion of CPU
> > time is spent on memory allocation and the iomap state machine
> > iteration:
> >   5.33%  [kernel]  [k] __iomap_dio_rw
> >   3.26%  [kernel]  [k] iomap_iter
> >   2.37%  [kernel]  [k] iomap_dio_bio_iter
> >   2.35%  [kernel]  [k] kfree
> >   1.33%  [kernel]  [k] iomap_dio_complete
> 
> Hmm read is usually under a shared lock for inode as well as extent
> lookup so we should ideally not be blocking too much there. Can you
> share a bit more detailed perf report. I'd be interested to see where
> in iomap_iter() are you seeing the regression?
Are there enough images of the flame diagram? I’ve attached them.
ext4_poll_7.svg is without this patch, iomap_fast.svg is with this patch.

> > 
> > I attempted several incremental optimizations in the __iomap_dio_rw()
> > path to close the gap:
> > 1. Allocating the `bio` and `struct iomap_dio` together to avoid a
> >    separate kmalloc. However, because `struct iomap_dio` is relatively
> >    large and the main path is complex, this yielded almost no
> >    performance improvement.
> > 2. Reducing unnecessary state resets in the iomap state machine (e.g.,
> >    skipping `iomap_iter_reset_iomap` where safe). This provided a ~5%
> >    IOPS boost, which is helpful but still falls far short of closing
> >    the gap with the raw block device.
> > 
> 
> <...>
> 
> >  
> > +static bool iomap_dio_fast_read_enabled = true;
> > +
> > +struct iomap_dio_fast_read {
> > +        struct kiocb        *iocb;
> > +        size_t                size;
> > +        bool                should_dirty;
> > +        struct work_struct        work;
> > +        struct bio        bio ____cacheline_aligned_in_smp;
> 
> As Christoph pointed out, were you seeing any performance loss due to
> not aligning to cacheline? Architectures like powerpc have a 128byte
> cacheline and we could end up wasting significant space here.
Get your point. I'll check.

> 
> > +};
> > +
> > +static struct bio_set iomap_dio_fast_read_pool;
> > +
> > +static void iomap_dio_fast_read_complete_work(struct work_struct *work)
> > +{
> 
> <...>
> 
> > +
> > +static inline bool iomap_dio_fast_read_supported(struct kiocb *iocb,
> > +                                          struct iov_iter *iter,
> > +                                          unsigned int dio_flags,
> > +                                          size_t done_before)
> > +{
> > +        struct inode *inode = file_inode(iocb->ki_filp);
> > +        size_t count = iov_iter_count(iter);
> > +        unsigned int alignment;
> > +
> > +        if (!iomap_dio_fast_read_enabled)
> > +                return false;
> > +        if (iov_iter_rw(iter) != READ)
> > +                return false;
> > +
> > +        /*
> > +         * Fast read is an optimization for small IO. Filter out large IO early
> > +         * as it's the most common case to fail for typical direct IO workloads.
> > +         */
> > +        if (count > inode->i_sb->s_blocksize)
> > +                return false;
> > +
> > +        if (is_sync_kiocb(iocb) || done_before)
> 
> Did you try this for sync reads as well? I think we should be seeing
> similar benefits with sync reads too. Further, if the fast path helps us
> reduce the critical section under inode lock, it could be a good win for
> mixed read write workloads.
Get. sync read will support in next version.
> 
> > +                return false;
> > +        if (dio_flags & (IOMAP_DIO_FORCE_WAIT | IOMAP_DIO_BOUNCE))
> > +                return false;
> > +        if (iocb->ki_pos + count > i_size_read(inode))
> > +                return false;
> > +        if (IS_ENCRYPTED(inode) || fsverity_active(inode))
> > +                return false;
> > +
> > +        if (count < bdev_logical_block_size(inode->i_sb->s_bdev))
> > +                return false;
> > +
> > +        if (dio_flags & IOMAP_DIO_FSBLOCK_ALIGNED)
> > +                alignment = i_blocksize(inode);
> > +        else
> > +                alignment = bdev_logical_block_size(inode->i_sb->s_bdev);
> > +
> > +        if ((iocb->ki_pos | count) & (alignment - 1))
> > +                return false;
> > +
> > +        return true;
> > +}
> > +
> > +static ssize_t iomap_dio_fast_read_async(struct kiocb *iocb,
> 
> <...>
> 
> > +static ssize_t fast_read_enable_store(struct kobject *kobj,
> > +                                      struct kobj_attribute *attr,
> > +                                      const char *buf, size_t count)
> > +{
> > +        bool enable;
> > +        int ret;
> > +
> > +        ret = kstrtobool(buf, &enable);
> > +        if (ret)
> > +                return ret;
> > +
> > +        iomap_dio_fast_read_enabled = enable;
> > +        return count;
> > +}
> > +
> > +static struct kobj_attribute fast_read_enable_attr =
> > +        __ATTR(fast_read_enable, 0644, fast_read_enable_show, fast_read_enable_store);
> > +
> > +static struct kobject *iomap_kobj;
> > +
> > +static int __init iomap_dio_sysfs_init(void)
> 
> Since we do more than sysfs work here, maybe we can have a more generic
> name like iomap_dio_init(void) or iomap_dio_fast/simple_read_init().
Sounds good.

> 
> 
> > +{
> > +        int ret;
> > +
> > +        ret = bioset_init(&iomap_dio_fast_read_pool, 4,
> > +                          offsetof(struct iomap_dio_fast_read, bio),
> > +                          BIOSET_NEED_BVECS | BIOSET_PERCPU_CACHE);
> > +        if (ret)
> > +                return ret;
> > +
> > +        iomap_kobj = kobject_create_and_add("iomap", fs_kobj);
> > +        if (!iomap_kobj) {
> > +                bioset_exit(&iomap_dio_fast_read_pool);
> > +                return -ENOMEM;
> > +        }
> > +
> > +        if (sysfs_create_file(iomap_kobj, &fast_read_enable_attr.attr)) {
> > +                kobject_put(iomap_kobj);
> > +                bioset_exit(&iomap_dio_fast_read_pool);
> > +                return -ENOMEM;
> > +        }
> > +
> > +        return 0;
> > +}
> > +fs_initcall(iomap_dio_sysfs_init);
> > -- 
> 
> Regards,
> ojaswin
> 
> > 2.39.5 (Apple Git-154)
> >
> 

[-- Attachment #2: ext4_poll_7.svg --]
[-- Type: application/octet-stream, Size: 78314 bytes --]

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" width="1200" height="2134" onload="init(evt)" viewBox="0 0 1200 2134" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Flame graph stack visualization. See https://github.com/brendangregg/FlameGraph for latest version, and http://www.brendangregg.com/flamegraphs.html for examples. -->
<!-- NOTES:  -->
<defs>
	<linearGradient id="background" y1="0" y2="1" x1="0" x2="0" >
		<stop stop-color="#eeeeee" offset="5%" />
		<stop stop-color="#eeeeb0" offset="95%" />
	</linearGradient>
</defs>
<style type="text/css">
	text { font-family:Verdana; font-size:12px; fill:rgb(0,0,0); }
	#search, #ignorecase { opacity:0.1; cursor:pointer; }
	#search:hover, #search.show, #ignorecase:hover, #ignorecase.show { opacity:1; }
	#subtitle { text-anchor:middle; font-color:rgb(160,160,160); }
	#title { text-anchor:middle; font-size:17px}
	#unzoom { cursor:pointer; }
	#frames > *:hover { stroke:black; stroke-width:0.5; cursor:pointer; }
	.hide { display:none; }
	.parent { opacity:0.5; }
</style>
<script type="text/ecmascript">
<![CDATA[
	"use strict";
	var details, searchbtn, unzoombtn, matchedtxt, svg, searching, currentSearchTerm, ignorecase, ignorecaseBtn;
	function init(evt) {
		details = document.getElementById("details").firstChild;
		searchbtn = document.getElementById("search");
		ignorecaseBtn = document.getElementById("ignorecase");
		unzoombtn = document.getElementById("unzoom");
		matchedtxt = document.getElementById("matched");
		svg = document.getElementsByTagName("svg")[0];
		searching = 0;
		currentSearchTerm = null;

		// use GET parameters to restore a flamegraphs state.
		var params = get_params();
		if (params.x && params.y)
			zoom(find_group(document.querySelector('[x="' + params.x + '"][y="' + params.y + '"]')));
                if (params.s) search(params.s);
	}

	// event listeners
	window.addEventListener("click", function(e) {
		var target = find_group(e.target);
		if (target) {
			if (target.nodeName == "a") {
				if (e.ctrlKey === false) return;
				e.preventDefault();
			}
			if (target.classList.contains("parent")) unzoom(true);
			zoom(target);
			if (!document.querySelector('.parent')) {
				// we have basically done a clearzoom so clear the url
				var params = get_params();
				if (params.x) delete params.x;
				if (params.y) delete params.y;
				history.replaceState(null, null, parse_params(params));
				unzoombtn.classList.add("hide");
				return;
			}

			// set parameters for zoom state
			var el = target.querySelector("rect");
			if (el && el.attributes && el.attributes.y && el.attributes._orig_x) {
				var params = get_params()
				params.x = el.attributes._orig_x.value;
				params.y = el.attributes.y.value;
				history.replaceState(null, null, parse_params(params));
			}
		}
		else if (e.target.id == "unzoom") clearzoom();
		else if (e.target.id == "search") search_prompt();
		else if (e.target.id == "ignorecase") toggle_ignorecase();
	}, false)

	// mouse-over for info
	// show
	window.addEventListener("mouseover", function(e) {
		var target = find_group(e.target);
		if (target) details.nodeValue = "Function: " + g_to_text(target);
	}, false)

	// clear
	window.addEventListener("mouseout", function(e) {
		var target = find_group(e.target);
		if (target) details.nodeValue = ' ';
	}, false)

	// ctrl-F for search
	// ctrl-I to toggle case-sensitive search
	window.addEventListener("keydown",function (e) {
		if (e.keyCode === 114 || (e.ctrlKey && e.keyCode === 70)) {
			e.preventDefault();
			search_prompt();
		}
		else if (e.ctrlKey && e.keyCode === 73) {
			e.preventDefault();
			toggle_ignorecase();
		}
	}, false)

	// functions
	function get_params() {
		var params = {};
		var paramsarr = window.location.search.substr(1).split('&');
		for (var i = 0; i < paramsarr.length; ++i) {
			var tmp = paramsarr[i].split("=");
			if (!tmp[0] || !tmp[1]) continue;
			params[tmp[0]]  = decodeURIComponent(tmp[1]);
		}
		return params;
	}
	function parse_params(params) {
		var uri = "?";
		for (var key in params) {
			uri += key + '=' + encodeURIComponent(params[key]) + '&';
		}
		if (uri.slice(-1) == "&")
			uri = uri.substring(0, uri.length - 1);
		if (uri == '?')
			uri = window.location.href.split('?')[0];
		return uri;
	}
	function find_child(node, selector) {
		var children = node.querySelectorAll(selector);
		if (children.length) return children[0];
	}
	function find_group(node) {
		var parent = node.parentElement;
		if (!parent) return;
		if (parent.id == "frames") return node;
		return find_group(parent);
	}
	function orig_save(e, attr, val) {
		if (e.attributes["_orig_" + attr] != undefined) return;
		if (e.attributes[attr] == undefined) return;
		if (val == undefined) val = e.attributes[attr].value;
		e.setAttribute("_orig_" + attr, val);
	}
	function orig_load(e, attr) {
		if (e.attributes["_orig_"+attr] == undefined) return;
		e.attributes[attr].value = e.attributes["_orig_" + attr].value;
		e.removeAttribute("_orig_"+attr);
	}
	function g_to_text(e) {
		var text = find_child(e, "title").firstChild.nodeValue;
		return (text)
	}
	function g_to_func(e) {
		var func = g_to_text(e);
		// if there's any manipulation we want to do to the function
		// name before it's searched, do it here before returning.
		return (func);
	}
	function update_text(e) {
		var r = find_child(e, "rect");
		var t = find_child(e, "text");
		var w = parseFloat(r.attributes.width.value) -3;
		var txt = find_child(e, "title").textContent.replace(/\([^(]*\)$/,"");
		t.attributes.x.value = parseFloat(r.attributes.x.value) + 3;

		// Smaller than this size won't fit anything
		if (w < 2 * 12 * 0.59) {
			t.textContent = "";
			return;
		}

		t.textContent = txt;
		var sl = t.getSubStringLength(0, txt.length);
		// check if only whitespace or if we can fit the entire string into width w
		if (/^ *$/.test(txt) || sl < w)
			return;

		// this isn't perfect, but gives a good starting point
		// and avoids calling getSubStringLength too often
		var start = Math.floor((w/sl) * txt.length);
		for (var x = start; x > 0; x = x-2) {
			if (t.getSubStringLength(0, x + 2) <= w) {
				t.textContent = txt.substring(0, x) + "..";
				return;
			}
		}
		t.textContent = "";
	}

	// zoom
	function zoom_reset(e) {
		if (e.attributes != undefined) {
			orig_load(e, "x");
			orig_load(e, "width");
		}
		if (e.childNodes == undefined) return;
		for (var i = 0, c = e.childNodes; i < c.length; i++) {
			zoom_reset(c[i]);
		}
	}
	function zoom_child(e, x, ratio) {
		if (e.attributes != undefined) {
			if (e.attributes.x != undefined) {
				orig_save(e, "x");
				e.attributes.x.value = (parseFloat(e.attributes.x.value) - x - 10) * ratio + 10;
				if (e.tagName == "text")
					e.attributes.x.value = find_child(e.parentNode, "rect[x]").attributes.x.value + 3;
			}
			if (e.attributes.width != undefined) {
				orig_save(e, "width");
				e.attributes.width.value = parseFloat(e.attributes.width.value) * ratio;
			}
		}

		if (e.childNodes == undefined) return;
		for (var i = 0, c = e.childNodes; i < c.length; i++) {
			zoom_child(c[i], x - 10, ratio);
		}
	}
	function zoom_parent(e) {
		if (e.attributes) {
			if (e.attributes.x != undefined) {
				orig_save(e, "x");
				e.attributes.x.value = 10;
			}
			if (e.attributes.width != undefined) {
				orig_save(e, "width");
				e.attributes.width.value = parseInt(svg.width.baseVal.value) - (10 * 2);
			}
		}
		if (e.childNodes == undefined) return;
		for (var i = 0, c = e.childNodes; i < c.length; i++) {
			zoom_parent(c[i]);
		}
	}
	function zoom(node) {
		var attr = find_child(node, "rect").attributes;
		var width = parseFloat(attr.width.value);
		var xmin = parseFloat(attr.x.value);
		var xmax = parseFloat(xmin + width);
		var ymin = parseFloat(attr.y.value);
		var ratio = (svg.width.baseVal.value - 2 * 10) / width;

		// XXX: Workaround for JavaScript float issues (fix me)
		var fudge = 0.0001;

		unzoombtn.classList.remove("hide");

		var el = document.getElementById("frames").children;
		for (var i = 0; i < el.length; i++) {
			var e = el[i];
			var a = find_child(e, "rect").attributes;
			var ex = parseFloat(a.x.value);
			var ew = parseFloat(a.width.value);
			var upstack;
			// Is it an ancestor
			if (0 == 0) {
				upstack = parseFloat(a.y.value) > ymin;
			} else {
				upstack = parseFloat(a.y.value) < ymin;
			}
			if (upstack) {
				// Direct ancestor
				if (ex <= xmin && (ex+ew+fudge) >= xmax) {
					e.classList.add("parent");
					zoom_parent(e);
					update_text(e);
				}
				// not in current path
				else
					e.classList.add("hide");
			}
			// Children maybe
			else {
				// no common path
				if (ex < xmin || ex + fudge >= xmax) {
					e.classList.add("hide");
				}
				else {
					zoom_child(e, xmin, ratio);
					update_text(e);
				}
			}
		}
		search();
	}
	function unzoom(dont_update_text) {
		unzoombtn.classList.add("hide");
		var el = document.getElementById("frames").children;
		for(var i = 0; i < el.length; i++) {
			el[i].classList.remove("parent");
			el[i].classList.remove("hide");
			zoom_reset(el[i]);
			if(!dont_update_text) update_text(el[i]);
		}
		search();
	}
	function clearzoom() {
		unzoom();

		// remove zoom state
		var params = get_params();
		if (params.x) delete params.x;
		if (params.y) delete params.y;
		history.replaceState(null, null, parse_params(params));
	}

	// search
	function toggle_ignorecase() {
		ignorecase = !ignorecase;
		if (ignorecase) {
			ignorecaseBtn.classList.add("show");
		} else {
			ignorecaseBtn.classList.remove("show");
		}
		reset_search();
		search();
	}
	function reset_search() {
		var el = document.querySelectorAll("#frames rect");
		for (var i = 0; i < el.length; i++) {
			orig_load(el[i], "fill")
		}
		var params = get_params();
		delete params.s;
		history.replaceState(null, null, parse_params(params));
	}
	function search_prompt() {
		if (!searching) {
			var term = prompt("Enter a search term (regexp " +
			    "allowed, eg: ^ext4_)"
			    + (ignorecase ? ", ignoring case" : "")
			    + "\nPress Ctrl-i to toggle case sensitivity", "");
			if (term != null) search(term);
		} else {
			reset_search();
			searching = 0;
			currentSearchTerm = null;
			searchbtn.classList.remove("show");
			searchbtn.firstChild.nodeValue = "Search"
			matchedtxt.classList.add("hide");
			matchedtxt.firstChild.nodeValue = ""
		}
	}
	function search(term) {
		if (term) currentSearchTerm = term;
		if (currentSearchTerm === null) return;

		var re = new RegExp(currentSearchTerm, ignorecase ? 'i' : '');
		var el = document.getElementById("frames").children;
		var matches = new Object();
		var maxwidth = 0;
		for (var i = 0; i < el.length; i++) {
			var e = el[i];
			var func = g_to_func(e);
			var rect = find_child(e, "rect");
			if (func == null || rect == null)
				continue;

			// Save max width. Only works as we have a root frame
			var w = parseFloat(rect.attributes.width.value);
			if (w > maxwidth)
				maxwidth = w;

			if (func.match(re)) {
				// highlight
				var x = parseFloat(rect.attributes.x.value);
				orig_save(rect, "fill");
				rect.attributes.fill.value = "rgb(230,0,230)";

				// remember matches
				if (matches[x] == undefined) {
					matches[x] = w;
				} else {
					if (w > matches[x]) {
						// overwrite with parent
						matches[x] = w;
					}
				}
				searching = 1;
			}
		}
		if (!searching)
			return;
		var params = get_params();
		params.s = currentSearchTerm;
		history.replaceState(null, null, parse_params(params));

		searchbtn.classList.add("show");
		searchbtn.firstChild.nodeValue = "Reset Search";

		// calculate percent matched, excluding vertical overlap
		var count = 0;
		var lastx = -1;
		var lastw = 0;
		var keys = Array();
		for (k in matches) {
			if (matches.hasOwnProperty(k))
				keys.push(k);
		}
		// sort the matched frames by their x location
		// ascending, then width descending
		keys.sort(function(a, b){
			return a - b;
		});
		// Step through frames saving only the biggest bottom-up frames
		// thanks to the sort order. This relies on the tree property
		// where children are always smaller than their parents.
		var fudge = 0.0001;	// JavaScript floating point
		for (var k in keys) {
			var x = parseFloat(keys[k]);
			var w = matches[keys[k]];
			if (x >= lastx + lastw - fudge) {
				count += w;
				lastx = x;
				lastw = w;
			}
		}
		// display matched percent
		matchedtxt.classList.remove("hide");
		var pct = 100 * count / maxwidth;
		if (pct != 100) pct = pct.toFixed(1)
		matchedtxt.firstChild.nodeValue = "Matched: " + pct + "%";
	}
]]>
</script>
<rect x="0.0" y="0" width="1200.0" height="2134.0" fill="url(#background)"  />
<text id="title" x="600.00" y="24" >Flame Graph</text>
<text id="details" x="10.00" y="2117" > </text>
<text id="unzoom" x="10.00" y="24" class="hide">Reset Zoom</text>
<text id="search" x="1090.00" y="24" >Search</text>
<text id="ignorecase" x="1174.00" y="24" >ic</text>
<text id="matched" x="1090.00" y="2117" > </text>
<g id="frames">
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="949" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="959.5" ></text>
</g>
<g >
<title>_raw_spin_lock_irqsave (1,077,902,788 samples, 0.54%)</title><rect x="831.4" y="1765" width="6.3" height="15.0" fill="rgb(247,195,46)" rx="2" ry="2" />
<text  x="834.40" y="1775.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="725" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="735.5" ></text>
</g>
<g >
<title>__io_commit_cqring_flush (17,658,302 samples, 0.01%)</title><rect x="91.1" y="1941" width="0.1" height="15.0" fill="rgb(220,69,16)" rx="2" ry="2" />
<text  x="94.07" y="1951.5" ></text>
</g>
<g >
<title>__list_del_entry_valid_or_report (1,128,348,792 samples, 0.56%)</title><rect x="100.3" y="1957" width="6.6" height="15.0" fill="rgb(243,176,42)" rx="2" ry="2" />
<text  x="103.29" y="1967.5" ></text>
</g>
<g >
<title>entry_SYSCALL_64 (211,073,871 samples, 0.11%)</title><rect x="35.2" y="2037" width="1.2" height="15.0" fill="rgb(239,156,37)" rx="2" ry="2" />
<text  x="38.19" y="2047.5" ></text>
</g>
<g >
<title>__rcu_read_unlock (715,396,068 samples, 0.36%)</title><rect x="657.7" y="1829" width="4.2" height="15.0" fill="rgb(253,224,53)" rx="2" ry="2" />
<text  x="660.68" y="1839.5" ></text>
</g>
<g >
<title>bio_to_wbt_flags (431,359,461 samples, 0.22%)</title><rect x="865.9" y="1781" width="2.5" height="15.0" fill="rgb(235,138,33)" rx="2" ry="2" />
<text  x="868.89" y="1791.5" ></text>
</g>
<g >
<title>mempool_alloc_slab (56,036,252 samples, 0.03%)</title><rect x="710.0" y="1829" width="0.3" height="15.0" fill="rgb(241,167,40)" rx="2" ry="2" />
<text  x="712.99" y="1839.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1669" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1679.5" ></text>
</g>
<g >
<title>io_do_iopoll (44,109,247,618 samples, 21.99%)</title><rect x="39.1" y="1973" width="259.4" height="15.0" fill="rgb(246,191,45)" rx="2" ry="2" />
<text  x="42.08" y="1983.5" >io_do_iopoll</text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1621" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1631.5" ></text>
</g>
<g >
<title>ktime_get (43,750,141 samples, 0.02%)</title><rect x="227.9" y="1941" width="0.3" height="15.0" fill="rgb(207,10,2)" rx="2" ry="2" />
<text  x="230.90" y="1951.5" ></text>
</g>
<g >
<title>iomap_dio_alloc_bio (513,523,256 samples, 0.26%)</title><rect x="727.3" y="1861" width="3.0" height="15.0" fill="rgb(224,90,21)" rx="2" ry="2" />
<text  x="730.31" y="1871.5" ></text>
</g>
<g >
<title>io_file_supports_nowait (575,669,648 samples, 0.29%)</title><rect x="1127.6" y="1925" width="3.4" height="15.0" fill="rgb(247,196,47)" rx="2" ry="2" />
<text  x="1130.57" y="1935.5" ></text>
</g>
<g >
<title>__x64_sys_io_uring_enter (195,836,925,169 samples, 97.63%)</title><rect x="37.4" y="2005" width="1152.0" height="15.0" fill="rgb(210,27,6)" rx="2" ry="2" />
<text  x="40.37" y="2015.5" >__x64_sys_io_uring_enter</text>
</g>
<g >
<title>ext4_sb_block_valid (2,054,932,855 samples, 1.02%)</title><rect x="996.5" y="1813" width="12.1" height="15.0" fill="rgb(244,180,43)" rx="2" ry="2" />
<text  x="999.47" y="1823.5" ></text>
</g>
<g >
<title>__rcu_read_lock (600,292,682 samples, 0.30%)</title><rect x="691.6" y="1797" width="3.6" height="15.0" fill="rgb(220,69,16)" rx="2" ry="2" />
<text  x="694.62" y="1807.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1029" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1039.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1861" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1871.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="981" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="991.5" ></text>
</g>
<g >
<title>io_import_reg_buf (3,159,284,480 samples, 1.57%)</title><rect x="1159.4" y="1925" width="18.6" height="15.0" fill="rgb(216,52,12)" rx="2" ry="2" />
<text  x="1162.38" y="1935.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1141" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1151.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1413" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1423.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="293" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="303.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1189" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1199.5" ></text>
</g>
<g >
<title>io_iopoll_check (44,149,158,377 samples, 22.01%)</title><rect x="38.8" y="1989" width="259.7" height="15.0" fill="rgb(215,46,11)" rx="2" ry="2" />
<text  x="41.84" y="1999.5" >io_iopoll_check</text>
</g>
<g >
<title>barn_replace_full_sheaf.part.95 (115,133,106 samples, 0.06%)</title><rect x="227.2" y="1877" width="0.7" height="15.0" fill="rgb(233,131,31)" rx="2" ry="2" />
<text  x="230.22" y="1887.5" ></text>
</g>
<g >
<title>__kmalloc_cache_noprof (3,358,349,391 samples, 1.67%)</title><rect x="585.9" y="1877" width="19.8" height="15.0" fill="rgb(241,167,40)" rx="2" ry="2" />
<text  x="588.93" y="1887.5" ></text>
</g>
<g >
<title>wbt_done (786,016,446 samples, 0.39%)</title><rect x="166.4" y="1925" width="4.6" height="15.0" fill="rgb(222,81,19)" rx="2" ry="2" />
<text  x="169.42" y="1935.5" ></text>
</g>
<g >
<title>ext4_file_read_iter (109,833,513,600 samples, 54.75%)</title><rect x="481.5" y="1925" width="646.1" height="15.0" fill="rgb(244,180,43)" rx="2" ry="2" />
<text  x="484.49" y="1935.5" >ext4_file_read_iter</text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="789" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="799.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="885" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="895.5" ></text>
</g>
<g >
<title>mutex_unlock (1,729,415,866 samples, 0.86%)</title><rect x="1179.2" y="1989" width="10.2" height="15.0" fill="rgb(251,212,50)" rx="2" ry="2" />
<text  x="1182.19" y="1999.5" ></text>
</g>
<g >
<title>all (200,598,159,198 samples, 100%)</title><rect x="10.0" y="2085" width="1180.0" height="15.0" fill="rgb(213,39,9)" rx="2" ry="2" />
<text  x="13.00" y="2095.5" ></text>
</g>
<g >
<title>blk_mq_submit_bio (22,630,089,034 samples, 11.28%)</title><rect x="777.5" y="1829" width="133.1" height="15.0" fill="rgb(224,89,21)" rx="2" ry="2" />
<text  x="780.50" y="1839.5" >blk_mq_submit_bio</text>
</g>
<g >
<title>ext4_set_iomap (2,794,874,383 samples, 1.39%)</title><rect x="1074.2" y="1845" width="16.5" height="15.0" fill="rgb(229,110,26)" rx="2" ry="2" />
<text  x="1077.21" y="1855.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="421" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="431.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="213" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="223.5" ></text>
</g>
<g >
<title>bio_integrity_prep (317,001,236 samples, 0.16%)</title><rect x="868.4" y="1813" width="1.9" height="15.0" fill="rgb(220,69,16)" rx="2" ry="2" />
<text  x="871.44" y="1823.5" ></text>
</g>
<g >
<title>ext4_dio_alignment (1,498,360,433 samples, 0.75%)</title><rect x="508.0" y="1893" width="8.8" height="15.0" fill="rgb(236,146,35)" rx="2" ry="2" />
<text  x="510.99" y="1903.5" ></text>
</g>
<g >
<title>update_io_ticks (699,996,298 samples, 0.35%)</title><rect x="242.3" y="1941" width="4.1" height="15.0" fill="rgb(235,141,33)" rx="2" ry="2" />
<text  x="245.28" y="1951.5" ></text>
</g>
<g >
<title>[unknown] (3,121,865,120 samples, 1.56%)</title><rect x="10.0" y="101" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="111.5" ></text>
</g>
<g >
<title>barn_replace_full_sheaf.part.95 (82,896,437 samples, 0.04%)</title><rect x="99.8" y="1909" width="0.5" height="15.0" fill="rgb(233,131,31)" rx="2" ry="2" />
<text  x="102.80" y="1919.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="565" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="575.5" ></text>
</g>
<g >
<title>kthread_blkcg (300,124,375 samples, 0.15%)</title><rect x="703.4" y="1813" width="1.8" height="15.0" fill="rgb(249,203,48)" rx="2" ry="2" />
<text  x="706.42" y="1823.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1589" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1599.5" ></text>
</g>
<g >
<title>dma_unmap_page_attrs (118,188,921 samples, 0.06%)</title><rect x="280.5" y="1941" width="0.7" height="15.0" fill="rgb(252,218,52)" rx="2" ry="2" />
<text  x="283.47" y="1951.5" ></text>
</g>
<g >
<title>jbd2_transaction_committed (238,727,314 samples, 0.12%)</title><rect x="1089.2" y="1829" width="1.5" height="15.0" fill="rgb(221,77,18)" rx="2" ry="2" />
<text  x="1092.25" y="1839.5" ></text>
</g>
<g >
<title>iomap_iter (30,121,285,568 samples, 15.02%)</title><rect x="913.5" y="1877" width="177.2" height="15.0" fill="rgb(233,132,31)" rx="2" ry="2" />
<text  x="916.46" y="1887.5" >iomap_iter</text>
</g>
<g >
<title>__rcu_read_unlock (393,009,962 samples, 0.20%)</title><rect x="178.0" y="1925" width="2.3" height="15.0" fill="rgb(253,224,53)" rx="2" ry="2" />
<text  x="181.03" y="1935.5" ></text>
</g>
<g >
<title>_raw_spin_lock_irqsave (53,730,791 samples, 0.03%)</title><rect x="351.1" y="1893" width="0.3" height="15.0" fill="rgb(247,195,46)" rx="2" ry="2" />
<text  x="354.11" y="1903.5" ></text>
</g>
<g >
<title>nvme_poll (3,620,839,902 samples, 1.81%)</title><rect x="255.7" y="1909" width="21.3" height="15.0" fill="rgb(234,135,32)" rx="2" ry="2" />
<text  x="258.72" y="1919.5" >n..</text>
</g>
<g >
<title>io_read (117,554,830,458 samples, 58.60%)</title><rect x="460.2" y="1957" width="691.5" height="15.0" fill="rgb(243,175,41)" rx="2" ry="2" />
<text  x="463.22" y="1967.5" >io_read</text>
</g>
<g >
<title>iomap_dio_complete (5,039,225,900 samples, 2.51%)</title><rect x="198.3" y="1925" width="29.6" height="15.0" fill="rgb(209,19,4)" rx="2" ry="2" />
<text  x="201.26" y="1935.5" >io..</text>
</g>
<g >
<title>bio_init (9,068,510,873 samples, 4.52%)</title><rect x="651.8" y="1845" width="53.4" height="15.0" fill="rgb(254,229,54)" rx="2" ry="2" />
<text  x="654.85" y="1855.5" >bio_i..</text>
</g>
<g >
<title>__sbitmap_queue_get_batch (2,184,777,880 samples, 1.09%)</title><rect x="825.9" y="1781" width="12.9" height="15.0" fill="rgb(253,221,53)" rx="2" ry="2" />
<text  x="828.94" y="1791.5" ></text>
</g>
<g >
<title>do_syscall_64 (195,975,860,660 samples, 97.70%)</title><rect x="36.8" y="2021" width="1152.8" height="15.0" fill="rgb(209,20,4)" rx="2" ry="2" />
<text  x="39.76" y="2031.5" >do_syscall_64</text>
</g>
<g >
<title>io_uring (200,598,159,198 samples, 100.00%)</title><rect x="10.0" y="2069" width="1180.0" height="15.0" fill="rgb(208,13,3)" rx="2" ry="2" />
<text  x="13.00" y="2079.5" >io_uring</text>
</g>
<g >
<title>read_tsc (143,544,904 samples, 0.07%)</title><rect x="905.3" y="1797" width="0.8" height="15.0" fill="rgb(206,7,1)" rx="2" ry="2" />
<text  x="908.29" y="1807.5" ></text>
</g>
<g >
<title>iov_iter_advance (1,608,089,543 samples, 0.80%)</title><rect x="717.9" y="1845" width="9.4" height="15.0" fill="rgb(248,197,47)" rx="2" ry="2" />
<text  x="720.85" y="1855.5" ></text>
</g>
<g >
<title>barn_replace_empty_sheaf (146,607,415 samples, 0.07%)</title><rect x="350.6" y="1909" width="0.9" height="15.0" fill="rgb(223,84,20)" rx="2" ry="2" />
<text  x="353.64" y="1919.5" ></text>
</g>
<g >
<title>read_tsc (28,398,438 samples, 0.01%)</title><rect x="228.0" y="1925" width="0.2" height="15.0" fill="rgb(206,7,1)" rx="2" ry="2" />
<text  x="230.99" y="1935.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1701" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1711.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="245" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="255.5" ></text>
</g>
<g >
<title>submitter_uring_fn (1,381,721,602 samples, 0.69%)</title><rect x="20.2" y="37" width="8.2" height="15.0" fill="rgb(218,61,14)" rx="2" ry="2" />
<text  x="23.24" y="47.5" ></text>
</g>
<g >
<title>[unknown] (3,124,600,077 samples, 1.56%)</title><rect x="10.0" y="2053" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="2063.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1445" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1455.5" ></text>
</g>
<g >
<title>blk_mq_start_request (2,734,221,559 samples, 1.36%)</title><rect x="381.2" y="1877" width="16.1" height="15.0" fill="rgb(242,172,41)" rx="2" ry="2" />
<text  x="384.19" y="1887.5" ></text>
</g>
<g >
<title>[unknown] (3,122,574,652 samples, 1.56%)</title><rect x="10.0" y="181" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="191.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1525" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1535.5" ></text>
</g>
<g >
<title>__io_submit_flush_completions (5,718,444,365 samples, 2.85%)</title><rect x="66.7" y="1957" width="33.6" height="15.0" fill="rgb(226,99,23)" rx="2" ry="2" />
<text  x="69.66" y="1967.5" >__..</text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="629" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="639.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="341" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="351.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1221" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1231.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1333" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1343.5" ></text>
</g>
<g >
<title>down_read_trylock (2,396,862,333 samples, 1.19%)</title><rect x="490.7" y="1909" width="14.1" height="15.0" fill="rgb(219,66,15)" rx="2" ry="2" />
<text  x="493.74" y="1919.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1061" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1071.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1829" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1839.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1781" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1791.5" ></text>
</g>
<g >
<title>rw_verify_area (1,599,725,526 samples, 0.80%)</title><rect x="1142.3" y="1925" width="9.4" height="15.0" fill="rgb(218,64,15)" rx="2" ry="2" />
<text  x="1145.31" y="1935.5" ></text>
</g>
<g >
<title>[unknown] (3,122,574,652 samples, 1.56%)</title><rect x="10.0" y="133" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="143.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="2021" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="2031.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="549" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="559.5" ></text>
</g>
<g >
<title>__rcu_read_unlock (20,728,599 samples, 0.01%)</title><rect x="825.5" y="1797" width="0.1" height="15.0" fill="rgb(253,224,53)" rx="2" ry="2" />
<text  x="828.45" y="1807.5" ></text>
</g>
<g >
<title>blk_rq_merge_ok (1,478,130,142 samples, 0.74%)</title><rect x="884.1" y="1781" width="8.7" height="15.0" fill="rgb(215,46,11)" rx="2" ry="2" />
<text  x="887.07" y="1791.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="501" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="511.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="901" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="911.5" ></text>
</g>
<g >
<title>blk_attempt_bio_merge (2,901,277,578 samples, 1.45%)</title><rect x="879.7" y="1797" width="17.1" height="15.0" fill="rgb(206,7,1)" rx="2" ry="2" />
<text  x="882.73" y="1807.5" ></text>
</g>
<g >
<title>io_cache_alloc_new (2,803,334,290 samples, 1.40%)</title><rect x="338.1" y="1957" width="16.5" height="15.0" fill="rgb(236,146,35)" rx="2" ry="2" />
<text  x="341.14" y="1967.5" ></text>
</g>
<g >
<title>io_rw_recycle (773,698,789 samples, 0.39%)</title><rect x="249.7" y="1941" width="4.5" height="15.0" fill="rgb(235,142,34)" rx="2" ry="2" />
<text  x="252.65" y="1951.5" ></text>
</g>
<g >
<title>kiocb_write_and_wait (597,211,034 samples, 0.30%)</title><rect x="1094.0" y="1877" width="3.5" height="15.0" fill="rgb(221,77,18)" rx="2" ry="2" />
<text  x="1097.00" y="1887.5" ></text>
</g>
<g >
<title>blk_mq_finish_request (511,225,423 samples, 0.25%)</title><rect x="185.4" y="1941" width="3.0" height="15.0" fill="rgb(206,6,1)" rx="2" ry="2" />
<text  x="188.37" y="1951.5" ></text>
</g>
<g >
<title>__radix_tree_lookup (1,215,074,118 samples, 0.61%)</title><rect x="684.5" y="1797" width="7.1" height="15.0" fill="rgb(253,222,53)" rx="2" ry="2" />
<text  x="687.47" y="1807.5" ></text>
</g>
<g >
<title>submit_bio_noacct_nocheck (25,760,357,611 samples, 12.84%)</title><rect x="761.9" y="1861" width="151.6" height="15.0" fill="rgb(225,95,22)" rx="2" ry="2" />
<text  x="764.93" y="1871.5" >submit_bio_noacct_n..</text>
</g>
<g >
<title>ktime_get (253,310,592 samples, 0.13%)</title><rect x="904.6" y="1813" width="1.5" height="15.0" fill="rgb(207,10,2)" rx="2" ry="2" />
<text  x="907.64" y="1823.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="325" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="335.5" ></text>
</g>
<g >
<title>__rcu_read_unlock (1,236,633,414 samples, 0.62%)</title><rect x="695.2" y="1797" width="7.2" height="15.0" fill="rgb(253,224,53)" rx="2" ry="2" />
<text  x="698.15" y="1807.5" ></text>
</g>
<g >
<title>kmem_cache_free (391,431,228 samples, 0.20%)</title><rect x="158.7" y="1909" width="2.3" height="15.0" fill="rgb(254,225,53)" rx="2" ry="2" />
<text  x="161.73" y="1919.5" ></text>
</g>
<g >
<title>submitter_uring_fn (197,473,434,122 samples, 98.44%)</title><rect x="28.4" y="2053" width="1161.6" height="15.0" fill="rgb(218,61,14)" rx="2" ry="2" />
<text  x="31.38" y="2063.5" >submitter_uring_fn</text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1909" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1919.5" ></text>
</g>
<g >
<title>bio_endio (1,998,035,513 samples, 1.00%)</title><rect x="171.1" y="1941" width="11.7" height="15.0" fill="rgb(217,55,13)" rx="2" ry="2" />
<text  x="174.05" y="1951.5" ></text>
</g>
<g >
<title>__iomap_dio_rw (98,268,516,766 samples, 48.99%)</title><rect x="519.5" y="1893" width="578.0" height="15.0" fill="rgb(212,35,8)" rx="2" ry="2" />
<text  x="522.45" y="1903.5" >__iomap_dio_rw</text>
</g>
<g >
<title>wbt_issue (344,664,823 samples, 0.17%)</title><rect x="391.3" y="1845" width="2.0" height="15.0" fill="rgb(226,98,23)" rx="2" ry="2" />
<text  x="394.30" y="1855.5" ></text>
</g>
<g >
<title>mempool_alloc_noprof (872,032,812 samples, 0.43%)</title><rect x="705.2" y="1845" width="5.1" height="15.0" fill="rgb(228,106,25)" rx="2" ry="2" />
<text  x="708.19" y="1855.5" ></text>
</g>
<g >
<title>__submit_bio (23,548,162,534 samples, 11.74%)</title><rect x="772.1" y="1845" width="138.5" height="15.0" fill="rgb(230,117,28)" rx="2" ry="2" />
<text  x="775.10" y="1855.5" >__submit_bio</text>
</g>
<g >
<title>blk_start_plug (389,947,699 samples, 0.19%)</title><rect x="611.0" y="1877" width="2.3" height="15.0" fill="rgb(217,56,13)" rx="2" ry="2" />
<text  x="613.97" y="1887.5" ></text>
</g>
<g >
<title>__blk_mq_alloc_requests (6,163,309,038 samples, 3.07%)</title><rect x="813.0" y="1813" width="36.2" height="15.0" fill="rgb(248,199,47)" rx="2" ry="2" />
<text  x="815.96" y="1823.5" >__b..</text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="437" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="447.5" ></text>
</g>
<g >
<title>blk_mq_complete_request_remote (574,948,329 samples, 0.29%)</title><rect x="273.6" y="1893" width="3.4" height="15.0" fill="rgb(235,140,33)" rx="2" ry="2" />
<text  x="276.63" y="1903.5" ></text>
</g>
<g >
<title>io_init_rw_fixed (3,995,997,026 samples, 1.99%)</title><rect x="1154.5" y="1941" width="23.5" height="15.0" fill="rgb(244,182,43)" rx="2" ry="2" />
<text  x="1157.46" y="1951.5" >i..</text>
</g>
<g >
<title>ext4_inode_block_valid (211,064,702 samples, 0.11%)</title><rect x="995.2" y="1813" width="1.3" height="15.0" fill="rgb(215,50,11)" rx="2" ry="2" />
<text  x="998.23" y="1823.5" ></text>
</g>
<g >
<title>sbitmap_queue_clear_batch (2,401,718,431 samples, 1.20%)</title><rect x="228.2" y="1941" width="14.1" height="15.0" fill="rgb(245,184,44)" rx="2" ry="2" />
<text  x="231.16" y="1951.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1461" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1471.5" ></text>
</g>
<g >
<title>__check_block_validity.constprop.90 (3,012,094,778 samples, 1.50%)</title><rect x="990.8" y="1829" width="17.8" height="15.0" fill="rgb(233,129,30)" rx="2" ry="2" />
<text  x="993.84" y="1839.5" ></text>
</g>
<g >
<title>[unknown] (3,122,574,652 samples, 1.56%)</title><rect x="10.0" y="149" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="159.5" ></text>
</g>
<g >
<title>bio_uninit (188,828,177 samples, 0.09%)</title><rect x="157.3" y="1909" width="1.1" height="15.0" fill="rgb(238,154,36)" rx="2" ry="2" />
<text  x="160.30" y="1919.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1509" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1519.5" ></text>
</g>
<g >
<title>blk_mq_flush_plug_list (13,189,925,409 samples, 6.58%)</title><rect x="355.0" y="1941" width="77.6" height="15.0" fill="rgb(215,46,11)" rx="2" ry="2" />
<text  x="358.04" y="1951.5" >blk_mq_f..</text>
</g>
<g >
<title>ext4_es_lookup_extent (11,159,548,846 samples, 5.56%)</title><rect x="1008.6" y="1829" width="65.6" height="15.0" fill="rgb(222,80,19)" rx="2" ry="2" />
<text  x="1011.56" y="1839.5" >ext4_es..</text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="741" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="751.5" ></text>
</g>
<g >
<title>iomap_dio_complete_work (5,337,825,975 samples, 2.66%)</title><rect x="196.5" y="1941" width="31.4" height="15.0" fill="rgb(232,124,29)" rx="2" ry="2" />
<text  x="199.50" y="1951.5" >io..</text>
</g>
<g >
<title>io_vec_free (143,529,914 samples, 0.07%)</title><rect x="254.3" y="1957" width="0.8" height="15.0" fill="rgb(236,144,34)" rx="2" ry="2" />
<text  x="257.25" y="1967.5" ></text>
</g>
<g >
<title>entry_SYSCALL_64_safe_stack (36,079,163 samples, 0.02%)</title><rect x="1189.6" y="2037" width="0.2" height="15.0" fill="rgb(231,120,28)" rx="2" ry="2" />
<text  x="1192.57" y="2047.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1845" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1855.5" ></text>
</g>
<g >
<title>io_req_rw_cleanup (1,326,356,716 samples, 0.66%)</title><rect x="246.4" y="1957" width="7.8" height="15.0" fill="rgb(246,193,46)" rx="2" ry="2" />
<text  x="249.40" y="1967.5" ></text>
</g>
<g >
<title>mempool_free_slab (19,192,576 samples, 0.01%)</title><rect x="161.3" y="1909" width="0.1" height="15.0" fill="rgb(219,67,16)" rx="2" ry="2" />
<text  x="164.30" y="1919.5" ></text>
</g>
<g >
<title>blk_mq_get_tags (2,246,187,939 samples, 1.12%)</title><rect x="825.6" y="1797" width="13.2" height="15.0" fill="rgb(215,46,11)" rx="2" ry="2" />
<text  x="828.57" y="1807.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="661" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="671.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="709" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="719.5" ></text>
</g>
<g >
<title>ext4_should_use_dio.isra.16 (2,034,135,990 samples, 1.01%)</title><rect x="504.8" y="1909" width="12.0" height="15.0" fill="rgb(242,170,40)" rx="2" ry="2" />
<text  x="507.84" y="1919.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1541" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1551.5" ></text>
</g>
<g >
<title>__iomap_dio_bio_end_io (3,111,009,699 samples, 1.55%)</title><rect x="143.1" y="1941" width="18.3" height="15.0" fill="rgb(207,12,3)" rx="2" ry="2" />
<text  x="146.11" y="1951.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="309" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="319.5" ></text>
</g>
<g >
<title>__rcu_read_unlock (68,317,548 samples, 0.03%)</title><rect x="355.6" y="1909" width="0.4" height="15.0" fill="rgb(253,224,53)" rx="2" ry="2" />
<text  x="358.61" y="1919.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1685" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1695.5" ></text>
</g>
<g >
<title>__pcs_replace_empty_main (299,382,124 samples, 0.15%)</title><rect x="603.9" y="1861" width="1.8" height="15.0" fill="rgb(229,114,27)" rx="2" ry="2" />
<text  x="606.92" y="1871.5" ></text>
</g>
<g >
<title>bio_uninit (33,777,546 samples, 0.02%)</title><rect x="153.7" y="1909" width="0.2" height="15.0" fill="rgb(238,154,36)" rx="2" ry="2" />
<text  x="156.72" y="1919.5" ></text>
</g>
<g >
<title>blk_integrity_merge_bio (325,428,207 samples, 0.16%)</title><rect x="890.8" y="1765" width="2.0" height="15.0" fill="rgb(209,20,5)" rx="2" ry="2" />
<text  x="893.85" y="1775.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1045" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1055.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1205" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1215.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1317" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1327.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="357" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="367.5" ></text>
</g>
<g >
<title>submit_bio (578,018,166 samples, 0.29%)</title><rect x="746.7" y="1861" width="3.4" height="15.0" fill="rgb(207,13,3)" rx="2" ry="2" />
<text  x="749.65" y="1871.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1749" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1759.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="229" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="239.5" ></text>
</g>
<g >
<title>iocb_bio_iopoll (3,730,626,666 samples, 1.86%)</title><rect x="255.1" y="1957" width="21.9" height="15.0" fill="rgb(208,16,3)" rx="2" ry="2" />
<text  x="258.10" y="1967.5" >i..</text>
</g>
<g >
<title>__rcu_read_unlock (18,421,988 samples, 0.01%)</title><rect x="849.3" y="1813" width="0.1" height="15.0" fill="rgb(253,224,53)" rx="2" ry="2" />
<text  x="852.29" y="1823.5" ></text>
</g>
<g >
<title>_raw_spin_lock_irqsave (35,305,622 samples, 0.02%)</title><rect x="100.0" y="1893" width="0.2" height="15.0" fill="rgb(247,195,46)" rx="2" ry="2" />
<text  x="103.01" y="1903.5" ></text>
</g>
<g >
<title>syscall_return_via_sysret (29,939,947 samples, 0.01%)</title><rect x="1189.8" y="2037" width="0.2" height="15.0" fill="rgb(229,113,27)" rx="2" ry="2" />
<text  x="1192.82" y="2047.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1397" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1407.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="581" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="591.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="821" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="831.5" ></text>
</g>
<g >
<title>_raw_read_lock (2,582,300,175 samples, 1.29%)</title><rect x="1034.0" y="1813" width="15.2" height="15.0" fill="rgb(233,132,31)" rx="2" ry="2" />
<text  x="1037.00" y="1823.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="869" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="879.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1269" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1279.5" ></text>
</g>
<g >
<title>update_io_ticks (762,283,326 samples, 0.38%)</title><rect x="906.1" y="1813" width="4.5" height="15.0" fill="rgb(235,141,33)" rx="2" ry="2" />
<text  x="909.13" y="1823.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1109" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1119.5" ></text>
</g>
<g >
<title>[unknown] (3,122,574,652 samples, 1.56%)</title><rect x="10.0" y="165" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="175.5" ></text>
</g>
<g >
<title>__rcu_read_lock (297,833,438 samples, 0.15%)</title><rect x="667.3" y="1813" width="1.7" height="15.0" fill="rgb(220,69,16)" rx="2" ry="2" />
<text  x="670.30" y="1823.5" ></text>
</g>
<g >
<title>[unknown] (3,122,574,652 samples, 1.56%)</title><rect x="10.0" y="197" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="207.5" ></text>
</g>
<g >
<title>blk_hctx_poll.isra.67 (3,662,306,567 samples, 1.83%)</title><rect x="255.5" y="1925" width="21.5" height="15.0" fill="rgb(209,22,5)" rx="2" ry="2" />
<text  x="258.47" y="1935.5" >b..</text>
</g>
<g >
<title>__list_add_valid_or_report (500,494,189 samples, 0.25%)</title><rect x="450.1" y="1957" width="3.0" height="15.0" fill="rgb(215,46,11)" rx="2" ry="2" />
<text  x="453.11" y="1967.5" ></text>
</g>
<g >
<title>__pcs_replace_full_main (198,806,521 samples, 0.10%)</title><rect x="226.7" y="1893" width="1.2" height="15.0" fill="rgb(230,119,28)" rx="2" ry="2" />
<text  x="229.73" y="1903.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1797" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1807.5" ></text>
</g>
<g >
<title>io_rw_init_file (1,930,476,081 samples, 0.96%)</title><rect x="1131.0" y="1925" width="11.3" height="15.0" fill="rgb(218,60,14)" rx="2" ry="2" />
<text  x="1133.96" y="1935.5" ></text>
</g>
<g >
<title>blk_mq_sched_bio_merge (1,333,242,881 samples, 0.66%)</title><rect x="896.8" y="1813" width="7.8" height="15.0" fill="rgb(210,26,6)" rx="2" ry="2" />
<text  x="899.80" y="1823.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="805" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="815.5" ></text>
</g>
<g >
<title>__rq_qos_done (1,185,940,827 samples, 0.59%)</title><rect x="164.1" y="1941" width="6.9" height="15.0" fill="rgb(226,98,23)" rx="2" ry="2" />
<text  x="167.07" y="1951.5" ></text>
</g>
<g >
<title>nvme_unmap_data (617,178,405 samples, 0.31%)</title><rect x="294.9" y="1941" width="3.6" height="15.0" fill="rgb(237,149,35)" rx="2" ry="2" />
<text  x="297.92" y="1951.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="261" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="271.5" ></text>
</g>
<g >
<title>mutex_lock (86,721,107 samples, 0.04%)</title><rect x="1178.7" y="1989" width="0.5" height="15.0" fill="rgb(217,57,13)" rx="2" ry="2" />
<text  x="1181.68" y="1999.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1957" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1967.5" ></text>
</g>
<g >
<title>__rcu_read_unlock (601,805,813 samples, 0.30%)</title><rect x="1005.0" y="1797" width="3.6" height="15.0" fill="rgb(253,224,53)" rx="2" ry="2" />
<text  x="1008.02" y="1807.5" ></text>
</g>
<g >
<title>__rq_qos_done_bio (419,122,814 samples, 0.21%)</title><rect x="180.3" y="1925" width="2.5" height="15.0" fill="rgb(234,134,32)" rx="2" ry="2" />
<text  x="183.34" y="1935.5" ></text>
</g>
<g >
<title>[unknown] (3,121,865,120 samples, 1.56%)</title><rect x="10.0" y="53" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="63.5" ></text>
</g>
<g >
<title>__io_prep_rw (6,507,638,344 samples, 3.24%)</title><rect x="316.3" y="1973" width="38.3" height="15.0" fill="rgb(222,80,19)" rx="2" ry="2" />
<text  x="319.35" y="1983.5" >__i..</text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1573" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1583.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="693" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="703.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="373" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="383.5" ></text>
</g>
<g >
<title>iomap_iter_advance (568,776,951 samples, 0.28%)</title><rect x="1090.7" y="1877" width="3.3" height="15.0" fill="rgb(206,4,1)" rx="2" ry="2" />
<text  x="1093.65" y="1887.5" ></text>
</g>
<g >
<title>nvme_queue_rqs (13,025,651,367 samples, 6.49%)</title><rect x="356.0" y="1909" width="76.6" height="15.0" fill="rgb(250,211,50)" rx="2" ry="2" />
<text  x="359.01" y="1919.5" >nvme_que..</text>
</g>
<g >
<title>ext4_iomap_begin (22,794,302,344 samples, 11.36%)</title><rect x="956.6" y="1861" width="134.1" height="15.0" fill="rgb(233,133,31)" rx="2" ry="2" />
<text  x="959.56" y="1871.5" >ext4_iomap_begin</text>
</g>
<g >
<title>iomap_dio_bio_end_io (244,863,204 samples, 0.12%)</title><rect x="195.1" y="1941" width="1.4" height="15.0" fill="rgb(235,138,33)" rx="2" ry="2" />
<text  x="198.06" y="1951.5" ></text>
</g>
<g >
<title>__pcs_replace_empty_main (64,495,208 samples, 0.03%)</title><rect x="709.6" y="1813" width="0.4" height="15.0" fill="rgb(229,114,27)" rx="2" ry="2" />
<text  x="712.61" y="1823.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="965" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="975.5" ></text>
</g>
<g >
<title>iomap_dio_submit_bio (2,774,577,725 samples, 1.38%)</title><rect x="730.3" y="1861" width="16.4" height="15.0" fill="rgb(239,159,38)" rx="2" ry="2" />
<text  x="733.33" y="1871.5" ></text>
</g>
<g >
<title>__rcu_read_lock (203,410,843 samples, 0.10%)</title><rect x="1003.8" y="1797" width="1.2" height="15.0" fill="rgb(220,69,16)" rx="2" ry="2" />
<text  x="1006.82" y="1807.5" ></text>
</g>
<g >
<title>bio_alloc_bioset (12,138,171,216 samples, 6.05%)</title><rect x="638.9" y="1861" width="71.4" height="15.0" fill="rgb(206,5,1)" rx="2" ry="2" />
<text  x="641.92" y="1871.5" >bio_allo..</text>
</g>
<g >
<title>nvme_submit_cmds.part.55 (1,985,849,787 samples, 0.99%)</title><rect x="420.9" y="1893" width="11.7" height="15.0" fill="rgb(245,187,44)" rx="2" ry="2" />
<text  x="423.95" y="1903.5" ></text>
</g>
<g >
<title>entry_SYSCALL_64_after_hwframe (196,031,136,912 samples, 97.72%)</title><rect x="36.4" y="2037" width="1153.2" height="15.0" fill="rgb(218,63,15)" rx="2" ry="2" />
<text  x="39.43" y="2047.5" >entry_SYSCALL_64_after_hwframe</text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="613" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="623.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="853" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="863.5" ></text>
</g>
<g >
<title>blk_add_timer (670,164,765 samples, 0.33%)</title><rect x="393.3" y="1861" width="4.0" height="15.0" fill="rgb(224,91,21)" rx="2" ry="2" />
<text  x="396.34" y="1871.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1877" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1887.5" ></text>
</g>
<g >
<title>__list_del_entry_valid_or_report (27,630,743 samples, 0.01%)</title><rect x="605.1" y="1829" width="0.1" height="15.0" fill="rgb(243,176,42)" rx="2" ry="2" />
<text  x="608.08" y="1839.5" ></text>
</g>
<g >
<title>kfree (1,534,449,931 samples, 0.76%)</title><rect x="91.3" y="1941" width="9.0" height="15.0" fill="rgb(222,78,18)" rx="2" ry="2" />
<text  x="94.27" y="1951.5" ></text>
</g>
<g >
<title>mempool_free (511,180,276 samples, 0.25%)</title><rect x="158.4" y="1925" width="3.0" height="15.0" fill="rgb(233,131,31)" rx="2" ry="2" />
<text  x="161.41" y="1935.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="453" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="463.5" ></text>
</g>
<g >
<title>iov_iter_bvec (323,923,750 samples, 0.16%)</title><rect x="1176.1" y="1909" width="1.9" height="15.0" fill="rgb(224,90,21)" rx="2" ry="2" />
<text  x="1179.06" y="1919.5" ></text>
</g>
<g >
<title>_raw_spin_lock_irqsave (57,576,410 samples, 0.03%)</title><rect x="605.2" y="1829" width="0.4" height="15.0" fill="rgb(247,195,46)" rx="2" ry="2" />
<text  x="608.25" y="1839.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1973" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1983.5" ></text>
</g>
<g >
<title>_raw_spin_unlock_irqrestore (178,092,733 samples, 0.09%)</title><rect x="837.7" y="1765" width="1.1" height="15.0" fill="rgb(228,106,25)" rx="2" ry="2" />
<text  x="840.74" y="1775.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1429" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1439.5" ></text>
</g>
<g >
<title>_find_next_bit (36,857,567 samples, 0.02%)</title><rect x="910.4" y="1765" width="0.2" height="15.0" fill="rgb(230,116,27)" rx="2" ry="2" />
<text  x="913.40" y="1775.5" ></text>
</g>
<g >
<title>percpu_counter_add_batch (1,579,001,476 samples, 0.79%)</title><rect x="1064.9" y="1813" width="9.3" height="15.0" fill="rgb(241,166,39)" rx="2" ry="2" />
<text  x="1067.92" y="1823.5" ></text>
</g>
<g >
<title>__pi_memset (530,432,963 samples, 0.26%)</title><rect x="351.5" y="1941" width="3.1" height="15.0" fill="rgb(215,47,11)" rx="2" ry="2" />
<text  x="354.51" y="1951.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="405" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="415.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="645" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="655.5" ></text>
</g>
<g >
<title>ext4_map_blocks (17,150,015,990 samples, 8.55%)</title><rect x="973.3" y="1845" width="100.9" height="15.0" fill="rgb(247,196,46)" rx="2" ry="2" />
<text  x="976.33" y="1855.5" >ext4_map_blo..</text>
</g>
<g >
<title>kfree (1,646,450,652 samples, 0.82%)</title><rect x="218.2" y="1909" width="9.7" height="15.0" fill="rgb(222,78,18)" rx="2" ry="2" />
<text  x="221.21" y="1919.5" ></text>
</g>
<g >
<title>[unknown] (3,121,865,120 samples, 1.56%)</title><rect x="10.0" y="85" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="95.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1717" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1727.5" ></text>
</g>
<g >
<title>wbt_wait (1,535,959,142 samples, 0.77%)</title><rect x="851.5" y="1797" width="9.1" height="15.0" fill="rgb(225,95,22)" rx="2" ry="2" />
<text  x="854.54" y="1807.5" ></text>
</g>
<g >
<title>io_assign_file.part.63 (1,218,192,856 samples, 0.61%)</title><rect x="453.1" y="1957" width="7.1" height="15.0" fill="rgb(228,107,25)" rx="2" ry="2" />
<text  x="456.05" y="1967.5" ></text>
</g>
<g >
<title>__list_del_entry_valid_or_report (26,100,399 samples, 0.01%)</title><rect x="351.0" y="1893" width="0.1" height="15.0" fill="rgb(243,176,42)" rx="2" ry="2" />
<text  x="353.95" y="1903.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1941" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1951.5" ></text>
</g>
<g >
<title>_find_first_zero_bit (108,229,251 samples, 0.05%)</title><rect x="830.8" y="1765" width="0.6" height="15.0" fill="rgb(244,181,43)" rx="2" ry="2" />
<text  x="833.76" y="1775.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1077" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1087.5" ></text>
</g>
<g >
<title>blk_finish_plug (898,047,097 samples, 0.45%)</title><rect x="605.7" y="1877" width="5.3" height="15.0" fill="rgb(231,119,28)" rx="2" ry="2" />
<text  x="608.69" y="1887.5" ></text>
</g>
<g >
<title>barn_replace_empty_sheaf (161,204,716 samples, 0.08%)</title><rect x="604.7" y="1845" width="1.0" height="15.0" fill="rgb(223,84,20)" rx="2" ry="2" />
<text  x="607.73" y="1855.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1237" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1247.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="533" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="543.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="933" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="943.5" ></text>
</g>
<g >
<title>io_read_fixed (4,460,420,321 samples, 2.22%)</title><rect x="1151.7" y="1957" width="26.3" height="15.0" fill="rgb(218,62,14)" rx="2" ry="2" />
<text  x="1154.72" y="1967.5" >i..</text>
</g>
<g >
<title>__rq_qos_track (1,334,794,047 samples, 0.67%)</title><rect x="860.6" y="1813" width="7.8" height="15.0" fill="rgb(209,20,4)" rx="2" ry="2" />
<text  x="863.58" y="1823.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1605" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1615.5" ></text>
</g>
<g >
<title>blk_cgroup_bio_start (484,376,891 samples, 0.24%)</title><rect x="910.6" y="1845" width="2.9" height="15.0" fill="rgb(229,114,27)" rx="2" ry="2" />
<text  x="913.62" y="1855.5" ></text>
</g>
<g >
<title>bdev_count_inflight_rw.part.14 (128,992,677 samples, 0.06%)</title><rect x="909.9" y="1781" width="0.7" height="15.0" fill="rgb(208,15,3)" rx="2" ry="2" />
<text  x="912.86" y="1791.5" ></text>
</g>
<g >
<title>dma_unmap_phys (1,414,794,723 samples, 0.71%)</title><rect x="281.2" y="1941" width="8.3" height="15.0" fill="rgb(218,64,15)" rx="2" ry="2" />
<text  x="284.16" y="1951.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="997" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1007.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1157" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1167.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1365" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1375.5" ></text>
</g>
<g >
<title>bio_associate_blkg (7,361,394,905 samples, 3.67%)</title><rect x="661.9" y="1829" width="43.3" height="15.0" fill="rgb(244,183,43)" rx="2" ry="2" />
<text  x="664.89" y="1839.5" >bio_..</text>
</g>
<g >
<title>wb_timestamp (277,858,246 samples, 0.14%)</title><rect x="169.4" y="1909" width="1.6" height="15.0" fill="rgb(217,56,13)" rx="2" ry="2" />
<text  x="172.41" y="1919.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="773" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="783.5" ></text>
</g>
<g >
<title>blk_start_plug_nr_ios (18,426,904 samples, 0.01%)</title><rect x="432.6" y="1973" width="0.1" height="15.0" fill="rgb(254,228,54)" rx="2" ry="2" />
<text  x="435.63" y="1983.5" ></text>
</g>
<g >
<title>wb_timestamp (338,494,931 samples, 0.17%)</title><rect x="858.6" y="1781" width="2.0" height="15.0" fill="rgb(217,56,13)" rx="2" ry="2" />
<text  x="861.59" y="1791.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1493" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1503.5" ></text>
</g>
<g >
<title>bio_put (745,335,950 samples, 0.37%)</title><rect x="154.0" y="1925" width="4.4" height="15.0" fill="rgb(242,173,41)" rx="2" ry="2" />
<text  x="157.02" y="1935.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="2037" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="2047.5" ></text>
</g>
<g >
<title>bio_to_wbt_flags (297,839,667 samples, 0.15%)</title><rect x="856.8" y="1781" width="1.8" height="15.0" fill="rgb(235,138,33)" rx="2" ry="2" />
<text  x="859.84" y="1791.5" ></text>
</g>
<g >
<title>blk_attempt_plug_merge (3,291,988,316 samples, 1.64%)</title><rect x="877.4" y="1813" width="19.4" height="15.0" fill="rgb(242,173,41)" rx="2" ry="2" />
<text  x="880.43" y="1823.5" ></text>
</g>
<g >
<title>blk_mq_rq_ctx_init.isra.58 (1,772,430,460 samples, 0.88%)</title><rect x="838.8" y="1797" width="10.4" height="15.0" fill="rgb(223,83,19)" rx="2" ry="2" />
<text  x="841.79" y="1807.5" ></text>
</g>
<g >
<title>_raw_read_unlock (2,669,710,869 samples, 1.33%)</title><rect x="1049.2" y="1813" width="15.7" height="15.0" fill="rgb(217,57,13)" rx="2" ry="2" />
<text  x="1052.19" y="1823.5" ></text>
</g>
<g >
<title>__rcu_read_unlock (444,979,049 samples, 0.22%)</title><rect x="161.4" y="1941" width="2.7" height="15.0" fill="rgb(253,224,53)" rx="2" ry="2" />
<text  x="164.45" y="1951.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1637" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1647.5" ></text>
</g>
<g >
<title>barn_replace_empty_sheaf (29,175,668 samples, 0.01%)</title><rect x="709.8" y="1797" width="0.2" height="15.0" fill="rgb(223,84,20)" rx="2" ry="2" />
<text  x="712.81" y="1807.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="277" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="287.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="757" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="767.5" ></text>
</g>
<g >
<title>bio_iov_iter_get_pages (2,888,197,191 samples, 1.44%)</title><rect x="710.3" y="1861" width="17.0" height="15.0" fill="rgb(228,107,25)" rx="2" ry="2" />
<text  x="713.32" y="1871.5" ></text>
</g>
<g >
<title>__rcu_read_lock (138,931,437 samples, 0.07%)</title><rect x="192.8" y="1925" width="0.8" height="15.0" fill="rgb(220,69,16)" rx="2" ry="2" />
<text  x="195.83" y="1935.5" ></text>
</g>
<g >
<title>fpregs_assert_state_consistent (22,249,206 samples, 0.01%)</title><rect x="1189.4" y="2005" width="0.1" height="15.0" fill="rgb(228,109,26)" rx="2" ry="2" />
<text  x="1192.36" y="2015.5" ></text>
</g>
<g >
<title>__kmalloc_noprof (1,975,862,398 samples, 0.98%)</title><rect x="339.9" y="1941" width="11.6" height="15.0" fill="rgb(235,138,33)" rx="2" ry="2" />
<text  x="342.89" y="1951.5" ></text>
</g>
<g >
<title>_raw_spin_lock (218,008,068 samples, 0.11%)</title><rect x="272.3" y="1893" width="1.3" height="15.0" fill="rgb(239,160,38)" rx="2" ry="2" />
<text  x="275.31" y="1903.5" ></text>
</g>
<g >
<title>io_complete_rw_iopoll (239,453,986 samples, 0.12%)</title><rect x="193.7" y="1941" width="1.4" height="15.0" fill="rgb(254,228,54)" rx="2" ry="2" />
<text  x="196.65" y="1951.5" ></text>
</g>
<g >
<title>security_file_permission (553,457,624 samples, 0.28%)</title><rect x="1148.5" y="1909" width="3.2" height="15.0" fill="rgb(225,96,23)" rx="2" ry="2" />
<text  x="1151.47" y="1919.5" ></text>
</g>
<g >
<title>__rq_qos_throttle (1,900,556,621 samples, 0.95%)</title><rect x="849.4" y="1813" width="11.2" height="15.0" fill="rgb(229,110,26)" rx="2" ry="2" />
<text  x="852.40" y="1823.5" ></text>
</g>
<g >
<title>get_offset.part.0 (1,740,143,518 samples, 0.87%)</title><rect x="10.0" y="37" width="10.2" height="15.0" fill="rgb(212,36,8)" rx="2" ry="2" />
<text  x="13.00" y="47.5" ></text>
</g>
<g >
<title>radix_tree_lookup (167,334,968 samples, 0.08%)</title><rect x="702.4" y="1797" width="1.0" height="15.0" fill="rgb(230,118,28)" rx="2" ry="2" />
<text  x="705.44" y="1807.5" ></text>
</g>
<g >
<title>iomap_dio_bio_iter (51,033,390,387 samples, 25.44%)</title><rect x="613.3" y="1877" width="300.2" height="15.0" fill="rgb(236,145,34)" rx="2" ry="2" />
<text  x="616.27" y="1887.5" >iomap_dio_bio_iter</text>
</g>
<g >
<title>bdev_count_inflight (128,992,677 samples, 0.06%)</title><rect x="909.9" y="1797" width="0.7" height="15.0" fill="rgb(209,22,5)" rx="2" ry="2" />
<text  x="912.86" y="1807.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="837" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="847.5" ></text>
</g>
<g >
<title>__io_read (116,579,955,921 samples, 58.12%)</title><rect x="466.0" y="1941" width="685.7" height="15.0" fill="rgb(215,49,11)" rx="2" ry="2" />
<text  x="468.95" y="1951.5" >__io_read</text>
</g>
<g >
<title>wbt_track (743,017,426 samples, 0.37%)</title><rect x="864.1" y="1797" width="4.3" height="15.0" fill="rgb(205,2,0)" rx="2" ry="2" />
<text  x="867.06" y="1807.5" ></text>
</g>
<g >
<title>blk_mq_end_request_batch (23,709,729,459 samples, 11.82%)</title><rect x="106.9" y="1957" width="139.5" height="15.0" fill="rgb(254,225,53)" rx="2" ry="2" />
<text  x="109.93" y="1967.5" >blk_mq_end_reques..</text>
</g>
<g >
<title>blk_try_merge (686,257,215 samples, 0.34%)</title><rect x="892.8" y="1781" width="4.0" height="15.0" fill="rgb(235,142,34)" rx="2" ry="2" />
<text  x="895.76" y="1791.5" ></text>
</g>
<g >
<title>io_prep_read_fixed (121,277,378 samples, 0.06%)</title><rect x="1178.0" y="1973" width="0.7" height="15.0" fill="rgb(218,64,15)" rx="2" ry="2" />
<text  x="1180.96" y="1983.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1093" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1103.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1813" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1823.5" ></text>
</g>
<g >
<title>kmem_cache_alloc_noprof (605,667,599 samples, 0.30%)</title><rect x="706.4" y="1829" width="3.6" height="15.0" fill="rgb(248,200,47)" rx="2" ry="2" />
<text  x="709.43" y="1839.5" ></text>
</g>
<g >
<title>blk_mq_dispatch_queue_requests (13,150,774,975 samples, 6.56%)</title><rect x="355.3" y="1925" width="77.3" height="15.0" fill="rgb(216,50,12)" rx="2" ry="2" />
<text  x="358.27" y="1935.5" >blk_mq_d..</text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1349" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1359.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="917" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="927.5" ></text>
</g>
<g >
<title>mempool_free_bulk (45,288,475 samples, 0.02%)</title><rect x="161.0" y="1909" width="0.3" height="15.0" fill="rgb(242,171,40)" rx="2" ry="2" />
<text  x="164.03" y="1919.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1253" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1263.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1301" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1311.5" ></text>
</g>
<g >
<title>__pcs_replace_empty_main (268,660,930 samples, 0.13%)</title><rect x="349.9" y="1925" width="1.6" height="15.0" fill="rgb(229,114,27)" rx="2" ry="2" />
<text  x="352.93" y="1935.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="485" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="495.5" ></text>
</g>
<g >
<title>ext4_inode_journal_mode (836,718,472 samples, 0.42%)</title><rect x="511.9" y="1877" width="4.9" height="15.0" fill="rgb(206,7,1)" rx="2" ry="2" />
<text  x="514.89" y="1887.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="677" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="687.5" ></text>
</g>
<g >
<title>nvme_complete_batch_req (923,455,304 samples, 0.46%)</title><rect x="289.5" y="1941" width="5.4" height="15.0" fill="rgb(217,58,13)" rx="2" ry="2" />
<text  x="292.48" y="1951.5" ></text>
</g>
<g >
<title>bio_free (94,410,360 samples, 0.05%)</title><rect x="153.5" y="1925" width="0.5" height="15.0" fill="rgb(221,74,17)" rx="2" ry="2" />
<text  x="156.47" y="1935.5" ></text>
</g>
<g >
<title>dma_map_page_attrs (292,475,583 samples, 0.15%)</title><rect x="397.3" y="1877" width="1.7" height="15.0" fill="rgb(218,64,15)" rx="2" ry="2" />
<text  x="400.28" y="1887.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1733" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1743.5" ></text>
</g>
<g >
<title>__pcs_replace_full_main (140,470,132 samples, 0.07%)</title><rect x="99.5" y="1925" width="0.8" height="15.0" fill="rgb(230,119,28)" rx="2" ry="2" />
<text  x="102.46" y="1935.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1925" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1935.5" ></text>
</g>
<g >
<title>io_issue_sqe (126,686,887,144 samples, 63.15%)</title><rect x="432.7" y="1973" width="745.3" height="15.0" fill="rgb(243,175,42)" rx="2" ry="2" />
<text  x="435.74" y="1983.5" >io_issue_sqe</text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="597" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="607.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1173" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1183.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1381" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1391.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="389" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="399.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1765" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1775.5" ></text>
</g>
<g >
<title>bio_associate_blkg_from_css (5,843,814,546 samples, 2.91%)</title><rect x="669.0" y="1813" width="34.4" height="15.0" fill="rgb(225,94,22)" rx="2" ry="2" />
<text  x="672.05" y="1823.5" >bi..</text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1893" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1903.5" ></text>
</g>
<g >
<title>dma_map_phys (1,224,304,522 samples, 0.61%)</title><rect x="399.0" y="1877" width="7.2" height="15.0" fill="rgb(235,139,33)" rx="2" ry="2" />
<text  x="402.00" y="1887.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1013" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1023.5" ></text>
</g>
<g >
<title>bio_poll (3,718,344,469 samples, 1.85%)</title><rect x="255.2" y="1941" width="21.8" height="15.0" fill="rgb(235,140,33)" rx="2" ry="2" />
<text  x="258.17" y="1951.5" >b..</text>
</g>
<g >
<title>__pcs_replace_full_main (29,171,295 samples, 0.01%)</title><rect x="160.9" y="1893" width="0.1" height="15.0" fill="rgb(230,119,28)" rx="2" ry="2" />
<text  x="163.86" y="1903.5" ></text>
</g>
<g >
<title>[unknown] (3,121,865,120 samples, 1.56%)</title><rect x="10.0" y="69" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="79.5" ></text>
</g>
<g >
<title>io_submit_sqes (149,620,620,008 samples, 74.59%)</title><rect x="298.5" y="1989" width="880.2" height="15.0" fill="rgb(209,18,4)" rx="2" ry="2" />
<text  x="301.55" y="1999.5" >io_submit_sqes</text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1989" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1999.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="2005" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="2015.5" ></text>
</g>
<g >
<title>nvme_pci_complete_batch (3,655,417,870 samples, 1.82%)</title><rect x="277.0" y="1957" width="21.5" height="15.0" fill="rgb(245,185,44)" rx="2" ry="2" />
<text  x="280.04" y="1967.5" >n..</text>
</g>
<g >
<title>__rq_qos_issue (796,770,690 samples, 0.40%)</title><rect x="388.6" y="1861" width="4.7" height="15.0" fill="rgb(230,115,27)" rx="2" ry="2" />
<text  x="391.64" y="1871.5" ></text>
</g>
<g >
<title>__blk_flush_plug (13,244,428,583 samples, 6.60%)</title><rect x="354.7" y="1957" width="77.9" height="15.0" fill="rgb(217,57,13)" rx="2" ry="2" />
<text  x="357.72" y="1967.5" >__blk_flu..</text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1125" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1135.5" ></text>
</g>
<g >
<title>__rcu_read_lock (30,706,640 samples, 0.02%)</title><rect x="825.3" y="1797" width="0.2" height="15.0" fill="rgb(220,69,16)" rx="2" ry="2" />
<text  x="828.27" y="1807.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1653" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1663.5" ></text>
</g>
<g >
<title>iomap_dio_rw (98,718,333,614 samples, 49.21%)</title><rect x="516.8" y="1909" width="580.7" height="15.0" fill="rgb(240,161,38)" rx="2" ry="2" />
<text  x="519.81" y="1919.5" >iomap_dio_rw</text>
</g>
<g >
<title>__list_del_entry_valid_or_report (23,028,084 samples, 0.01%)</title><rect x="227.4" y="1861" width="0.2" height="15.0" fill="rgb(243,176,42)" rx="2" ry="2" />
<text  x="230.42" y="1871.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1285" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1295.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1477" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1487.5" ></text>
</g>
<g >
<title>blk_account_io_completion.part.66 (436,745,357 samples, 0.22%)</title><rect x="182.8" y="1941" width="2.6" height="15.0" fill="rgb(249,203,48)" rx="2" ry="2" />
<text  x="185.81" y="1951.5" ></text>
</g>
<g >
<title>__rcu_read_lock (132,029,584 samples, 0.07%)</title><rect x="177.3" y="1925" width="0.7" height="15.0" fill="rgb(220,69,16)" rx="2" ry="2" />
<text  x="180.25" y="1935.5" ></text>
</g>
<g >
<title>blk_add_rq_to_plug (1,212,057,721 samples, 0.60%)</title><rect x="870.3" y="1813" width="7.1" height="15.0" fill="rgb(243,175,41)" rx="2" ry="2" />
<text  x="873.30" y="1823.5" ></text>
</g>
<g >
<title>[unknown] (3,122,574,652 samples, 1.56%)</title><rect x="10.0" y="117" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="127.5" ></text>
</g>
<g >
<title>blk_finish_plug (13,259,014,476 samples, 6.61%)</title><rect x="354.6" y="1973" width="78.0" height="15.0" fill="rgb(231,119,28)" rx="2" ry="2" />
<text  x="357.64" y="1983.5" >blk_finis..</text>
</g>
<g >
<title>submit_bio_noacct (2,019,588,772 samples, 1.01%)</title><rect x="750.1" y="1861" width="11.8" height="15.0" fill="rgb(211,30,7)" rx="2" ry="2" />
<text  x="753.05" y="1871.5" ></text>
</g>
<g >
<title>up_read (5,110,617,190 samples, 2.55%)</title><rect x="1097.5" y="1909" width="30.1" height="15.0" fill="rgb(209,18,4)" rx="2" ry="2" />
<text  x="1100.51" y="1919.5" >up..</text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="1557" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1567.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="469" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="479.5" ></text>
</g>
<g >
<title>_raw_spin_lock (94,416,278 samples, 0.05%)</title><rect x="432.1" y="1877" width="0.5" height="15.0" fill="rgb(239,160,38)" rx="2" ry="2" />
<text  x="435.07" y="1887.5" ></text>
</g>
<g >
<title>[unknown] (3,123,342,755 samples, 1.56%)</title><rect x="10.0" y="517" width="18.4" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="527.5" ></text>
</g>
<g >
<title>nvme_prep_rq (10,371,193,312 samples, 5.17%)</title><rect x="359.9" y="1893" width="61.0" height="15.0" fill="rgb(254,227,54)" rx="2" ry="2" />
<text  x="362.94" y="1903.5" >nvme_p..</text>
</g>
<g >
<title>blk_stat_add (888,893,094 samples, 0.44%)</title><rect x="188.4" y="1941" width="5.3" height="15.0" fill="rgb(227,103,24)" rx="2" ry="2" />
<text  x="191.42" y="1951.5" ></text>
</g>
<g >
<title>_raw_spin_lock_irqsave (45,285,357 samples, 0.02%)</title><rect x="227.6" y="1861" width="0.2" height="15.0" fill="rgb(247,195,46)" rx="2" ry="2" />
<text  x="230.56" y="1871.5" ></text>
</g>
<g >
<title>nvme_setup_cmd (2,507,063,928 samples, 1.25%)</title><rect x="406.2" y="1877" width="14.7" height="15.0" fill="rgb(243,175,41)" rx="2" ry="2" />
<text  x="409.20" y="1887.5" ></text>
</g>
</g>
</svg>

[-- Attachment #3: iomap_fast.svg --]
[-- Type: application/octet-stream, Size: 72140 bytes --]

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" width="1200" height="2134" onload="init(evt)" viewBox="0 0 1200 2134" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Flame graph stack visualization. See https://github.com/brendangregg/FlameGraph for latest version, and http://www.brendangregg.com/flamegraphs.html for examples. -->
<!-- NOTES:  -->
<defs>
	<linearGradient id="background" y1="0" y2="1" x1="0" x2="0" >
		<stop stop-color="#eeeeee" offset="5%" />
		<stop stop-color="#eeeeb0" offset="95%" />
	</linearGradient>
</defs>
<style type="text/css">
	text { font-family:Verdana; font-size:12px; fill:rgb(0,0,0); }
	#search, #ignorecase { opacity:0.1; cursor:pointer; }
	#search:hover, #search.show, #ignorecase:hover, #ignorecase.show { opacity:1; }
	#subtitle { text-anchor:middle; font-color:rgb(160,160,160); }
	#title { text-anchor:middle; font-size:17px}
	#unzoom { cursor:pointer; }
	#frames > *:hover { stroke:black; stroke-width:0.5; cursor:pointer; }
	.hide { display:none; }
	.parent { opacity:0.5; }
</style>
<script type="text/ecmascript">
<![CDATA[
	"use strict";
	var details, searchbtn, unzoombtn, matchedtxt, svg, searching, currentSearchTerm, ignorecase, ignorecaseBtn;
	function init(evt) {
		details = document.getElementById("details").firstChild;
		searchbtn = document.getElementById("search");
		ignorecaseBtn = document.getElementById("ignorecase");
		unzoombtn = document.getElementById("unzoom");
		matchedtxt = document.getElementById("matched");
		svg = document.getElementsByTagName("svg")[0];
		searching = 0;
		currentSearchTerm = null;

		// use GET parameters to restore a flamegraphs state.
		var params = get_params();
		if (params.x && params.y)
			zoom(find_group(document.querySelector('[x="' + params.x + '"][y="' + params.y + '"]')));
                if (params.s) search(params.s);
	}

	// event listeners
	window.addEventListener("click", function(e) {
		var target = find_group(e.target);
		if (target) {
			if (target.nodeName == "a") {
				if (e.ctrlKey === false) return;
				e.preventDefault();
			}
			if (target.classList.contains("parent")) unzoom(true);
			zoom(target);
			if (!document.querySelector('.parent')) {
				// we have basically done a clearzoom so clear the url
				var params = get_params();
				if (params.x) delete params.x;
				if (params.y) delete params.y;
				history.replaceState(null, null, parse_params(params));
				unzoombtn.classList.add("hide");
				return;
			}

			// set parameters for zoom state
			var el = target.querySelector("rect");
			if (el && el.attributes && el.attributes.y && el.attributes._orig_x) {
				var params = get_params()
				params.x = el.attributes._orig_x.value;
				params.y = el.attributes.y.value;
				history.replaceState(null, null, parse_params(params));
			}
		}
		else if (e.target.id == "unzoom") clearzoom();
		else if (e.target.id == "search") search_prompt();
		else if (e.target.id == "ignorecase") toggle_ignorecase();
	}, false)

	// mouse-over for info
	// show
	window.addEventListener("mouseover", function(e) {
		var target = find_group(e.target);
		if (target) details.nodeValue = "Function: " + g_to_text(target);
	}, false)

	// clear
	window.addEventListener("mouseout", function(e) {
		var target = find_group(e.target);
		if (target) details.nodeValue = ' ';
	}, false)

	// ctrl-F for search
	// ctrl-I to toggle case-sensitive search
	window.addEventListener("keydown",function (e) {
		if (e.keyCode === 114 || (e.ctrlKey && e.keyCode === 70)) {
			e.preventDefault();
			search_prompt();
		}
		else if (e.ctrlKey && e.keyCode === 73) {
			e.preventDefault();
			toggle_ignorecase();
		}
	}, false)

	// functions
	function get_params() {
		var params = {};
		var paramsarr = window.location.search.substr(1).split('&');
		for (var i = 0; i < paramsarr.length; ++i) {
			var tmp = paramsarr[i].split("=");
			if (!tmp[0] || !tmp[1]) continue;
			params[tmp[0]]  = decodeURIComponent(tmp[1]);
		}
		return params;
	}
	function parse_params(params) {
		var uri = "?";
		for (var key in params) {
			uri += key + '=' + encodeURIComponent(params[key]) + '&';
		}
		if (uri.slice(-1) == "&")
			uri = uri.substring(0, uri.length - 1);
		if (uri == '?')
			uri = window.location.href.split('?')[0];
		return uri;
	}
	function find_child(node, selector) {
		var children = node.querySelectorAll(selector);
		if (children.length) return children[0];
	}
	function find_group(node) {
		var parent = node.parentElement;
		if (!parent) return;
		if (parent.id == "frames") return node;
		return find_group(parent);
	}
	function orig_save(e, attr, val) {
		if (e.attributes["_orig_" + attr] != undefined) return;
		if (e.attributes[attr] == undefined) return;
		if (val == undefined) val = e.attributes[attr].value;
		e.setAttribute("_orig_" + attr, val);
	}
	function orig_load(e, attr) {
		if (e.attributes["_orig_"+attr] == undefined) return;
		e.attributes[attr].value = e.attributes["_orig_" + attr].value;
		e.removeAttribute("_orig_"+attr);
	}
	function g_to_text(e) {
		var text = find_child(e, "title").firstChild.nodeValue;
		return (text)
	}
	function g_to_func(e) {
		var func = g_to_text(e);
		// if there's any manipulation we want to do to the function
		// name before it's searched, do it here before returning.
		return (func);
	}
	function update_text(e) {
		var r = find_child(e, "rect");
		var t = find_child(e, "text");
		var w = parseFloat(r.attributes.width.value) -3;
		var txt = find_child(e, "title").textContent.replace(/\([^(]*\)$/,"");
		t.attributes.x.value = parseFloat(r.attributes.x.value) + 3;

		// Smaller than this size won't fit anything
		if (w < 2 * 12 * 0.59) {
			t.textContent = "";
			return;
		}

		t.textContent = txt;
		var sl = t.getSubStringLength(0, txt.length);
		// check if only whitespace or if we can fit the entire string into width w
		if (/^ *$/.test(txt) || sl < w)
			return;

		// this isn't perfect, but gives a good starting point
		// and avoids calling getSubStringLength too often
		var start = Math.floor((w/sl) * txt.length);
		for (var x = start; x > 0; x = x-2) {
			if (t.getSubStringLength(0, x + 2) <= w) {
				t.textContent = txt.substring(0, x) + "..";
				return;
			}
		}
		t.textContent = "";
	}

	// zoom
	function zoom_reset(e) {
		if (e.attributes != undefined) {
			orig_load(e, "x");
			orig_load(e, "width");
		}
		if (e.childNodes == undefined) return;
		for (var i = 0, c = e.childNodes; i < c.length; i++) {
			zoom_reset(c[i]);
		}
	}
	function zoom_child(e, x, ratio) {
		if (e.attributes != undefined) {
			if (e.attributes.x != undefined) {
				orig_save(e, "x");
				e.attributes.x.value = (parseFloat(e.attributes.x.value) - x - 10) * ratio + 10;
				if (e.tagName == "text")
					e.attributes.x.value = find_child(e.parentNode, "rect[x]").attributes.x.value + 3;
			}
			if (e.attributes.width != undefined) {
				orig_save(e, "width");
				e.attributes.width.value = parseFloat(e.attributes.width.value) * ratio;
			}
		}

		if (e.childNodes == undefined) return;
		for (var i = 0, c = e.childNodes; i < c.length; i++) {
			zoom_child(c[i], x - 10, ratio);
		}
	}
	function zoom_parent(e) {
		if (e.attributes) {
			if (e.attributes.x != undefined) {
				orig_save(e, "x");
				e.attributes.x.value = 10;
			}
			if (e.attributes.width != undefined) {
				orig_save(e, "width");
				e.attributes.width.value = parseInt(svg.width.baseVal.value) - (10 * 2);
			}
		}
		if (e.childNodes == undefined) return;
		for (var i = 0, c = e.childNodes; i < c.length; i++) {
			zoom_parent(c[i]);
		}
	}
	function zoom(node) {
		var attr = find_child(node, "rect").attributes;
		var width = parseFloat(attr.width.value);
		var xmin = parseFloat(attr.x.value);
		var xmax = parseFloat(xmin + width);
		var ymin = parseFloat(attr.y.value);
		var ratio = (svg.width.baseVal.value - 2 * 10) / width;

		// XXX: Workaround for JavaScript float issues (fix me)
		var fudge = 0.0001;

		unzoombtn.classList.remove("hide");

		var el = document.getElementById("frames").children;
		for (var i = 0; i < el.length; i++) {
			var e = el[i];
			var a = find_child(e, "rect").attributes;
			var ex = parseFloat(a.x.value);
			var ew = parseFloat(a.width.value);
			var upstack;
			// Is it an ancestor
			if (0 == 0) {
				upstack = parseFloat(a.y.value) > ymin;
			} else {
				upstack = parseFloat(a.y.value) < ymin;
			}
			if (upstack) {
				// Direct ancestor
				if (ex <= xmin && (ex+ew+fudge) >= xmax) {
					e.classList.add("parent");
					zoom_parent(e);
					update_text(e);
				}
				// not in current path
				else
					e.classList.add("hide");
			}
			// Children maybe
			else {
				// no common path
				if (ex < xmin || ex + fudge >= xmax) {
					e.classList.add("hide");
				}
				else {
					zoom_child(e, xmin, ratio);
					update_text(e);
				}
			}
		}
		search();
	}
	function unzoom(dont_update_text) {
		unzoombtn.classList.add("hide");
		var el = document.getElementById("frames").children;
		for(var i = 0; i < el.length; i++) {
			el[i].classList.remove("parent");
			el[i].classList.remove("hide");
			zoom_reset(el[i]);
			if(!dont_update_text) update_text(el[i]);
		}
		search();
	}
	function clearzoom() {
		unzoom();

		// remove zoom state
		var params = get_params();
		if (params.x) delete params.x;
		if (params.y) delete params.y;
		history.replaceState(null, null, parse_params(params));
	}

	// search
	function toggle_ignorecase() {
		ignorecase = !ignorecase;
		if (ignorecase) {
			ignorecaseBtn.classList.add("show");
		} else {
			ignorecaseBtn.classList.remove("show");
		}
		reset_search();
		search();
	}
	function reset_search() {
		var el = document.querySelectorAll("#frames rect");
		for (var i = 0; i < el.length; i++) {
			orig_load(el[i], "fill")
		}
		var params = get_params();
		delete params.s;
		history.replaceState(null, null, parse_params(params));
	}
	function search_prompt() {
		if (!searching) {
			var term = prompt("Enter a search term (regexp " +
			    "allowed, eg: ^ext4_)"
			    + (ignorecase ? ", ignoring case" : "")
			    + "\nPress Ctrl-i to toggle case sensitivity", "");
			if (term != null) search(term);
		} else {
			reset_search();
			searching = 0;
			currentSearchTerm = null;
			searchbtn.classList.remove("show");
			searchbtn.firstChild.nodeValue = "Search"
			matchedtxt.classList.add("hide");
			matchedtxt.firstChild.nodeValue = ""
		}
	}
	function search(term) {
		if (term) currentSearchTerm = term;
		if (currentSearchTerm === null) return;

		var re = new RegExp(currentSearchTerm, ignorecase ? 'i' : '');
		var el = document.getElementById("frames").children;
		var matches = new Object();
		var maxwidth = 0;
		for (var i = 0; i < el.length; i++) {
			var e = el[i];
			var func = g_to_func(e);
			var rect = find_child(e, "rect");
			if (func == null || rect == null)
				continue;

			// Save max width. Only works as we have a root frame
			var w = parseFloat(rect.attributes.width.value);
			if (w > maxwidth)
				maxwidth = w;

			if (func.match(re)) {
				// highlight
				var x = parseFloat(rect.attributes.x.value);
				orig_save(rect, "fill");
				rect.attributes.fill.value = "rgb(230,0,230)";

				// remember matches
				if (matches[x] == undefined) {
					matches[x] = w;
				} else {
					if (w > matches[x]) {
						// overwrite with parent
						matches[x] = w;
					}
				}
				searching = 1;
			}
		}
		if (!searching)
			return;
		var params = get_params();
		params.s = currentSearchTerm;
		history.replaceState(null, null, parse_params(params));

		searchbtn.classList.add("show");
		searchbtn.firstChild.nodeValue = "Reset Search";

		// calculate percent matched, excluding vertical overlap
		var count = 0;
		var lastx = -1;
		var lastw = 0;
		var keys = Array();
		for (k in matches) {
			if (matches.hasOwnProperty(k))
				keys.push(k);
		}
		// sort the matched frames by their x location
		// ascending, then width descending
		keys.sort(function(a, b){
			return a - b;
		});
		// Step through frames saving only the biggest bottom-up frames
		// thanks to the sort order. This relies on the tree property
		// where children are always smaller than their parents.
		var fudge = 0.0001;	// JavaScript floating point
		for (var k in keys) {
			var x = parseFloat(keys[k]);
			var w = matches[keys[k]];
			if (x >= lastx + lastw - fudge) {
				count += w;
				lastx = x;
				lastw = w;
			}
		}
		// display matched percent
		matchedtxt.classList.remove("hide");
		var pct = 100 * count / maxwidth;
		if (pct != 100) pct = pct.toFixed(1)
		matchedtxt.firstChild.nodeValue = "Matched: " + pct + "%";
	}
]]>
</script>
<rect x="0.0" y="0" width="1200.0" height="2134.0" fill="url(#background)"  />
<text id="title" x="600.00" y="24" >Flame Graph</text>
<text id="details" x="10.00" y="2117" > </text>
<text id="unzoom" x="10.00" y="24" class="hide">Reset Zoom</text>
<text id="search" x="1090.00" y="24" >Search</text>
<text id="ignorecase" x="1174.00" y="24" >ic</text>
<text id="matched" x="1090.00" y="2117" > </text>
<g id="frames">
<g >
<title>down_read_trylock (1,086,031,724 samples, 1.28%)</title><rect x="564.9" y="1909" width="15.1" height="15.0" fill="rgb(219,66,15)" rx="2" ry="2" />
<text  x="567.93" y="1919.5" ></text>
</g>
<g >
<title>syscall_return_via_sysret (13,814,392 samples, 0.02%)</title><rect x="1189.8" y="2037" width="0.2" height="15.0" fill="rgb(229,113,27)" rx="2" ry="2" />
<text  x="1192.81" y="2047.5" ></text>
</g>
<g >
<title>_raw_spin_unlock_irqrestore (131,250,844 samples, 0.15%)</title><rect x="987.8" y="1781" width="1.8" height="15.0" fill="rgb(228,106,25)" rx="2" ry="2" />
<text  x="990.77" y="1791.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1477" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1487.5" >[..</text>
</g>
<g >
<title>blk_mq_complete_request_remote (306,201,175 samples, 0.36%)</title><rect x="316.3" y="1893" width="4.2" height="15.0" fill="rgb(235,140,33)" rx="2" ry="2" />
<text  x="319.29" y="1903.5" ></text>
</g>
<g >
<title>blk_add_timer (399,107,317 samples, 0.47%)</title><rect x="460.6" y="1861" width="5.5" height="15.0" fill="rgb(224,91,21)" rx="2" ry="2" />
<text  x="463.59" y="1871.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1221" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1231.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1013" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1023.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="373" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="383.5" >[..</text>
</g>
<g >
<title>percpu_counter_add_batch (970,176,177 samples, 1.14%)</title><rect x="823.5" y="1829" width="13.5" height="15.0" fill="rgb(241,166,39)" rx="2" ry="2" />
<text  x="826.53" y="1839.5" ></text>
</g>
<g >
<title>__rq_qos_done (413,697,486 samples, 0.49%)</title><rect x="204.6" y="1941" width="5.7" height="15.0" fill="rgb(226,98,23)" rx="2" ry="2" />
<text  x="207.56" y="1951.5" ></text>
</g>
<g >
<title>blk_integrity_merge_bio (166,564,100 samples, 0.20%)</title><rect x="1052.0" y="1781" width="2.3" height="15.0" fill="rgb(209,20,5)" rx="2" ry="2" />
<text  x="1054.97" y="1791.5" ></text>
</g>
<g >
<title>__rq_qos_throttle (947,071,517 samples, 1.12%)</title><rect x="1003.2" y="1829" width="13.1" height="15.0" fill="rgb(229,110,26)" rx="2" ry="2" />
<text  x="1006.15" y="1839.5" ></text>
</g>
<g >
<title>__list_add_valid_or_report (287,063,475 samples, 0.34%)</title><rect x="515.7" y="1957" width="4.0" height="15.0" fill="rgb(215,46,11)" rx="2" ry="2" />
<text  x="518.69" y="1967.5" ></text>
</g>
<g >
<title>_raw_spin_lock (62,161,660 samples, 0.07%)</title><rect x="441.4" y="1877" width="0.8" height="15.0" fill="rgb(239,160,38)" rx="2" ry="2" />
<text  x="444.36" y="1887.5" ></text>
</g>
<g >
<title>submit_bio (264,793,157 samples, 0.31%)</title><rect x="861.6" y="1877" width="3.7" height="15.0" fill="rgb(207,13,3)" rx="2" ry="2" />
<text  x="864.62" y="1887.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1989" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1999.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="965" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="975.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1861" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1871.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1557" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1567.5" >[..</text>
</g>
<g >
<title>dma_unmap_phys (735,258,468 samples, 0.87%)</title><rect x="82.4" y="1941" width="10.2" height="15.0" fill="rgb(218,64,15)" rx="2" ry="2" />
<text  x="85.42" y="1951.5" ></text>
</g>
<g >
<title>io_iopoll_check (19,653,838,624 samples, 23.15%)</title><rect x="47.3" y="1989" width="273.3" height="15.0" fill="rgb(215,46,11)" rx="2" ry="2" />
<text  x="50.34" y="1999.5" >io_iopoll_check</text>
</g>
<g >
<title>barn_replace_empty_sheaf (78,294,487 samples, 0.09%)</title><rect x="378.7" y="1909" width="1.1" height="15.0" fill="rgb(223,84,20)" rx="2" ry="2" />
<text  x="381.69" y="1919.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1701" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1711.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="693" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="703.5" >[..</text>
</g>
<g >
<title>blk_account_io_completion.part.67 (426,117,370 samples, 0.50%)</title><rect x="225.6" y="1941" width="5.9" height="15.0" fill="rgb(242,173,41)" rx="2" ry="2" />
<text  x="228.55" y="1951.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1349" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1359.5" >[..</text>
</g>
<g >
<title>submitter_uring_fn (83,133,984,839 samples, 97.94%)</title><rect x="34.3" y="2053" width="1155.7" height="15.0" fill="rgb(218,61,14)" rx="2" ry="2" />
<text  x="37.31" y="2063.5" >submitter_uring_fn</text>
</g>
<g >
<title>__pfx_nvme_put_ns_head (68,310,719 samples, 0.08%)</title><rect x="440.4" y="1877" width="1.0" height="15.0" fill="rgb(215,47,11)" rx="2" ry="2" />
<text  x="443.41" y="1887.5" ></text>
</g>
<g >
<title>entry_SYSCALL_64 (110,387,544 samples, 0.13%)</title><rect x="43.6" y="2037" width="1.5" height="15.0" fill="rgb(239,156,37)" rx="2" ry="2" />
<text  x="46.57" y="2047.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1957" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1967.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1413" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1423.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="501" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="511.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="885" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="895.5" >[..</text>
</g>
<g >
<title>_find_first_zero_bit (96,705,618 samples, 0.11%)</title><rect x="976.7" y="1781" width="1.3" height="15.0" fill="rgb(244,181,43)" rx="2" ry="2" />
<text  x="979.67" y="1791.5" ></text>
</g>
<g >
<title>__io_read (43,238,183,094 samples, 50.94%)</title><rect x="535.3" y="1941" width="601.1" height="15.0" fill="rgb(215,49,11)" rx="2" ry="2" />
<text  x="538.34" y="1951.5" >__io_read</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="149" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="159.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="165" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="175.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="741" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="751.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1653" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1663.5" >[..</text>
</g>
<g >
<title>update_io_ticks (379,194,202 samples, 0.45%)</title><rect x="1070.0" y="1829" width="5.3" height="15.0" fill="rgb(235,141,33)" rx="2" ry="2" />
<text  x="1072.99" y="1839.5" ></text>
</g>
<g >
<title>__rcu_read_unlock (9,209,031 samples, 0.01%)</title><rect x="1003.0" y="1829" width="0.2" height="15.0" fill="rgb(253,224,53)" rx="2" ry="2" />
<text  x="1006.03" y="1839.5" ></text>
</g>
<g >
<title>[button.ko] (1,899,533,424 samples, 2.24%)</title><rect x="294.1" y="1909" width="26.4" height="15.0" fill="rgb(254,226,54)" rx="2" ry="2" />
<text  x="297.14" y="1919.5" >[..</text>
</g>
<g >
<title>__kmalloc_noprof (921,024,731 samples, 1.09%)</title><rect x="367.0" y="1941" width="12.8" height="15.0" fill="rgb(235,138,33)" rx="2" ry="2" />
<text  x="369.98" y="1951.5" ></text>
</g>
<g >
<title>update_io_ticks (386,767,936 samples, 0.46%)</title><rect x="277.5" y="1941" width="5.4" height="15.0" fill="rgb(235,141,33)" rx="2" ry="2" />
<text  x="280.52" y="1951.5" ></text>
</g>
<g >
<title>io_uring (84,882,428,926 samples, 100.00%)</title><rect x="10.0" y="2069" width="1180.0" height="15.0" fill="rgb(208,13,3)" rx="2" ry="2" />
<text  x="13.00" y="2079.5" >io_uring</text>
</g>
<g >
<title>__rcu_read_unlock (70,609,372 samples, 0.08%)</title><rect x="492.3" y="1909" width="1.0" height="15.0" fill="rgb(253,224,53)" rx="2" ry="2" />
<text  x="495.32" y="1919.5" ></text>
</g>
<g >
<title>io_init_rw_fixed (2,129,398,368 samples, 2.51%)</title><rect x="1139.9" y="1941" width="29.6" height="15.0" fill="rgb(244,182,43)" rx="2" ry="2" />
<text  x="1142.89" y="1951.5" >io..</text>
</g>
<g >
<title>blk_mq_submit_bio (12,559,969,245 samples, 14.80%)</title><rect x="900.7" y="1845" width="174.6" height="15.0" fill="rgb(224,89,21)" rx="2" ry="2" />
<text  x="903.66" y="1855.5" >blk_mq_submit_bio</text>
</g>
<g >
<title>_raw_spin_lock_irqsave (41,456,984 samples, 0.05%)</title><rect x="379.1" y="1893" width="0.6" height="15.0" fill="rgb(247,195,46)" rx="2" ry="2" />
<text  x="382.13" y="1903.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="117" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="127.5" >[..</text>
</g>
<g >
<title>_raw_read_unlock (1,327,736,488 samples, 1.56%)</title><rect x="805.0" y="1829" width="18.5" height="15.0" fill="rgb(217,57,13)" rx="2" ry="2" />
<text  x="808.04" y="1839.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="2005" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="2015.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="213" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="223.5" >[..</text>
</g>
<g >
<title>blk_mq_dispatch_queue_requests (7,811,721,024 samples, 9.20%)</title><rect x="384.7" y="1925" width="108.6" height="15.0" fill="rgb(216,50,12)" rx="2" ry="2" />
<text  x="387.71" y="1935.5" >blk_mq_dispat..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1813" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1823.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="949" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="959.5" >[..</text>
</g>
<g >
<title>bio_iov_iter_get_pages (1,412,137,178 samples, 1.66%)</title><rect x="666.2" y="1877" width="19.7" height="15.0" fill="rgb(228,107,25)" rx="2" ry="2" />
<text  x="669.23" y="1887.5" ></text>
</g>
<g >
<title>mutex_unlock (1,327,562,319 samples, 1.56%)</title><rect x="1170.7" y="1989" width="18.5" height="15.0" fill="rgb(251,212,50)" rx="2" ry="2" />
<text  x="1173.74" y="1999.5" ></text>
</g>
<g >
<title>nvme_host_path_error (41,451,780 samples, 0.05%)</title><rect x="482.6" y="1877" width="0.6" height="15.0" fill="rgb(211,31,7)" rx="2" ry="2" />
<text  x="485.63" y="1887.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1301" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1311.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="613" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="623.5" >[..</text>
</g>
<g >
<title>blk_mq_rq_ctx_init.isra.60 (959,403,093 samples, 1.13%)</title><rect x="989.6" y="1813" width="13.3" height="15.0" fill="rgb(218,61,14)" rx="2" ry="2" />
<text  x="992.59" y="1823.5" ></text>
</g>
<g >
<title>ext4_set_iomap (1,574,930,047 samples, 1.86%)</title><rect x="837.0" y="1861" width="21.9" height="15.0" fill="rgb(229,110,26)" rx="2" ry="2" />
<text  x="840.01" y="1871.5" >e..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="69" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="79.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="549" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="559.5" >[..</text>
</g>
<g >
<title>__list_del_entry_valid_or_report (11,513,407 samples, 0.01%)</title><rect x="379.0" y="1893" width="0.1" height="15.0" fill="rgb(243,176,42)" rx="2" ry="2" />
<text  x="381.97" y="1903.5" ></text>
</g>
<g >
<title>blk_attempt_plug_merge (1,528,133,355 samples, 1.80%)</title><rect x="1036.6" y="1829" width="21.3" height="15.0" fill="rgb(242,173,41)" rx="2" ry="2" />
<text  x="1039.65" y="1839.5" >b..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1061" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1071.5" >[..</text>
</g>
<g >
<title>_raw_spin_lock (134,318,478 samples, 0.16%)</title><rect x="314.4" y="1893" width="1.9" height="15.0" fill="rgb(239,160,38)" rx="2" ry="2" />
<text  x="317.41" y="1903.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1173" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1183.5" >[..</text>
</g>
<g >
<title>__submit_bio (13,244,583,068 samples, 15.60%)</title><rect x="891.1" y="1861" width="184.2" height="15.0" fill="rgb(230,117,28)" rx="2" ry="2" />
<text  x="894.14" y="1871.5" >__submit_bio</text>
</g>
<g >
<title>io_issue_sqe (48,630,353,536 samples, 57.29%)</title><rect x="493.5" y="1973" width="676.0" height="15.0" fill="rgb(243,175,42)" rx="2" ry="2" />
<text  x="496.46" y="1983.5" >io_issue_sqe</text>
</g>
<g >
<title>iocb_bio_iopoll (1,936,371,021 samples, 2.28%)</title><rect x="293.6" y="1957" width="27.0" height="15.0" fill="rgb(208,16,3)" rx="2" ry="2" />
<text  x="296.64" y="1967.5" >i..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1733" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1743.5" >[..</text>
</g>
<g >
<title>entry_SYSCALL_64_after_hwframe (82,311,064,292 samples, 96.97%)</title><rect x="45.1" y="2037" width="1144.3" height="15.0" fill="rgb(218,63,15)" rx="2" ry="2" />
<text  x="48.11" y="2047.5" >entry_SYSCALL_64_after_hwframe</text>
</g>
<g >
<title>io_cqe_cache_refill (9,978,211 samples, 0.01%)</title><rect x="132.1" y="1941" width="0.1" height="15.0" fill="rgb(253,224,53)" rx="2" ry="2" />
<text  x="135.05" y="1951.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="85" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="95.5" >[..</text>
</g>
<g >
<title>mempool_free (59,817,225 samples, 0.07%)</title><rect x="257.9" y="1941" width="0.9" height="15.0" fill="rgb(233,131,31)" rx="2" ry="2" />
<text  x="260.93" y="1951.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1669" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1679.5" >[..</text>
</g>
<g >
<title>bio_alloc_bioset (1,503,517,015 samples, 1.77%)</title><rect x="645.3" y="1877" width="20.9" height="15.0" fill="rgb(206,5,1)" rx="2" ry="2" />
<text  x="648.33" y="1887.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="981" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="991.5" >[..</text>
</g>
<g >
<title>__io_commit_cqring_flush (7,676,194 samples, 0.01%)</title><rect x="131.9" y="1941" width="0.2" height="15.0" fill="rgb(220,69,16)" rx="2" ry="2" />
<text  x="134.95" y="1951.5" ></text>
</g>
<g >
<title>kfree (935,431,274 samples, 1.10%)</title><rect x="132.2" y="1941" width="13.0" height="15.0" fill="rgb(222,78,18)" rx="2" ry="2" />
<text  x="135.19" y="1951.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1381" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1391.5" >[..</text>
</g>
<g >
<title>__rcu_read_lock (102,074,912 samples, 0.12%)</title><rect x="238.7" y="1925" width="1.4" height="15.0" fill="rgb(220,69,16)" rx="2" ry="2" />
<text  x="241.69" y="1935.5" ></text>
</g>
<g >
<title>all (84,882,428,926 samples, 100%)</title><rect x="10.0" y="2085" width="1180.0" height="15.0" fill="rgb(213,39,9)" rx="2" ry="2" />
<text  x="13.00" y="2095.5" ></text>
</g>
<g >
<title>__check_block_validity.constprop.90 (607,915,080 samples, 0.72%)</title><rect x="728.0" y="1845" width="8.5" height="15.0" fill="rgb(233,129,30)" rx="2" ry="2" />
<text  x="731.05" y="1855.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="453" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="463.5" >[..</text>
</g>
<g >
<title>iomap_dio_fast_read_end_io (1,262,482,885 samples, 1.49%)</title><rect x="240.1" y="1941" width="17.6" height="15.0" fill="rgb(210,25,6)" rx="2" ry="2" />
<text  x="243.11" y="1951.5" ></text>
</g>
<g >
<title>__io_prep_rw (3,099,274,989 samples, 3.65%)</title><rect x="341.0" y="1973" width="43.1" height="15.0" fill="rgb(222,80,19)" rx="2" ry="2" />
<text  x="344.00" y="1983.5" >__io..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="533" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="543.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1605" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1615.5" >[..</text>
</g>
<g >
<title>__rcu_read_lock (17,653,578 samples, 0.02%)</title><rect x="968.3" y="1813" width="0.2" height="15.0" fill="rgb(220,69,16)" rx="2" ry="2" />
<text  x="971.27" y="1823.5" ></text>
</g>
<g >
<title>_raw_spin_unlock_irqrestore (7,676,572 samples, 0.01%)</title><rect x="145.1" y="1893" width="0.1" height="15.0" fill="rgb(228,106,25)" rx="2" ry="2" />
<text  x="148.07" y="1903.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1189" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1199.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="917" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="927.5" >[..</text>
</g>
<g >
<title>blk_mq_start_request (1,718,478,156 samples, 2.02%)</title><rect x="442.2" y="1877" width="23.9" height="15.0" fill="rgb(242,172,41)" rx="2" ry="2" />
<text  x="445.25" y="1887.5" >b..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1253" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1263.5" >[..</text>
</g>
<g >
<title>__blk_flush_plug (7,848,559,346 samples, 9.25%)</title><rect x="384.2" y="1957" width="109.1" height="15.0" fill="rgb(217,57,13)" rx="2" ry="2" />
<text  x="387.20" y="1967.5" >__blk_flush_p..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="837" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="847.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1829" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1839.5" >[..</text>
</g>
<g >
<title>dma_unmap_page_attrs (74,444,956 samples, 0.09%)</title><rect x="81.4" y="1941" width="1.0" height="15.0" fill="rgb(252,218,52)" rx="2" ry="2" />
<text  x="84.38" y="1951.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="661" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="671.5" >[..</text>
</g>
<g >
<title>ext4_should_use_dio.isra.16 (1,087,598,013 samples, 1.28%)</title><rect x="580.0" y="1909" width="15.2" height="15.0" fill="rgb(242,170,40)" rx="2" ry="2" />
<text  x="583.03" y="1919.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1941" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1951.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1893" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1903.5" >[..</text>
</g>
<g >
<title>io_do_iopoll (19,639,258,475 samples, 23.14%)</title><rect x="47.5" y="1973" width="273.1" height="15.0" fill="rgb(246,191,45)" rx="2" ry="2" />
<text  x="50.54" y="1983.5" >io_do_iopoll</text>
</g>
<g >
<title>blk_attempt_bio_merge (1,248,763,709 samples, 1.47%)</title><rect x="1040.5" y="1813" width="17.4" height="15.0" fill="rgb(206,7,1)" rx="2" ry="2" />
<text  x="1043.53" y="1823.5" ></text>
</g>
<g >
<title>io_prep_read_fixed (41,445,502 samples, 0.05%)</title><rect x="1169.5" y="1973" width="0.6" height="15.0" fill="rgb(218,64,15)" rx="2" ry="2" />
<text  x="1172.50" y="1983.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1589" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1599.5" >[..</text>
</g>
<g >
<title>io_submit_sqes (61,109,399,470 samples, 71.99%)</title><rect x="320.6" y="1989" width="849.5" height="15.0" fill="rgb(209,18,4)" rx="2" ry="2" />
<text  x="323.56" y="1999.5" >io_submit_sqes</text>
</g>
<g >
<title>[button.ko] (1,988,576,896 samples, 2.34%)</title><rect x="70.6" y="1957" width="27.7" height="15.0" fill="rgb(254,226,54)" rx="2" ry="2" />
<text  x="73.61" y="1967.5" >[..</text>
</g>
<g >
<title>nvme_open (69,067,257 samples, 0.08%)</title><rect x="97.3" y="1941" width="1.0" height="15.0" fill="rgb(216,54,13)" rx="2" ry="2" />
<text  x="100.29" y="1951.5" ></text>
</g>
<g >
<title>__list_del_entry_valid_or_report (13,048,018 samples, 0.02%)</title><rect x="144.5" y="1893" width="0.1" height="15.0" fill="rgb(243,176,42)" rx="2" ry="2" />
<text  x="147.46" y="1903.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1621" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1631.5" >[..</text>
</g>
<g >
<title>iomap_dio_fast_read_async.isra.31 (33,797,318,932 samples, 39.82%)</title><rect x="605.4" y="1893" width="469.9" height="15.0" fill="rgb(252,220,52)" rx="2" ry="2" />
<text  x="608.42" y="1903.5" >iomap_dio_fast_read_async.isra.31</text>
</g>
<g >
<title>iov_iter_bvec (244,083,872 samples, 0.29%)</title><rect x="1166.1" y="1909" width="3.4" height="15.0" fill="rgb(224,90,21)" rx="2" ry="2" />
<text  x="1169.10" y="1919.5" ></text>
</g>
<g >
<title>__rq_qos_track (522,698,043 samples, 0.62%)</title><rect x="1016.3" y="1829" width="7.3" height="15.0" fill="rgb(209,20,4)" rx="2" ry="2" />
<text  x="1019.32" y="1839.5" ></text>
</g>
<g >
<title>[button.ko] (7,317,436,834 samples, 8.62%)</title><rect x="390.5" y="1893" width="101.7" height="15.0" fill="rgb(254,226,54)" rx="2" ry="2" />
<text  x="393.47" y="1903.5" >[button.ko]</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="581" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="591.5" >[..</text>
</g>
<g >
<title>ktime_get (143,533,439 samples, 0.17%)</title><rect x="1068.0" y="1829" width="2.0" height="15.0" fill="rgb(207,10,2)" rx="2" ry="2" />
<text  x="1070.99" y="1839.5" ></text>
</g>
<g >
<title>kiocb_write_and_wait (194,961,252 samples, 0.23%)</title><rect x="858.9" y="1877" width="2.7" height="15.0" fill="rgb(221,77,18)" rx="2" ry="2" />
<text  x="861.91" y="1887.5" ></text>
</g>
<g >
<title>io_import_reg_buf (1,673,480,297 samples, 1.97%)</title><rect x="1146.2" y="1925" width="23.3" height="15.0" fill="rgb(216,52,12)" rx="2" ry="2" />
<text  x="1149.23" y="1935.5" >i..</text>
</g>
<g >
<title>memset (309,331,995 samples, 0.36%)</title><rect x="379.8" y="1941" width="4.3" height="15.0" fill="rgb(208,14,3)" rx="2" ry="2" />
<text  x="382.78" y="1951.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1029" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1039.5" >[..</text>
</g>
<g >
<title>__io_submit_flush_completions (3,376,872,303 samples, 3.98%)</title><rect x="98.3" y="1957" width="46.9" height="15.0" fill="rgb(226,99,23)" rx="2" ry="2" />
<text  x="101.25" y="1967.5" >__io..</text>
</g>
<g >
<title>blk_start_plug_nr_ios (10,746,150 samples, 0.01%)</title><rect x="493.3" y="1973" width="0.2" height="15.0" fill="rgb(254,228,54)" rx="2" ry="2" />
<text  x="496.31" y="1983.5" ></text>
</g>
<g >
<title>bio_integrity_prep (346,918,654 samples, 0.41%)</title><rect x="1023.6" y="1829" width="4.8" height="15.0" fill="rgb(220,69,16)" rx="2" ry="2" />
<text  x="1026.59" y="1839.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1093" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1103.5" >[..</text>
</g>
<g >
<title>blk_add_rq_to_plug (592,554,943 samples, 0.70%)</title><rect x="1028.4" y="1829" width="8.2" height="15.0" fill="rgb(243,175,41)" rx="2" ry="2" />
<text  x="1031.41" y="1839.5" ></text>
</g>
<g >
<title>io_read_fixed (2,379,637,248 samples, 2.80%)</title><rect x="1136.4" y="1957" width="33.1" height="15.0" fill="rgb(218,62,14)" rx="2" ry="2" />
<text  x="1139.42" y="1967.5" >io..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1141" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1151.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="101" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="111.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1333" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1343.5" >[..</text>
</g>
<g >
<title>entry_SYSCALL_64_safe_stack (24,549,420 samples, 0.03%)</title><rect x="1189.4" y="2037" width="0.3" height="15.0" fill="rgb(231,120,28)" rx="2" ry="2" />
<text  x="1192.36" y="2047.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="773" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="783.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="2021" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="2031.5" >[..</text>
</g>
<g >
<title>wb_timestamp (98,242,481 samples, 0.12%)</title><rect x="1015.0" y="1797" width="1.3" height="15.0" fill="rgb(217,56,13)" rx="2" ry="2" />
<text  x="1017.95" y="1807.5" ></text>
</g>
<g >
<title>iov_iter_advance (711,360,564 samples, 0.84%)</title><rect x="676.0" y="1861" width="9.9" height="15.0" fill="rgb(248,197,47)" rx="2" ry="2" />
<text  x="678.97" y="1871.5" ></text>
</g>
<g >
<title>blk_mq_sched_bio_merge (726,904,602 samples, 0.86%)</title><rect x="1057.9" y="1829" width="10.1" height="15.0" fill="rgb(210,26,6)" rx="2" ry="2" />
<text  x="1060.89" y="1839.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1525" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1535.5" >[..</text>
</g>
<g >
<title>__list_del_entry_valid_or_report (548,494,004 samples, 0.65%)</title><rect x="145.2" y="1957" width="7.6" height="15.0" fill="rgb(243,176,42)" rx="2" ry="2" />
<text  x="148.19" y="1967.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1781" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1791.5" >[..</text>
</g>
<g >
<title>[button.ko] (348,418,634 samples, 0.41%)</title><rect x="75.6" y="1941" width="4.9" height="15.0" fill="rgb(254,226,54)" rx="2" ry="2" />
<text  x="78.61" y="1951.5" ></text>
</g>
<g >
<title>wbt_wait (682,246,972 samples, 0.80%)</title><rect x="1006.8" y="1813" width="9.5" height="15.0" fill="rgb(225,95,22)" rx="2" ry="2" />
<text  x="1009.83" y="1823.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="293" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="303.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="709" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="719.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="517" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="527.5" >[..</text>
</g>
<g >
<title>bio_to_wbt_flags (144,280,811 samples, 0.17%)</title><rect x="1012.9" y="1797" width="2.1" height="15.0" fill="rgb(235,138,33)" rx="2" ry="2" />
<text  x="1015.95" y="1807.5" ></text>
</g>
<g >
<title>blk_rq_merge_ok (655,450,965 samples, 0.77%)</title><rect x="1045.2" y="1797" width="9.1" height="15.0" fill="rgb(215,46,11)" rx="2" ry="2" />
<text  x="1048.17" y="1807.5" ></text>
</g>
<g >
<title>__rcu_read_unlock (339,999,534 samples, 0.40%)</title><rect x="199.8" y="1941" width="4.8" height="15.0" fill="rgb(253,224,53)" rx="2" ry="2" />
<text  x="202.83" y="1951.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1685" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1695.5" >[..</text>
</g>
<g >
<title>blk_try_merge (259,440,628 samples, 0.31%)</title><rect x="1054.3" y="1797" width="3.6" height="15.0" fill="rgb(235,142,34)" rx="2" ry="2" />
<text  x="1057.28" y="1807.5" ></text>
</g>
<g >
<title>wbt_track (271,706,739 samples, 0.32%)</title><rect x="1019.8" y="1813" width="3.8" height="15.0" fill="rgb(205,2,0)" rx="2" ry="2" />
<text  x="1022.81" y="1823.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1909" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1919.5" >[..</text>
</g>
<g >
<title>io_complete_rw_iopoll (145,835,515 samples, 0.17%)</title><rect x="255.6" y="1925" width="2.1" height="15.0" fill="rgb(254,228,54)" rx="2" ry="2" />
<text  x="258.63" y="1935.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1125" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1135.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1973" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1983.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="853" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="863.5" >[..</text>
</g>
<g >
<title>dma_map_page_attrs (141,225,547 samples, 0.17%)</title><rect x="466.1" y="1877" width="2.0" height="15.0" fill="rgb(218,64,15)" rx="2" ry="2" />
<text  x="469.14" y="1887.5" ></text>
</g>
<g >
<title>ext4_es_lookup_extent (7,229,054,379 samples, 8.52%)</title><rect x="736.5" y="1845" width="100.5" height="15.0" fill="rgb(222,80,19)" rx="2" ry="2" />
<text  x="739.52" y="1855.5" >ext4_es_look..</text>
</g>
<g >
<title>blk_mq_get_tags (1,495,173,924 samples, 1.76%)</title><rect x="968.8" y="1813" width="20.8" height="15.0" fill="rgb(215,46,11)" rx="2" ry="2" />
<text  x="971.81" y="1823.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="597" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="607.5" >[..</text>
</g>
<g >
<title>io_rw_recycle (384,517,706 samples, 0.45%)</title><rect x="286.9" y="1941" width="5.4" height="15.0" fill="rgb(235,142,34)" rx="2" ry="2" />
<text  x="289.94" y="1951.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1269" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1279.5" >[..</text>
</g>
<g >
<title>__x64_sys_io_uring_enter (82,228,173,167 samples, 96.87%)</title><rect x="46.1" y="2005" width="1143.1" height="15.0" fill="rgb(210,27,6)" rx="2" ry="2" />
<text  x="49.10" y="2015.5" >__x64_sys_io_uring_enter</text>
</g>
<g >
<title>bdev_count_inflight (73,703,310 samples, 0.09%)</title><rect x="1074.2" y="1813" width="1.1" height="15.0" fill="rgb(209,22,5)" rx="2" ry="2" />
<text  x="1077.24" y="1823.5" ></text>
</g>
<g >
<title>__pfx_nvme_open (66,768,433 samples, 0.08%)</title><rect x="80.5" y="1941" width="0.9" height="15.0" fill="rgb(218,60,14)" rx="2" ry="2" />
<text  x="83.45" y="1951.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="181" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="191.5" >[..</text>
</g>
<g >
<title>io_cache_alloc_new (1,369,268,857 samples, 1.61%)</title><rect x="365.0" y="1957" width="19.1" height="15.0" fill="rgb(236,146,35)" rx="2" ry="2" />
<text  x="368.05" y="1967.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="805" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="815.5" >[..</text>
</g>
<g >
<title>ext4_map_blocks (9,425,724,827 samples, 11.10%)</title><rect x="706.0" y="1861" width="131.0" height="15.0" fill="rgb(247,196,46)" rx="2" ry="2" />
<text  x="708.98" y="1871.5" >ext4_map_blocks</text>
</g>
<g >
<title>blk_finish_plug (7,857,001,237 samples, 9.26%)</title><rect x="384.1" y="1973" width="109.2" height="15.0" fill="rgb(231,119,28)" rx="2" ry="2" />
<text  x="387.08" y="1983.5" >blk_finish_plug</text>
</g>
<g >
<title>nvme_put_ns_head (61,394,810 samples, 0.07%)</title><rect x="484.8" y="1877" width="0.9" height="15.0" fill="rgb(214,41,9)" rx="2" ry="2" />
<text  x="487.85" y="1887.5" ></text>
</g>
<g >
<title>iomap_dio_rw (34,536,395,961 samples, 40.69%)</title><rect x="595.2" y="1909" width="480.1" height="15.0" fill="rgb(240,161,38)" rx="2" ry="2" />
<text  x="598.15" y="1919.5" >iomap_dio_rw</text>
</g>
<g >
<title>get_offset.part.0 (960,966,364 samples, 1.13%)</title><rect x="10.0" y="37" width="13.4" height="15.0" fill="rgb(212,36,8)" rx="2" ry="2" />
<text  x="13.00" y="47.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="197" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="207.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1205" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1215.5" >[..</text>
</g>
<g >
<title>ext4_iomap_begin (12,447,862,176 samples, 14.66%)</title><rect x="685.9" y="1877" width="173.0" height="15.0" fill="rgb(233,133,31)" rx="2" ry="2" />
<text  x="688.86" y="1887.5" >ext4_iomap_begin</text>
</g>
<g >
<title>blk_hctx_poll.isra.68 (1,907,209,536 samples, 2.25%)</title><rect x="294.0" y="1925" width="26.5" height="15.0" fill="rgb(253,222,53)" rx="2" ry="2" />
<text  x="297.03" y="1935.5" >b..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="421" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="431.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="245" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="255.5" >[..</text>
</g>
<g >
<title>nvme_complete_rq (346,167,323 samples, 0.41%)</title><rect x="477.8" y="1877" width="4.8" height="15.0" fill="rgb(254,226,54)" rx="2" ry="2" />
<text  x="480.81" y="1887.5" ></text>
</g>
<g >
<title>bio_free (7,675,037 samples, 0.01%)</title><rect x="219.9" y="1941" width="0.1" height="15.0" fill="rgb(221,74,17)" rx="2" ry="2" />
<text  x="222.90" y="1951.5" ></text>
</g>
<g >
<title>up_read (2,307,972,303 samples, 2.72%)</title><rect x="1075.3" y="1909" width="32.0" height="15.0" fill="rgb(209,18,4)" rx="2" ry="2" />
<text  x="1078.26" y="1919.5" >up..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1749" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1759.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1845" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1855.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1461" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1471.5" >[..</text>
</g>
<g >
<title>__sbitmap_queue_get_batch (1,447,587,765 samples, 1.71%)</title><rect x="969.5" y="1797" width="20.1" height="15.0" fill="rgb(253,221,53)" rx="2" ry="2" />
<text  x="972.47" y="1807.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="789" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="799.5" >[..</text>
</g>
<g >
<title>io_assign_file.part.60 (606,367,619 samples, 0.71%)</title><rect x="519.7" y="1957" width="8.4" height="15.0" fill="rgb(247,196,47)" rx="2" ry="2" />
<text  x="522.69" y="1967.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="341" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="351.5" >[..</text>
</g>
<g >
<title>__pfx_nvme_identify_ns (62,937,441 samples, 0.07%)</title><rect x="439.5" y="1877" width="0.9" height="15.0" fill="rgb(249,202,48)" rx="2" ry="2" />
<text  x="442.54" y="1887.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1317" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1327.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="133" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="143.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="357" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="367.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1765" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1775.5" >[..</text>
</g>
<g >
<title>submitter_uring_fn (786,727,729 samples, 0.93%)</title><rect x="23.4" y="37" width="10.9" height="15.0" fill="rgb(218,61,14)" rx="2" ry="2" />
<text  x="26.36" y="47.5" ></text>
</g>
<g >
<title>io_req_rw_cleanup (675,408,318 samples, 0.80%)</title><rect x="282.9" y="1957" width="9.4" height="15.0" fill="rgb(246,193,46)" rx="2" ry="2" />
<text  x="285.89" y="1967.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1397" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1407.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="405" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="415.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="261" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="271.5" >[..</text>
</g>
<g >
<title>blk_mq_flush_plug_list (7,824,772,328 samples, 9.22%)</title><rect x="384.5" y="1941" width="108.8" height="15.0" fill="rgb(215,46,11)" rx="2" ry="2" />
<text  x="387.53" y="1951.5" >blk_mq_flush_..</text>
</g>
<g >
<title>__blk_mq_alloc_requests (3,703,420,577 samples, 4.36%)</title><rect x="951.4" y="1829" width="51.5" height="15.0" fill="rgb(248,199,47)" rx="2" ry="2" />
<text  x="954.45" y="1839.5" >__blk..</text>
</g>
<g >
<title>entry_SYSRETQ_unsafe_stack (7,673,295 samples, 0.01%)</title><rect x="1189.7" y="2037" width="0.1" height="15.0" fill="rgb(206,7,1)" rx="2" ry="2" />
<text  x="1192.70" y="2047.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1045" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1055.5" >[..</text>
</g>
<g >
<title>read_tsc (9,211,960 samples, 0.01%)</title><rect x="257.8" y="1925" width="0.1" height="15.0" fill="rgb(206,7,1)" rx="2" ry="2" />
<text  x="260.80" y="1935.5" ></text>
</g>
<g >
<title>__rq_qos_done_bio (159,653,206 samples, 0.19%)</title><rect x="217.7" y="1925" width="2.2" height="15.0" fill="rgb(234,134,32)" rx="2" ry="2" />
<text  x="220.68" y="1935.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="901" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="911.5" >[..</text>
</g>
<g >
<title>nvme_identify_ns (118,207,937 samples, 0.14%)</title><rect x="483.2" y="1877" width="1.6" height="15.0" fill="rgb(247,196,47)" rx="2" ry="2" />
<text  x="486.20" y="1887.5" ></text>
</g>
<g >
<title>io_rw_init_file (875,024,793 samples, 1.03%)</title><rect x="1111.9" y="1925" width="12.1" height="15.0" fill="rgb(218,60,14)" rx="2" ry="2" />
<text  x="1114.85" y="1935.5" ></text>
</g>
<g >
<title>mempool_alloc_noprof (148,901,428 samples, 0.18%)</title><rect x="664.2" y="1861" width="2.0" height="15.0" fill="rgb(228,106,25)" rx="2" ry="2" />
<text  x="667.16" y="1871.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1109" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1119.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1925" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1935.5" >[..</text>
</g>
<g >
<title>_find_next_bit (30,710,579 samples, 0.04%)</title><rect x="1074.8" y="1781" width="0.5" height="15.0" fill="rgb(230,116,27)" rx="2" ry="2" />
<text  x="1077.83" y="1791.5" ></text>
</g>
<g >
<title>_raw_spin_lock_irqsave (30,707,479 samples, 0.04%)</title><rect x="144.6" y="1893" width="0.5" height="15.0" fill="rgb(247,195,46)" rx="2" ry="2" />
<text  x="147.64" y="1903.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1573" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1583.5" >[..</text>
</g>
<g >
<title>[button.ko] (7,722,691,980 samples, 9.10%)</title><rect x="384.9" y="1909" width="107.4" height="15.0" fill="rgb(254,226,54)" rx="2" ry="2" />
<text  x="387.93" y="1919.5" >[button.ko]</text>
</g>
<g >
<title>nvme_update_ns_info_block (250,235,965 samples, 0.29%)</title><rect x="488.7" y="1877" width="3.5" height="15.0" fill="rgb(228,109,26)" rx="2" ry="2" />
<text  x="491.72" y="1887.5" ></text>
</g>
<g >
<title>ext4_file_read_iter (39,771,657,253 samples, 46.85%)</title><rect x="554.5" y="1925" width="552.8" height="15.0" fill="rgb(244,180,43)" rx="2" ry="2" />
<text  x="557.46" y="1935.5" >ext4_file_read_iter</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="725" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="735.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1285" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1295.5" >[..</text>
</g>
<g >
<title>bio_to_wbt_flags (166,547,357 samples, 0.20%)</title><rect x="1021.3" y="1797" width="2.3" height="15.0" fill="rgb(235,138,33)" rx="2" ry="2" />
<text  x="1024.27" y="1807.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1509" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1519.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="485" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="495.5" >[..</text>
</g>
<g >
<title>jbd2_transaction_committed (154,283,090 samples, 0.18%)</title><rect x="856.8" y="1845" width="2.1" height="15.0" fill="rgb(221,77,18)" rx="2" ry="2" />
<text  x="859.76" y="1855.5" ></text>
</g>
<g >
<title>security_file_permission (304,694,413 samples, 0.36%)</title><rect x="1132.2" y="1909" width="4.2" height="15.0" fill="rgb(225,96,23)" rx="2" ry="2" />
<text  x="1135.18" y="1919.5" ></text>
</g>
<g >
<title>wb_timestamp (135,085,667 samples, 0.16%)</title><rect x="208.4" y="1909" width="1.9" height="15.0" fill="rgb(217,56,13)" rx="2" ry="2" />
<text  x="211.43" y="1919.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="677" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="687.5" >[..</text>
</g>
<g >
<title>__rq_qos_issue (455,155,557 samples, 0.54%)</title><rect x="454.2" y="1861" width="6.4" height="15.0" fill="rgb(230,115,27)" rx="2" ry="2" />
<text  x="457.23" y="1871.5" ></text>
</g>
<g >
<title>__pcs_replace_empty_main (164,255,903 samples, 0.19%)</title><rect x="377.5" y="1925" width="2.3" height="15.0" fill="rgb(229,114,27)" rx="2" ry="2" />
<text  x="380.50" y="1935.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1429" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1439.5" >[..</text>
</g>
<g >
<title>blk_mq_end_request_batch (9,354,373,763 samples, 11.02%)</title><rect x="152.9" y="1957" width="130.0" height="15.0" fill="rgb(254,225,53)" rx="2" ry="2" />
<text  x="155.85" y="1967.5" >blk_mq_end_reque..</text>
</g>
<g >
<title>read_tsc (85,194,415 samples, 0.10%)</title><rect x="1068.8" y="1813" width="1.2" height="15.0" fill="rgb(206,7,1)" rx="2" ry="2" />
<text  x="1071.81" y="1823.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="821" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="831.5" >[..</text>
</g>
<g >
<title>ext4_inode_block_valid (141,229,587 samples, 0.17%)</title><rect x="734.5" y="1829" width="2.0" height="15.0" fill="rgb(215,50,11)" rx="2" ry="2" />
<text  x="737.53" y="1839.5" ></text>
</g>
<g >
<title>wbt_done (282,452,355 samples, 0.33%)</title><rect x="206.4" y="1925" width="3.9" height="15.0" fill="rgb(222,81,19)" rx="2" ry="2" />
<text  x="209.38" y="1935.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="469" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="479.5" >[..</text>
</g>
<g >
<title>submit_bio_noacct (917,194,558 samples, 1.08%)</title><rect x="865.3" y="1877" width="12.7" height="15.0" fill="rgb(211,30,7)" rx="2" ry="2" />
<text  x="868.30" y="1887.5" ></text>
</g>
<g >
<title>nvme_ns_open (334,657,568 samples, 0.39%)</title><rect x="92.6" y="1941" width="4.7" height="15.0" fill="rgb(249,205,49)" rx="2" ry="2" />
<text  x="95.64" y="1951.5" ></text>
</g>
<g >
<title>bdev_count_inflight_rw.part.17 (73,703,310 samples, 0.09%)</title><rect x="1074.2" y="1797" width="1.1" height="15.0" fill="rgb(238,156,37)" rx="2" ry="2" />
<text  x="1077.24" y="1807.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="757" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="767.5" >[..</text>
</g>
<g >
<title>dma_map_phys (698,633,943 samples, 0.82%)</title><rect x="468.1" y="1877" width="9.7" height="15.0" fill="rgb(235,139,33)" rx="2" ry="2" />
<text  x="471.10" y="1887.5" ></text>
</g>
<g >
<title>_raw_read_lock (1,327,787,412 samples, 1.56%)</title><rect x="786.6" y="1829" width="18.4" height="15.0" fill="rgb(233,132,31)" rx="2" ry="2" />
<text  x="789.58" y="1839.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="645" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="655.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1493" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1503.5" >[..</text>
</g>
<g >
<title>mutex_lock (48,352,114 samples, 0.06%)</title><rect x="1170.1" y="1989" width="0.6" height="15.0" fill="rgb(217,57,13)" rx="2" ry="2" />
<text  x="1173.07" y="1999.5" ></text>
</g>
<g >
<title>_raw_spin_lock_irqsave (701,555,799 samples, 0.83%)</title><rect x="978.0" y="1781" width="9.8" height="15.0" fill="rgb(247,195,46)" rx="2" ry="2" />
<text  x="981.01" y="1791.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="389" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="399.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="997" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1007.5" >[..</text>
</g>
<g >
<title>ext4_dio_alignment (782,877,329 samples, 0.92%)</title><rect x="584.3" y="1893" width="10.9" height="15.0" fill="rgb(236,146,35)" rx="2" ry="2" />
<text  x="587.27" y="1903.5" ></text>
</g>
<g >
<title>bio_put (399,093,247 samples, 0.47%)</title><rect x="220.0" y="1941" width="5.6" height="15.0" fill="rgb(242,173,41)" rx="2" ry="2" />
<text  x="223.01" y="1951.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="437" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="447.5" >[..</text>
</g>
<g >
<title>sbitmap_queue_clear_batch (1,349,311,143 samples, 1.59%)</title><rect x="258.8" y="1941" width="18.7" height="15.0" fill="rgb(245,184,44)" rx="2" ry="2" />
<text  x="261.76" y="1951.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1077" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1087.5" >[..</text>
</g>
<g >
<title>bio_endio (689,993,701 samples, 0.81%)</title><rect x="210.3" y="1941" width="9.6" height="15.0" fill="rgb(217,55,13)" rx="2" ry="2" />
<text  x="213.31" y="1951.5" ></text>
</g>
<g >
<title>blk_stat_add (502,713,854 samples, 0.59%)</title><rect x="233.1" y="1941" width="7.0" height="15.0" fill="rgb(227,103,24)" rx="2" ry="2" />
<text  x="236.12" y="1951.5" ></text>
</g>
<g >
<title>io_read (43,757,041,605 samples, 51.55%)</title><rect x="528.1" y="1957" width="608.3" height="15.0" fill="rgb(243,175,41)" rx="2" ry="2" />
<text  x="531.12" y="1967.5" >io_read</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1365" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1375.5" >[..</text>
</g>
<g >
<title>ktime_get (19,185,275 samples, 0.02%)</title><rect x="257.7" y="1941" width="0.2" height="15.0" fill="rgb(207,10,2)" rx="2" ry="2" />
<text  x="260.66" y="1951.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="2037" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="2047.5" >[..</text>
</g>
<g >
<title>kmem_cache_alloc_noprof (96,714,300 samples, 0.11%)</title><rect x="664.8" y="1845" width="1.4" height="15.0" fill="rgb(248,200,47)" rx="2" ry="2" />
<text  x="667.83" y="1855.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="629" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="639.5" >[..</text>
</g>
<g >
<title>barn_replace_full_sheaf.part.95 (62,945,198 samples, 0.07%)</title><rect x="144.3" y="1909" width="0.9" height="15.0" fill="rgb(233,131,31)" rx="2" ry="2" />
<text  x="147.30" y="1919.5" ></text>
</g>
<g >
<title>kmem_cache_free (47,535,019 samples, 0.06%)</title><rect x="258.0" y="1925" width="0.7" height="15.0" fill="rgb(254,225,53)" rx="2" ry="2" />
<text  x="261.02" y="1935.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1237" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1247.5" >[..</text>
</g>
<g >
<title>io_file_supports_nowait (324,255,730 samples, 0.38%)</title><rect x="1107.3" y="1925" width="4.6" height="15.0" fill="rgb(247,196,47)" rx="2" ry="2" />
<text  x="1110.35" y="1935.5" ></text>
</g>
<g >
<title>__rcu_read_unlock (20,729,278 samples, 0.02%)</title><rect x="968.5" y="1813" width="0.3" height="15.0" fill="rgb(253,224,53)" rx="2" ry="2" />
<text  x="971.52" y="1823.5" ></text>
</g>
<g >
<title>[unknown] (1,748,444,087 samples, 2.06%)</title><rect x="10.0" y="2053" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="2063.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="933" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="943.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1797" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1807.5" >[..</text>
</g>
<g >
<title>wbt_issue (238,715,265 samples, 0.28%)</title><rect x="457.2" y="1845" width="3.4" height="15.0" fill="rgb(226,98,23)" rx="2" ry="2" />
<text  x="460.24" y="1855.5" ></text>
</g>
<g >
<title>[nvme-core.ko] (105,923,723 samples, 0.12%)</title><rect x="438.1" y="1877" width="1.4" height="15.0" fill="rgb(253,225,53)" rx="2" ry="2" />
<text  x="441.07" y="1887.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="869" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="879.5" >[..</text>
</g>
<g >
<title>do_syscall_64 (82,291,877,669 samples, 96.95%)</title><rect x="45.4" y="2021" width="1144.0" height="15.0" fill="rgb(209,20,4)" rx="2" ry="2" />
<text  x="48.37" y="2031.5" >do_syscall_64</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="229" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="239.5" >[..</text>
</g>
<g >
<title>submit_bio_noacct_nocheck (14,186,320,292 samples, 16.71%)</title><rect x="878.0" y="1877" width="197.3" height="15.0" fill="rgb(225,95,22)" rx="2" ry="2" />
<text  x="881.05" y="1887.5" >submit_bio_noacct_nocheck</text>
</g>
<g >
<title>nvme_tryget_ns_head (217,240,925 samples, 0.26%)</title><rect x="485.7" y="1877" width="3.0" height="15.0" fill="rgb(208,14,3)" rx="2" ry="2" />
<text  x="488.70" y="1887.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1877" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1887.5" >[..</text>
</g>
<g >
<title>bio_poll (1,932,533,875 samples, 2.28%)</title><rect x="293.7" y="1941" width="26.9" height="15.0" fill="rgb(235,140,33)" rx="2" ry="2" />
<text  x="296.69" y="1951.5" >b..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="277" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="287.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1541" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1551.5" >[..</text>
</g>
<g >
<title>blk_mq_finish_request (115,137,648 samples, 0.14%)</title><rect x="231.5" y="1941" width="1.6" height="15.0" fill="rgb(206,6,1)" rx="2" ry="2" />
<text  x="234.48" y="1951.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1157" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1167.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="53" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="63.5" >[..</text>
</g>
<g >
<title>__pcs_replace_full_main (105,928,204 samples, 0.12%)</title><rect x="143.7" y="1925" width="1.5" height="15.0" fill="rgb(230,119,28)" rx="2" ry="2" />
<text  x="146.70" y="1935.5" ></text>
</g>
<g >
<title>rw_verify_area (891,855,142 samples, 1.05%)</title><rect x="1124.0" y="1925" width="12.4" height="15.0" fill="rgb(218,64,15)" rx="2" ry="2" />
<text  x="1127.02" y="1935.5" ></text>
</g>
<g >
<title>ext4_inode_journal_mode (434,409,975 samples, 0.51%)</title><rect x="589.1" y="1877" width="6.1" height="15.0" fill="rgb(206,7,1)" rx="2" ry="2" />
<text  x="592.11" y="1887.5" ></text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="325" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="335.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1445" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1455.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1717" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1727.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="565" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="575.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="309" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="319.5" >[..</text>
</g>
<g >
<title>[unknown] (1,747,694,093 samples, 2.06%)</title><rect x="10.0" y="1637" width="24.3" height="15.0" fill="rgb(210,24,5)" rx="2" ry="2" />
<text  x="13.00" y="1647.5" >[..</text>
</g>
<g >
<title>io_vec_free (95,939,815 samples, 0.11%)</title><rect x="292.3" y="1957" width="1.3" height="15.0" fill="rgb(236,144,34)" rx="2" ry="2" />
<text  x="295.30" y="1967.5" ></text>
</g>
</g>
</svg>

^ permalink raw reply

* Re: [RFC v2 0/1] ext4: fail fast on repeated buffer_head reads after IO failure
From: Diangang Li @ 2026-04-16  3:54 UTC (permalink / raw)
  To: Theodore Tso, Diangang Li
  Cc: adilger.kernel, linux-ext4, linux-fsdevel, linux-kernel,
	changfengnan, yizhang089, willy
In-Reply-To: <20260413124703.GA20496@macsyma-wired.lan>

On 4/13/26 8:47 PM, Theodore Tso wrote:
> On Mon, Apr 13, 2026 at 02:24:59PM +0800, Diangang Li wrote:
>> From: Diangang Li <lidiangang@bytedance.com>
>>
>> A production system reported hung tasks blocked for 300s+ in ext4
>> buffer_head paths....
>>
>>    [Tue Mar 24 14:16:24 2026] blk_update_request: I/O error, dev sdi,
>>        sector 10704150288 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 0
>>    [Tue Mar 24 14:16:25 2026] blk_update_request: I/O error, dev sdi,
>>        sector 10704488160 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 0
>>    [Tue Mar 24 14:16:26 2026] blk_update_request: I/O error, dev sdi,
>>        sector 10704382912 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 0
> 
> I wonder whether the ext4 layer is the right place to be handle this
> sort of issue.  For example, it could be handled by having a subsystem
> scanning dmesg (or by wiring up notifications so block device errors
> get sent to a userspace daemon), and when certain criteria is met, the
> machine is automatically sent to hardware operations to run
> diagnostics and (most likey) replace the failing disk.
> 
> It could also be handled in the driver or SCSI layer so the "fail
> fast" semantics are handled there, so that it supports all file
> systems, not just ext4.  The SCSI layer also has more information
> about the type of error; you might want to handle things like media
> errors differently from Fibre Channel or iSCSI timeouts (which might
> be something where "fast fast" is not appropriate).
> 
> By the time the error gets propagated up to the buffer head, we lose a
> lot of detail about why the error took place.  Also, in the long term
> we will hopefully be moving away from using buffer cache.
> 
>     		     	    	      	    - Ted

Hi Ted,

What about moving the fail-fast check into the buffer-head path 
(submit_bh_wbc) so it is not ext4-specific. We can update a BH_Read_EIO 
bit in end_bio_bh_io_sync, and add a per-bdev/per-partition sysfs knob 
for the retry window. That turns it into a generic guard for buffer-head 
users, and it naturally goes away as buffer-head usage shrinks.

We did think about doing this in the block layer (submit_bio) or in 
SCSI/NVMe, but a generic solution there seems to need a per-device table 
to cache the error LBAs. With buffer-head, we can keep the error state 
on the bh itself.

I also checked f2fs (no buffer-head). It tracks repeated EIOs on 
metadata/node pages to avoid infinite retry loops. How do you see that 
compared with a buffer-head retry window? Are either of these directions 
worth exploring further?

Thanks,
Diangang

^ permalink raw reply

* Re: [PATCH v1] ext4: add mb_stats_clear for mballoc statistics
From: liubaolin @ 2026-04-16  7:07 UTC (permalink / raw)
  To: Ojaswin Mujoo
  Cc: tytso, adilger.kernel, linux-ext4, linux-kernel, wangguanyu,
	Baolin Liu
In-Reply-To: <ad_mguIqaOT-pEmh@li-dc0c254c-257c-11b2-a85c-98b6c1322444.ibm.com>

> Dear ojaswin,
>    Alright, thank you for your review. I will revise the patch according to Andreas's comments and submit a second version. 
>    When submitting the second version, I will also update the relevant files under the Documentation directory according to your suggestions to add explanations.
> 
> Regards,
> Baolin



在 2026/4/16 3:26, Ojaswin Mujoo 写道:
> On Tue, Apr 14, 2026 at 06:02:11PM +0800, Baolin Liu wrote:
>> From: Baolin Liu <liubaolin@kylinos.cn>
>>
>> Add a write-only mb_stats_clear sysfs knob to reset ext4 mballoc
>> runtime statistics.This makes it easier to inspect allocator
>> activity for a specific workload instead of using counters
>> accumulated since mount.
>>
>> Signed-off-by: Baolin Liu <liubaolin@kylinos.cn>
> 
> The patch looks good to me Baolin. We just need to add documentation of
> this to the Documentation/ABI/testing/sysfs-fs-ext4 file so that the
> users know what it is and the fact that the only value we allow to write
> is 1.
> 
> Regards,
> ojaswin


^ permalink raw reply

* Re: [PATCH v1] ext4: add mb_stats_clear for mballoc statistics
From: liubaolin @ 2026-04-16  7:11 UTC (permalink / raw)
  To: Andreas Dilger; +Cc: tytso, linux-ext4, linux-kernel, wangguanyu, Baolin Liu
In-Reply-To: <C713AA9C-D640-4C5B-98BF-A5D88AE3B2A0@dilger.ca>

> Dear Andreas,
>    Alright, thank you for your review. 
>    I will revise the patch according to your suggestions and submit a second version as soon as possible.
> 
> Regards,
> Baolin



在 2026/4/16 9:14, Andreas Dilger 写道:
> On Apr 14, 2026, at 04:02, Baolin Liu <liubaolin12138@163.com> wrote:
>>
>> From: Baolin Liu <liubaolin@kylinos.cn>
>>
>> Add a write-only mb_stats_clear sysfs knob to reset ext4 mballoc
>> runtime statistics. This makes it easier to inspect allocator
>> activity for a specific workload instead of using counters
>> accumulated since mount.
> 
> Rather than having a read-only "mb_stats" procfs file and a separate
> write-only "mb_stats_clear" sysfs file to clear "mb_stats", IMHO it
> would be more obvious to write directly to "/proc/fs/ext4/DEV/mb_stats"
> file to clear it.  Writing "0" would be logical to zero out the stats.
> 
> Cheers, Andreas
> 
>>
>> Signed-off-by: Baolin Liu <liubaolin@kylinos.cn>
>> ---
>> fs/ext4/ext4.h    |  1 +
>> fs/ext4/mballoc.c | 31 +++++++++++++++++++++++++++++++
>> fs/ext4/sysfs.c   | 24 ++++++++++++++++++++++++
>> 3 files changed, 56 insertions(+)
>>
>> diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
>> index 7617e2d454ea..3a32e1a515dd 100644
>> --- a/fs/ext4/ext4.h
>> +++ b/fs/ext4/ext4.h
>> @@ -2995,6 +2995,7 @@ int ext4_fc_record_regions(struct super_block *sb, int ino,
>> extern const struct seq_operations ext4_mb_seq_groups_ops;
>> extern const struct seq_operations ext4_mb_seq_structs_summary_ops;
>> extern int ext4_seq_mb_stats_show(struct seq_file *seq, void *offset);
>> +extern void ext4_mb_stats_clear(struct ext4_sb_info *sbi);
>> extern int ext4_mb_init(struct super_block *);
>> extern void ext4_mb_release(struct super_block *);
>> extern ext4_fsblk_t ext4_mb_new_blocks(handle_t *,
>> diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
>> index bb58eafb87bc..382c91586b26 100644
>> --- a/fs/ext4/mballoc.c
>> +++ b/fs/ext4/mballoc.c
>> @@ -3219,6 +3219,8 @@ int ext4_seq_mb_stats_show(struct seq_file *seq, void *offset)
>> }
>> seq_printf(seq, "\treqs: %u\n", atomic_read(&sbi->s_bal_reqs));
>> seq_printf(seq, "\tsuccess: %u\n", atomic_read(&sbi->s_bal_success));
>> + seq_printf(seq, "\tblocks_allocated: %u\n",
>> +   atomic_read(&sbi->s_bal_allocated));
>>
>> seq_printf(seq, "\tgroups_scanned: %u\n",
>>    atomic_read(&sbi->s_bal_groups_scanned));
>> @@ -4721,6 +4723,35 @@ static void ext4_mb_collect_stats(struct ext4_allocation_context *ac)
>> trace_ext4_mballoc_prealloc(ac);
>> }
>>
>> +void ext4_mb_stats_clear(struct ext4_sb_info *sbi)
>> +{
>> + int i;
>> +
>> + atomic_set(&sbi->s_bal_reqs, 0);
>> + atomic_set(&sbi->s_bal_success, 0);
>> + atomic_set(&sbi->s_bal_allocated, 0);
>> + atomic_set(&sbi->s_bal_groups_scanned, 0);
>> +
>> + for (i = 0; i < EXT4_MB_NUM_CRS; i++) {
>> + atomic64_set(&sbi->s_bal_cX_hits[i], 0);
>> + atomic64_set(&sbi->s_bal_cX_groups_considered[i], 0);
>> + atomic_set(&sbi->s_bal_cX_ex_scanned[i], 0);
>> + atomic64_set(&sbi->s_bal_cX_failed[i], 0);
>> + }
>> +
>> + atomic_set(&sbi->s_bal_ex_scanned, 0);
>> + atomic_set(&sbi->s_bal_goals, 0);
>> + atomic_set(&sbi->s_bal_stream_goals, 0);
>> + atomic_set(&sbi->s_bal_len_goals, 0);
>> + atomic_set(&sbi->s_bal_2orders, 0);
>> + atomic_set(&sbi->s_bal_breaks, 0);
>> + atomic_set(&sbi->s_mb_lost_chunks, 0);
>> + atomic_set(&sbi->s_mb_buddies_generated, 0);
>> + atomic64_set(&sbi->s_mb_generation_time, 0);
>> + atomic_set(&sbi->s_mb_preallocated, 0);
>> + atomic_set(&sbi->s_mb_discarded, 0);
>> +}
>> +
>> /*
>>   * Called on failure; free up any blocks from the inode PA for this
>>   * context.  We don't need this for MB_GROUP_PA because we only change
>> diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c
>> index 923b375e017f..a5bd88a99f22 100644
>> --- a/fs/ext4/sysfs.c
>> +++ b/fs/ext4/sysfs.c
>> @@ -41,6 +41,7 @@ typedef enum {
>> attr_pointer_atomic,
>> attr_journal_task,
>> attr_err_report_sec,
>> + attr_mb_stats_clear,
>> } attr_id_t;
>>
>> typedef enum {
>> @@ -161,6 +162,25 @@ static ssize_t err_report_sec_store(struct ext4_sb_info *sbi,
>> return count;
>> }
>>
>> +static ssize_t mb_stats_clear_store(struct ext4_sb_info *sbi,
>> +    const char *buf, size_t count)
>> +{
>> + int val;
>> + int ret;
>> +
>> + if (!capable(CAP_SYS_ADMIN))
>> + return -EPERM;
>> +
>> + ret = kstrtoint(skip_spaces(buf), 0, &val);
>> + if (ret)
>> + return ret;
>> + if (val != 1)
>> + return -EINVAL;
>> +
>> + ext4_mb_stats_clear(sbi);
>> + return count;
>> +}
>> +
>> static ssize_t journal_task_show(struct ext4_sb_info *sbi, char *buf)
>> {
>> if (!sbi->s_journal)
>> @@ -251,6 +271,7 @@ EXT4_ATTR_OFFSET(mb_best_avail_max_trim_order, 0644, mb_order,
>> EXT4_ATTR_OFFSET(err_report_sec, 0644, err_report_sec, ext4_sb_info, s_err_report_sec);
>> EXT4_RW_ATTR_SBI_UI(inode_goal, s_inode_goal);
>> EXT4_RW_ATTR_SBI_UI(mb_stats, s_mb_stats);
>> +EXT4_ATTR(mb_stats_clear, 0200, mb_stats_clear);
>> EXT4_RW_ATTR_SBI_UI(mb_max_to_scan, s_mb_max_to_scan);
>> EXT4_RW_ATTR_SBI_UI(mb_min_to_scan, s_mb_min_to_scan);
>> EXT4_RW_ATTR_SBI_UI(mb_order2_req, s_mb_order2_reqs);
>> @@ -301,6 +322,7 @@ static struct attribute *ext4_attrs[] = {
>> ATTR_LIST(inode_readahead_blks),
>> ATTR_LIST(inode_goal),
>> ATTR_LIST(mb_stats),
>> + ATTR_LIST(mb_stats_clear),
>> ATTR_LIST(mb_max_to_scan),
>> ATTR_LIST(mb_min_to_scan),
>> ATTR_LIST(mb_order2_req),
>> @@ -561,6 +583,8 @@ static ssize_t ext4_attr_store(struct kobject *kobj,
>> return trigger_test_error(sbi, buf, len);
>> case attr_err_report_sec:
>> return err_report_sec_store(sbi, buf, len);
>> + case attr_mb_stats_clear:
>> + return mb_stats_clear_store(sbi, buf, len);
>> default:
>> return ext4_generic_attr_store(a, sbi, buf, len);
>> }
>> -- 
>> 2.51.0
>>
> 
> 
> Cheers, Andreas
> 
> 
> 
> 


^ permalink raw reply

* Re: [PATCH v1] ext4: add mb_stats_clear for mballoc statistics
From: liubaolin @ 2026-04-16  7:16 UTC (permalink / raw)
  To: Ritesh Harjani (IBM), tytso, adilger.kernel
  Cc: linux-ext4, linux-kernel, wangguanyu, Baolin Liu
In-Reply-To: <mrz3u1a4.ritesh.list@gmail.com>

> Dear Ritesh,
> Thank you for your review. I will revise the patch according to Andreas's comments and submit a second version. 
> When the second version is submitted, you are welcome to review it. 
> Once the patch is finalized, the maintainer will add the Reviewed-by tag.
> 
> Regards,
> Baolin



在 2026/4/16 9:44, Ritesh Harjani (IBM) 写道:
> Baolin Liu <liubaolin12138@163.com> writes:
> 
>> From: Baolin Liu <liubaolin@kylinos.cn>
>>
>> Add a write-only mb_stats_clear sysfs knob to reset ext4 mballoc
>> runtime statistics.This makes it easier to inspect allocator
>> activity for a specific workload instead of using counters
>> accumulated since mount.
>>
>> Signed-off-by: Baolin Liu <liubaolin@kylinos.cn>
> 
> Make sense to me. The changes looks good and works fine at my end.
> So please feel free to add:
> 
> Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>


^ permalink raw reply

* Re: [PATCH v1] ext4: add mb_stats_clear for mballoc statistics
From: Zhang Yi @ 2026-04-16  8:53 UTC (permalink / raw)
  To: Baolin Liu, tytso, adilger.kernel
  Cc: linux-ext4, linux-kernel, wangguanyu, Baolin Liu
In-Reply-To: <20260414100212.95209-1-liubaolin12138@163.com>

On 4/14/2026 6:02 PM, Baolin Liu wrote:
> From: Baolin Liu <liubaolin@kylinos.cn>
> 
> Add a write-only mb_stats_clear sysfs knob to reset ext4 mballoc
> runtime statistics.This makes it easier to inspect allocator
> activity for a specific workload instead of using counters
> accumulated since mount.
> 
> Signed-off-by: Baolin Liu <liubaolin@kylinos.cn>

Looks good to me!

Reviewed-by: Zhang Yi <yi.zhang@huawei.com>

> ---
>  fs/ext4/ext4.h    |  1 +
>  fs/ext4/mballoc.c | 31 +++++++++++++++++++++++++++++++
>  fs/ext4/sysfs.c   | 24 ++++++++++++++++++++++++
>  3 files changed, 56 insertions(+)
> 
> diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
> index 7617e2d454ea..3a32e1a515dd 100644
> --- a/fs/ext4/ext4.h
> +++ b/fs/ext4/ext4.h
> @@ -2995,6 +2995,7 @@ int ext4_fc_record_regions(struct super_block *sb, int ino,
>  extern const struct seq_operations ext4_mb_seq_groups_ops;
>  extern const struct seq_operations ext4_mb_seq_structs_summary_ops;
>  extern int ext4_seq_mb_stats_show(struct seq_file *seq, void *offset);
> +extern void ext4_mb_stats_clear(struct ext4_sb_info *sbi);
>  extern int ext4_mb_init(struct super_block *);
>  extern void ext4_mb_release(struct super_block *);
>  extern ext4_fsblk_t ext4_mb_new_blocks(handle_t *,
> diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
> index bb58eafb87bc..382c91586b26 100644
> --- a/fs/ext4/mballoc.c
> +++ b/fs/ext4/mballoc.c
> @@ -3219,6 +3219,8 @@ int ext4_seq_mb_stats_show(struct seq_file *seq, void *offset)
>  	}
>  	seq_printf(seq, "\treqs: %u\n", atomic_read(&sbi->s_bal_reqs));
>  	seq_printf(seq, "\tsuccess: %u\n", atomic_read(&sbi->s_bal_success));
> +	seq_printf(seq, "\tblocks_allocated: %u\n",
> +		   atomic_read(&sbi->s_bal_allocated));
>  
>  	seq_printf(seq, "\tgroups_scanned: %u\n",
>  		   atomic_read(&sbi->s_bal_groups_scanned));
> @@ -4721,6 +4723,35 @@ static void ext4_mb_collect_stats(struct ext4_allocation_context *ac)
>  		trace_ext4_mballoc_prealloc(ac);
>  }
>  
> +void ext4_mb_stats_clear(struct ext4_sb_info *sbi)
> +{
> +	int i;
> +
> +	atomic_set(&sbi->s_bal_reqs, 0);
> +	atomic_set(&sbi->s_bal_success, 0);
> +	atomic_set(&sbi->s_bal_allocated, 0);
> +	atomic_set(&sbi->s_bal_groups_scanned, 0);
> +
> +	for (i = 0; i < EXT4_MB_NUM_CRS; i++) {
> +		atomic64_set(&sbi->s_bal_cX_hits[i], 0);
> +		atomic64_set(&sbi->s_bal_cX_groups_considered[i], 0);
> +		atomic_set(&sbi->s_bal_cX_ex_scanned[i], 0);
> +		atomic64_set(&sbi->s_bal_cX_failed[i], 0);
> +	}
> +
> +	atomic_set(&sbi->s_bal_ex_scanned, 0);
> +	atomic_set(&sbi->s_bal_goals, 0);
> +	atomic_set(&sbi->s_bal_stream_goals, 0);
> +	atomic_set(&sbi->s_bal_len_goals, 0);
> +	atomic_set(&sbi->s_bal_2orders, 0);
> +	atomic_set(&sbi->s_bal_breaks, 0);
> +	atomic_set(&sbi->s_mb_lost_chunks, 0);
> +	atomic_set(&sbi->s_mb_buddies_generated, 0);
> +	atomic64_set(&sbi->s_mb_generation_time, 0);
> +	atomic_set(&sbi->s_mb_preallocated, 0);
> +	atomic_set(&sbi->s_mb_discarded, 0);
> +}
> +
>  /*
>   * Called on failure; free up any blocks from the inode PA for this
>   * context.  We don't need this for MB_GROUP_PA because we only change
> diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c
> index 923b375e017f..a5bd88a99f22 100644
> --- a/fs/ext4/sysfs.c
> +++ b/fs/ext4/sysfs.c
> @@ -41,6 +41,7 @@ typedef enum {
>  	attr_pointer_atomic,
>  	attr_journal_task,
>  	attr_err_report_sec,
> +	attr_mb_stats_clear,
>  } attr_id_t;
>  
>  typedef enum {
> @@ -161,6 +162,25 @@ static ssize_t err_report_sec_store(struct ext4_sb_info *sbi,
>  	return count;
>  }
>  
> +static ssize_t mb_stats_clear_store(struct ext4_sb_info *sbi,
> +				    const char *buf, size_t count)
> +{
> +	int val;
> +	int ret;
> +
> +	if (!capable(CAP_SYS_ADMIN))
> +		return -EPERM;
> +
> +	ret = kstrtoint(skip_spaces(buf), 0, &val);
> +	if (ret)
> +		return ret;
> +	if (val != 1)
> +		return -EINVAL;
> +
> +	ext4_mb_stats_clear(sbi);
> +	return count;
> +}
> +
>  static ssize_t journal_task_show(struct ext4_sb_info *sbi, char *buf)
>  {
>  	if (!sbi->s_journal)
> @@ -251,6 +271,7 @@ EXT4_ATTR_OFFSET(mb_best_avail_max_trim_order, 0644, mb_order,
>  EXT4_ATTR_OFFSET(err_report_sec, 0644, err_report_sec, ext4_sb_info, s_err_report_sec);
>  EXT4_RW_ATTR_SBI_UI(inode_goal, s_inode_goal);
>  EXT4_RW_ATTR_SBI_UI(mb_stats, s_mb_stats);
> +EXT4_ATTR(mb_stats_clear, 0200, mb_stats_clear);
>  EXT4_RW_ATTR_SBI_UI(mb_max_to_scan, s_mb_max_to_scan);
>  EXT4_RW_ATTR_SBI_UI(mb_min_to_scan, s_mb_min_to_scan);
>  EXT4_RW_ATTR_SBI_UI(mb_order2_req, s_mb_order2_reqs);
> @@ -301,6 +322,7 @@ static struct attribute *ext4_attrs[] = {
>  	ATTR_LIST(inode_readahead_blks),
>  	ATTR_LIST(inode_goal),
>  	ATTR_LIST(mb_stats),
> +	ATTR_LIST(mb_stats_clear),
>  	ATTR_LIST(mb_max_to_scan),
>  	ATTR_LIST(mb_min_to_scan),
>  	ATTR_LIST(mb_order2_req),
> @@ -561,6 +583,8 @@ static ssize_t ext4_attr_store(struct kobject *kobj,
>  		return trigger_test_error(sbi, buf, len);
>  	case attr_err_report_sec:
>  		return err_report_sec_store(sbi, buf, len);
> +	case attr_mb_stats_clear:
> +		return mb_stats_clear_store(sbi, buf, len);
>  	default:
>  		return ext4_generic_attr_store(a, sbi, buf, len);
>  	}


^ permalink raw reply

* Re: [PATCH] jbd2: enforce power-of-two default revoke hash size at compile time
From: Jan Kara @ 2026-04-16 10:16 UTC (permalink / raw)
  To: Andreas Dilger; +Cc: Jan Kara, Milos Nikic, tytso, linux-ext4, linux-kernel
In-Reply-To: <C27553C0-0A8E-4BCF-8C6F-1D62A69841C1@dilger.ca>

Hi!

On Wed 15-04-26 19:35:21, Andreas Dilger wrote:
> On Apr 14, 2026, at 06:59, Jan Kara <jack@suse.cz> wrote:
> > On Mon 13-04-26 14:27:24, Milos Nikic wrote:
> >> The jbd2 revoke table relies on bitwise AND operations for fast hash
> >> indexing, which requires the hash table size to be a strict power of two.
> >> 
> >> Currently, this requirement is only enforced at runtime via a J_ASSERT
> >> in jbd2_journal_init_revoke(). While this successfully catches invalid
> >> dynamic allocations, it means a developer accidentally modifying the
> >> hardcoded JOURNAL_REVOKE_DEFAULT_HASH macro will experience a system
> >> panic upon mounting the filesystem during testing.
> >> 
> >> Add a BUILD_BUG_ON() in journal_init_common() to validate the default
> >> macro at compile time. This acts as an immediate, zero-overhead
> >> safeguard, preventing compilation entirely if the default hash size is
> >> mathematically invalid.
> >> 
> >> Signed-off-by: Milos Nikic <nikic.milos@gmail.com>
> > 
> > Eh, if you modify JOURNAL_REVOKE_DEFAULT_HASH you should better know what
> > you are doing and if you mess up, then the kernel failing with assertion
> > isn't that difficult to diagnose. So sorry I don't think this "cleanup" is
> > useful either.
> 
> Jan,
> this is a BUILD_BUG_ON() so it won't cause any runtime assertion.

Yes, I know. But there is already a runtime assertion in
jbd2_journal_init_revoke() making sure the passed value is a power of two
which is verifying also other callers that aren't using
JOURNAL_REVOKE_DEFAULT_HASH value. I don't see a value in the *additional*
BUILD_BUG_ON when we already have that runtime check.

								Honza

-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply

* Re: [patch 18/38] lib/tests: Replace get_cycles() with ktime_get()
From: Geert Uytterhoeven @ 2026-04-16 10:24 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, Andrew Morton, Uladzislau Rezki, linux-mm, Arnd Bergmann,
	x86, Lu Baolu, iommu, Michael Grzeschik, netdev, linux-wireless,
	Herbert Xu, linux-crypto, Vlastimil Babka, David Woodhouse,
	Bernie Thompson, linux-fbdev, Theodore Tso, linux-ext4,
	Marco Elver, Dmitry Vyukov, kasan-dev, Andrey Ryabinin,
	Thomas Sailer, linux-hams, Jason A. Donenfeld, Richard Henderson,
	linux-alpha, Russell King, linux-arm-kernel, Catalin Marinas,
	Huacai Chen, loongarch, linux-m68k, Dinh Nguyen, Jonas Bonn,
	linux-openrisc, Helge Deller, linux-parisc, Michael Ellerman,
	linuxppc-dev, Paul Walmsley, linux-riscv, Heiko Carstens,
	linux-s390, David S. Miller, sparclinux
In-Reply-To: <20260410120318.794680738@kernel.org>

Hi Thomas,

On Fri, 10 Apr 2026 at 14:20, Thomas Gleixner <tglx@kernel.org> wrote:
> get_cycles() is the historical access to a fine grained time source, but it
> is a suboptimal choice for two reasons:
>
>    - get_cycles() is not guaranteed to be supported and functional on all
>      systems/platforms. If not supported or not functional it returns 0,
>      which makes benchmarking moot.
>
>    - get_cycles() returns the raw counter value of whatever the
>      architecture platform provides. The original x86 Time Stamp Counter
>      (TSC) was despite its name tied to the actual CPU core frequency.
>      That's not longer the case. So the counter value is only meaningful
>      when the CPU operates at the same frequency as the TSC or the value is
>      adjusted to the actual CPU frequency. Other architectures and
>      platforms provide similar disjunct counters via get_cycles(), so the
>      result is operations per BOGO-cycles, which is not really meaningful.
>
> Use ktime_get() instead which provides nanosecond timestamps with the
> granularity of the underlying hardware counter, which is not different to
> the variety of get_cycles() implementations.
>
> This provides at least understandable metrics, i.e. operations/nanoseconds,
> and is available on all platforms. As with get_cycles() the result might
> have to be put into relation with the CPU operating frequency, but that's
> not any different.
>
> This is part of a larger effort to remove get_cycles() usage from
> non-architecture code.
>
> Signed-off-by: Thomas Gleixner <tglx@kernel.org>

Thanks for your patch!

> --- a/lib/interval_tree_test.c
> +++ b/lib/interval_tree_test.c
> @@ -65,13 +65,13 @@ static void init(void)
>  static int basic_check(void)
>  {
>         int i, j;
> -       cycles_t time1, time2, time;
> +       ktime_t time1, time2, time;
>
>         printk(KERN_ALERT "interval tree insert/remove");
>
>         init();
>
> -       time1 = get_cycles();
> +       time1 = ktime_get();
>
>         for (i = 0; i < perf_loops; i++) {
>                 for (j = 0; j < nnodes; j++)
> @@ -80,11 +80,11 @@ static int basic_check(void)
>                         interval_tree_remove(nodes + j, &root);
>         }
>
> -       time2 = get_cycles();
> +       time2 = ktime_get();
>         time = time2 - time1;
>
>         time = div_u64(time, perf_loops);
> -       printk(" -> %llu cycles\n", (unsigned long long)time);
> +       printk(" -> %llu nsecs\n", (unsigned long long)time);

While cycles_t was unsigned long or long long, ktime_t is always s64,
so "%lld", and the cast can be dropped (everywhere).

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox