]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
btrfs: add tracking of read blocks for read policy
authorAnand Jain <anand.jain@oracle.com>
Wed, 1 Jan 2025 18:06:34 +0000 (02:06 +0800)
committerDavid Sterba <dsterba@suse.com>
Mon, 13 Jan 2025 13:53:21 +0000 (14:53 +0100)
Track number of read blocks in the whole filesystem. The counter is
initialized when devices are opened. The counter is increased at
btrfs_submit_dev_bio() if the stats tracking is enabled (depends on the
read policy).  Stats tracking is disabled by default and is enabled
through fs_devices::collect_fs_stats when required.

The code is not under the EXPERIMENTAL define, as stats can be expanded
to include write counts and other performance counters, with the user
interface independent of its internal use.

This is an in-memory-only feature, not related to the dev error stats.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/bio.c
fs/btrfs/disk-io.c
fs/btrfs/fs.h
fs/btrfs/volumes.h

index bc80ee4f95a5a8de05f2664f68ac4fcb62864d7b..bc2555c44a120688c4571d8c0b8c30304ed3cdd4 100644 (file)
@@ -453,6 +453,14 @@ static void btrfs_submit_dev_bio(struct btrfs_device *dev, struct bio *bio)
                (unsigned long)dev->bdev->bd_dev, btrfs_dev_name(dev),
                dev->devid, bio->bi_iter.bi_size);
 
+       /*
+        * Track reads if tracking is enabled; ignore I/O operations before the
+        * filesystem is fully initialized.
+        */
+       if (dev->fs_devices->collect_fs_stats && bio_op(bio) == REQ_OP_READ && dev->fs_info)
+               percpu_counter_add(&dev->fs_info->stats_read_blocks,
+                                  bio->bi_iter.bi_size >> dev->fs_info->sectorsize_bits);
+
        if (bio->bi_opf & REQ_BTRFS_CGROUP_PUNT)
                blkcg_punt_bio_submit(bio);
        else
index 4928bf2cd07fe0d941bbc080e44286d90382f82f..ef3121b55c50b02686aad378f3223deff6a1a045 100644 (file)
@@ -1258,6 +1258,7 @@ void btrfs_free_fs_info(struct btrfs_fs_info *fs_info)
 {
        struct percpu_counter *em_counter = &fs_info->evictable_extent_maps;
 
+       percpu_counter_destroy(&fs_info->stats_read_blocks);
        percpu_counter_destroy(&fs_info->dirty_metadata_bytes);
        percpu_counter_destroy(&fs_info->delalloc_bytes);
        percpu_counter_destroy(&fs_info->ordered_bytes);
@@ -2923,6 +2924,10 @@ static int init_mount_fs_info(struct btrfs_fs_info *fs_info, struct super_block
        if (ret)
                return ret;
 
+       ret = percpu_counter_init(&fs_info->stats_read_blocks, 0, GFP_KERNEL);
+       if (ret)
+               return ret;
+
        fs_info->dirty_metadata_batch = PAGE_SIZE *
                                        (1 + ilog2(nr_cpu_ids));
 
index be8c32d1a7bbe096fc62c858992c4133045d8123..b572d6b9730b2217f4b637b3bde96bcab34b6824 100644 (file)
@@ -627,6 +627,9 @@ struct btrfs_fs_info {
        struct kobject *qgroups_kobj;
        struct kobject *discard_kobj;
 
+       /* Track the number of blocks (sectors) read by the filesystem. */
+       struct percpu_counter stats_read_blocks;
+
        /* Used to keep from writing metadata until there is a nice batch */
        struct percpu_counter dirty_metadata_bytes;
        struct percpu_counter delalloc_bytes;
index 10bdd731e3fcc889237b4e1b05cc9389bc937659..77926fdb6b0dd88f46fb60217f03a0b449bb5669 100644 (file)
@@ -417,6 +417,8 @@ struct btrfs_fs_devices {
        bool seeding;
        /* The mount needs to use a randomly generated fsid. */
        bool temp_fsid;
+       /* Enable/disable the filesystem stats tracking. */
+       bool collect_fs_stats;
 
        struct btrfs_fs_info *fs_info;
        /* sysfs kobjects */