diff mbox series

[v2] btrfs: zoned: use alloc_list instead of RCU locked device_list

Message ID c13ae130cf4d170da60d9bde63de78e3583611df.1647425970.git.johannes.thumshirn@wdc.com (mailing list archive)
State New, archived
Headers show
Series [v2] btrfs: zoned: use alloc_list instead of RCU locked device_list | expand

Commit Message

Johannes Thumshirn March 16, 2022, 4:21 p.m. UTC
Anand pointed out, that instead of using the RCU locked version of
fs_devices->device_list we can use fs_devices->alloc_list, protected by
the chunk_mutex to traverse the list of active devices in
btrfs_can_activate_zone().

We are in the chunk allocation thread. The newer chunk allocation
happens from the devices in the fs_device->alloc_list protected by the
chunk_mutex.

  btrfs_create_chunk()
    lockdep_assert_held(&info->chunk_mutex);
    gather_device_info
      list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list)

Also, a device that reappears after the mount won't join the alloc_list
yet and, it will be in the dev_list, which we don't want to consider in
the context of the chunk alloc.

Suggested-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
---
Changes since v1:
* Fix crash Anand reported
---
 fs/btrfs/zoned.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

Comments

David Sterba March 16, 2022, 4:35 p.m. UTC | #1
On Wed, Mar 16, 2022 at 09:21:12AM -0700, Johannes Thumshirn wrote:
> Anand pointed out, that instead of using the RCU locked version of
> fs_devices->device_list we can use fs_devices->alloc_list, protected by
> the chunk_mutex to traverse the list of active devices in
> btrfs_can_activate_zone().
> 
> We are in the chunk allocation thread. The newer chunk allocation
> happens from the devices in the fs_device->alloc_list protected by the
> chunk_mutex.
> 
>   btrfs_create_chunk()
>     lockdep_assert_held(&info->chunk_mutex);
>     gather_device_info
>       list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list)
> 
> Also, a device that reappears after the mount won't join the alloc_list
> yet and, it will be in the dev_list, which we don't want to consider in
> the context of the chunk alloc.
> 
> Suggested-by: Anand Jain <anand.jain@oracle.com>
> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
> ---
> Changes since v1:
> * Fix crash Anand reported

Patch updated, thanks.
diff mbox series

Patch

diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
index 49446bb5a5d1..1b1b310c3c51 100644
--- a/fs/btrfs/zoned.c
+++ b/fs/btrfs/zoned.c
@@ -1975,15 +1975,16 @@  int btrfs_zone_finish(struct btrfs_block_group *block_group)
 
 bool btrfs_can_activate_zone(struct btrfs_fs_devices *fs_devices, u64 flags)
 {
+	struct btrfs_fs_info *fs_info = fs_devices->fs_info;
 	struct btrfs_device *device;
 	bool ret = false;
 
-	if (!btrfs_is_zoned(fs_devices->fs_info))
+	if (!btrfs_is_zoned(fs_info))
 		return true;
 
 	/* Check if there is a device with active zones left */
-	rcu_read_lock();
-	list_for_each_entry_rcu(device, &fs_devices->devices, dev_list) {
+	mutex_lock(&fs_info->chunk_mutex);
+	list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) {
 		struct btrfs_zoned_device_info *zinfo = device->zone_info;
 
 		if (!device->bdev)
@@ -1995,7 +1996,7 @@  bool btrfs_can_activate_zone(struct btrfs_fs_devices *fs_devices, u64 flags)
 			break;
 		}
 	}
-	rcu_read_unlock();
+	mutex_unlock(&fs_info->chunk_mutex);
 
 	return ret;
 }