2022-05-17 00:13:59

by Pankaj Raghav

[permalink] [raw]
Subject: [PATCH v4 05/13] btrfs: zoned: Cache superblock location in btrfs_zoned_device_info

Instead of calculating the superblock location every time, cache the
superblock zone location in btrfs_zoned_device_info struct and use it to
locate the zone index.

The functions such as btrfs_sb_log_location_bdev() and
btrfs_reset_sb_log_zones() which work directly on block_device shall
continue to use the sb_zone_number because btrfs_zoned_device_info
struct might not have been initialized at that point.

This patch will enable non power-of-2 zoned devices to not perform
division to lookup superblock and its mirror location.

Reviewed-by: Luis Chamberlain <[email protected]>
Signed-off-by: Pankaj Raghav <[email protected]>
---
fs/btrfs/zoned.c | 13 +++++++++----
fs/btrfs/zoned.h | 1 +
2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
index 06f22c021..e8c7cebb2 100644
--- a/fs/btrfs/zoned.c
+++ b/fs/btrfs/zoned.c
@@ -511,6 +511,11 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device, bool populate_cache)
max_active_zones - nactive);
}

+ /* Cache the sb zone number */
+ for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; ++i) {
+ zone_info->sb_zone_location[i] =
+ sb_zone_number(zone_info->zone_size_shift, i);
+ }
/* Validate superblock log */
nr_zones = BTRFS_NR_SB_LOG_ZONES;
for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
@@ -518,7 +523,7 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device, bool populate_cache)
u64 sb_wp;
int sb_pos = BTRFS_NR_SB_LOG_ZONES * i;

- sb_zone = sb_zone_number(zone_info->zone_size_shift, i);
+ sb_zone = zone_info->sb_zone_location[i];
if (sb_zone + 1 >= zone_info->nr_zones)
continue;

@@ -866,7 +871,7 @@ int btrfs_sb_log_location(struct btrfs_device *device, int mirror, int rw,
return 0;
}

- zone_num = sb_zone_number(zinfo->zone_size_shift, mirror);
+ zone_num = zinfo->sb_zone_location[mirror];
if (zone_num + 1 >= zinfo->nr_zones)
return -ENOENT;

@@ -883,7 +888,7 @@ static inline bool is_sb_log_zone(struct btrfs_zoned_device_info *zinfo,
if (!zinfo)
return false;

- zone_num = sb_zone_number(zinfo->zone_size_shift, mirror);
+ zone_num = zinfo->sb_zone_location[mirror];
if (zone_num + 1 >= zinfo->nr_zones)
return false;

@@ -1011,7 +1016,7 @@ u64 btrfs_find_allocatable_zones(struct btrfs_device *device, u64 hole_start,
u32 sb_zone;
u64 sb_pos;

- sb_zone = sb_zone_number(shift, i);
+ sb_zone = zinfo->sb_zone_location[i];
if (!(end <= sb_zone ||
sb_zone + BTRFS_NR_SB_LOG_ZONES <= begin)) {
have_sb = true;
diff --git a/fs/btrfs/zoned.h b/fs/btrfs/zoned.h
index 10f31d1c8..694ab6d1e 100644
--- a/fs/btrfs/zoned.h
+++ b/fs/btrfs/zoned.h
@@ -27,6 +27,7 @@ struct btrfs_zoned_device_info {
unsigned long *active_zones;
struct blk_zone *zone_cache;
struct blk_zone sb_zones[2 * BTRFS_SUPER_MIRROR_MAX];
+ u32 sb_zone_location[BTRFS_SUPER_MIRROR_MAX];
};

#ifdef CONFIG_BLK_DEV_ZONED
--
2.25.1



2022-05-17 02:19:51

by David Sterba

[permalink] [raw]
Subject: Re: [PATCH v4 05/13] btrfs: zoned: Cache superblock location in btrfs_zoned_device_info

On Mon, May 16, 2022 at 06:54:08PM +0200, Pankaj Raghav wrote:
> Instead of calculating the superblock location every time, cache the
> superblock zone location in btrfs_zoned_device_info struct and use it to
> locate the zone index.
>
> The functions such as btrfs_sb_log_location_bdev() and
> btrfs_reset_sb_log_zones() which work directly on block_device shall
> continue to use the sb_zone_number because btrfs_zoned_device_info
> struct might not have been initialized at that point.
>
> This patch will enable non power-of-2 zoned devices to not perform
> division to lookup superblock and its mirror location.
>
> Reviewed-by: Luis Chamberlain <[email protected]>
> Signed-off-by: Pankaj Raghav <[email protected]>
> ---
> fs/btrfs/zoned.c | 13 +++++++++----
> fs/btrfs/zoned.h | 1 +
> 2 files changed, 10 insertions(+), 4 deletions(-)
>
> diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
> index 06f22c021..e8c7cebb2 100644
> --- a/fs/btrfs/zoned.c
> +++ b/fs/btrfs/zoned.c
> @@ -511,6 +511,11 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device, bool populate_cache)
> max_active_zones - nactive);
> }
>
> + /* Cache the sb zone number */
> + for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; ++i) {
> + zone_info->sb_zone_location[i] =
> + sb_zone_number(zone_info->zone_size_shift, i);
> + }

I don't think we need to cache the value right now, it's not in any hot
path and call to bdev_zone_no is relatively cheap (only dereferencing a
few pointers, all in-memory values).

2022-05-17 13:17:07

by Pankaj Raghav

[permalink] [raw]
Subject: Re: [PATCH v4 05/13] btrfs: zoned: Cache superblock location in btrfs_zoned_device_info

On 2022-05-16 23:58, David Sterba wrote:
>> Reviewed-by: Luis Chamberlain <[email protected]>
>> Signed-off-by: Pankaj Raghav <[email protected]>
>> ---
>> fs/btrfs/zoned.c | 13 +++++++++----
>> fs/btrfs/zoned.h | 1 +
>> 2 files changed, 10 insertions(+), 4 deletions(-)
>>
>> diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
>> index 06f22c021..e8c7cebb2 100644
>> --- a/fs/btrfs/zoned.c
>> +++ b/fs/btrfs/zoned.c
>> @@ -511,6 +511,11 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device, bool populate_cache)
>> max_active_zones - nactive);
>> }
>>
>> + /* Cache the sb zone number */
>> + for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; ++i) {
>> + zone_info->sb_zone_location[i] =
>> + sb_zone_number(zone_info->zone_size_shift, i);
>> + }
>
> I don't think we need to cache the value right now, it's not in any hot
> path and call to bdev_zone_no is relatively cheap (only dereferencing a
> few pointers, all in-memory values).
Ok. I will fix it up in the next revision! Thanks.