[PATCH 03/15] md: use folio for bb_folio

linan666@huaweicloud.com posted 15 patches 1 month, 3 weeks ago
There is a newer version of this series
[PATCH 03/15] md: use folio for bb_folio
Posted by linan666@huaweicloud.com 1 month, 3 weeks ago
From: Li Nan <linan122@huawei.com>

Convert bio_page to bio_folio and use it throughout.

Signed-off-by: Li Nan <linan122@huawei.com>
---
 drivers/md/md.h |  3 ++-
 drivers/md/md.c | 25 +++++++++++++------------
 2 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/md/md.h b/drivers/md/md.h
index 410f8a6b75e7..aa6d9df50fd0 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -144,7 +144,8 @@ struct md_rdev {
 	struct block_device *bdev;	/* block device handle */
 	struct file *bdev_file;		/* Handle from open for bdev */
 
-	struct page	*sb_page, *bb_page;
+	struct page	*sb_page;
+	struct folio	*bb_folio;
 	int		sb_loaded;
 	__u64		sb_events;
 	sector_t	data_offset;	/* start of data in array */
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 9dfd6f8da5b8..0732bbcdb95d 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1073,9 +1073,9 @@ void md_rdev_clear(struct md_rdev *rdev)
 		rdev->sb_start = 0;
 		rdev->sectors = 0;
 	}
-	if (rdev->bb_page) {
-		put_page(rdev->bb_page);
-		rdev->bb_page = NULL;
+	if (rdev->bb_folio) {
+		folio_put(rdev->bb_folio);
+		rdev->bb_folio = NULL;
 	}
 	badblocks_exit(&rdev->badblocks);
 }
@@ -1909,9 +1909,10 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_
 
 	rdev->desc_nr = le32_to_cpu(sb->dev_number);
 
-	if (!rdev->bb_page) {
-		rdev->bb_page = alloc_page(GFP_KERNEL);
-		if (!rdev->bb_page)
+	if (!rdev->bb_folio) {
+		rdev->bb_folio = folio_alloc(GFP_KERNEL, 0);
+
+		if (!rdev->bb_folio)
 			return -ENOMEM;
 	}
 	if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_BAD_BLOCKS) &&
@@ -1930,10 +1931,10 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_
 		if (offset == 0)
 			return -EINVAL;
 		bb_sector = (long long)offset;
-		if (!sync_page_io(rdev, bb_sector, sectors << 9,
-				  rdev->bb_page, REQ_OP_READ, true))
+		if (!sync_folio_io(rdev, bb_sector, sectors << 9, 0,
+				  rdev->bb_folio, REQ_OP_READ, true))
 			return -EIO;
-		bbp = (__le64 *)page_address(rdev->bb_page);
+		bbp = (__le64 *)folio_address(rdev->bb_folio);
 		rdev->badblocks.shift = sb->bblog_shift;
 		for (i = 0 ; i < (sectors << (9-3)) ; i++, bbp++) {
 			u64 bb = le64_to_cpu(*bbp);
@@ -2300,7 +2301,7 @@ static void super_1_sync(struct mddev *mddev, struct md_rdev *rdev)
 		md_error(mddev, rdev);
 	else {
 		struct badblocks *bb = &rdev->badblocks;
-		__le64 *bbp = (__le64 *)page_address(rdev->bb_page);
+		__le64 *bbp = (__le64 *)folio_address(rdev->bb_folio);
 		u64 *p = bb->page;
 		sb->feature_map |= cpu_to_le32(MD_FEATURE_BAD_BLOCKS);
 		if (bb->changed) {
@@ -2953,7 +2954,7 @@ void md_update_sb(struct mddev *mddev, int force_change)
 				md_write_metadata(mddev, rdev,
 						  rdev->badblocks.sector,
 						  rdev->badblocks.size << 9,
-						  rdev->bb_page, 0);
+						  folio_page(rdev->bb_folio, 0), 0);
 				rdev->badblocks.size = 0;
 			}
 
@@ -3809,7 +3810,7 @@ int md_rdev_init(struct md_rdev *rdev)
 	rdev->sb_events = 0;
 	rdev->last_read_error = 0;
 	rdev->sb_loaded = 0;
-	rdev->bb_page = NULL;
+	rdev->bb_folio = NULL;
 	atomic_set(&rdev->nr_pending, 0);
 	atomic_set(&rdev->read_errors, 0);
 	atomic_set(&rdev->corrected_errors, 0);
-- 
2.39.2
Re: [PATCH 03/15] md: use folio for bb_folio
Posted by Xiao Ni 3 weeks, 1 day ago
On Wed, Dec 17, 2025 at 8:11 PM <linan666@huaweicloud.com> wrote:
>
> From: Li Nan <linan122@huawei.com>
>
> Convert bio_page to bio_folio and use it throughout.
>
> Signed-off-by: Li Nan <linan122@huawei.com>
> ---
>  drivers/md/md.h |  3 ++-
>  drivers/md/md.c | 25 +++++++++++++------------
>  2 files changed, 15 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/md/md.h b/drivers/md/md.h
> index 410f8a6b75e7..aa6d9df50fd0 100644
> --- a/drivers/md/md.h
> +++ b/drivers/md/md.h
> @@ -144,7 +144,8 @@ struct md_rdev {
>         struct block_device *bdev;      /* block device handle */
>         struct file *bdev_file;         /* Handle from open for bdev */
>
> -       struct page     *sb_page, *bb_page;
> +       struct page     *sb_page;
> +       struct folio    *bb_folio;
>         int             sb_loaded;
>         __u64           sb_events;
>         sector_t        data_offset;    /* start of data in array */
> diff --git a/drivers/md/md.c b/drivers/md/md.c
> index 9dfd6f8da5b8..0732bbcdb95d 100644
> --- a/drivers/md/md.c
> +++ b/drivers/md/md.c
> @@ -1073,9 +1073,9 @@ void md_rdev_clear(struct md_rdev *rdev)
>                 rdev->sb_start = 0;
>                 rdev->sectors = 0;
>         }
> -       if (rdev->bb_page) {
> -               put_page(rdev->bb_page);
> -               rdev->bb_page = NULL;
> +       if (rdev->bb_folio) {
> +               folio_put(rdev->bb_folio);
> +               rdev->bb_folio = NULL;
>         }
>         badblocks_exit(&rdev->badblocks);
>  }
> @@ -1909,9 +1909,10 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_
>
>         rdev->desc_nr = le32_to_cpu(sb->dev_number);
>
> -       if (!rdev->bb_page) {
> -               rdev->bb_page = alloc_page(GFP_KERNEL);
> -               if (!rdev->bb_page)
> +       if (!rdev->bb_folio) {
> +               rdev->bb_folio = folio_alloc(GFP_KERNEL, 0);
> +
> +               if (!rdev->bb_folio)
>                         return -ENOMEM;
>         }
>         if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_BAD_BLOCKS) &&
> @@ -1930,10 +1931,10 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_
>                 if (offset == 0)
>                         return -EINVAL;
>                 bb_sector = (long long)offset;
> -               if (!sync_page_io(rdev, bb_sector, sectors << 9,
> -                                 rdev->bb_page, REQ_OP_READ, true))
> +               if (!sync_folio_io(rdev, bb_sector, sectors << 9, 0,
> +                                 rdev->bb_folio, REQ_OP_READ, true))
>                         return -EIO;
> -               bbp = (__le64 *)page_address(rdev->bb_page);
> +               bbp = (__le64 *)folio_address(rdev->bb_folio);
>                 rdev->badblocks.shift = sb->bblog_shift;
>                 for (i = 0 ; i < (sectors << (9-3)) ; i++, bbp++) {
>                         u64 bb = le64_to_cpu(*bbp);
> @@ -2300,7 +2301,7 @@ static void super_1_sync(struct mddev *mddev, struct md_rdev *rdev)
>                 md_error(mddev, rdev);
>         else {
>                 struct badblocks *bb = &rdev->badblocks;
> -               __le64 *bbp = (__le64 *)page_address(rdev->bb_page);
> +               __le64 *bbp = (__le64 *)folio_address(rdev->bb_folio);
>                 u64 *p = bb->page;
>                 sb->feature_map |= cpu_to_le32(MD_FEATURE_BAD_BLOCKS);
>                 if (bb->changed) {
> @@ -2953,7 +2954,7 @@ void md_update_sb(struct mddev *mddev, int force_change)
>                                 md_write_metadata(mddev, rdev,
>                                                   rdev->badblocks.sector,
>                                                   rdev->badblocks.size << 9,
> -                                                 rdev->bb_page, 0);
> +                                                 folio_page(rdev->bb_folio, 0), 0);
>                                 rdev->badblocks.size = 0;
>                         }
>
> @@ -3809,7 +3810,7 @@ int md_rdev_init(struct md_rdev *rdev)
>         rdev->sb_events = 0;
>         rdev->last_read_error = 0;
>         rdev->sb_loaded = 0;
> -       rdev->bb_page = NULL;
> +       rdev->bb_folio = NULL;
>         atomic_set(&rdev->nr_pending, 0);
>         atomic_set(&rdev->read_errors, 0);
>         atomic_set(&rdev->corrected_errors, 0);
> --
> 2.39.2
>

Hi Nan

Bad block page is only one single page. I don't think it's necessary
to use folio here. And it uses folio_page to get the page again. Or do
you plan to replace all page apis to folio apis? Looking through all
patches, sync_page_io is not removed. In patch02, it says sync_page_io
will be removed. So maybe it's better to switch bb_page to bb_folio in
your second patch set? And this patch set only focuses on replacing
sync pages with folio. It's my 2 cents point. If you think it's better
to change the bad block page here, I'm still ok.

Best Regards
Xiao
Re: [PATCH 03/15] md: use folio for bb_folio
Posted by Li Nan 2 weeks, 6 days ago

在 2026/1/19 11:03, Xiao Ni 写道:
> On Wed, Dec 17, 2025 at 8:11 PM <linan666@huaweicloud.com> wrote:
>>
>> From: Li Nan <linan122@huawei.com>
>>
>> Convert bio_page to bio_folio and use it throughout.
>>
>> Signed-off-by: Li Nan <linan122@huawei.com>
>> ---
>>   drivers/md/md.h |  3 ++-
>>   drivers/md/md.c | 25 +++++++++++++------------
>>   2 files changed, 15 insertions(+), 13 deletions(-)
>>
>> diff --git a/drivers/md/md.h b/drivers/md/md.h
>> index 410f8a6b75e7..aa6d9df50fd0 100644
>> --- a/drivers/md/md.h
>> +++ b/drivers/md/md.h
>> @@ -144,7 +144,8 @@ struct md_rdev {
>>          struct block_device *bdev;      /* block device handle */
>>          struct file *bdev_file;         /* Handle from open for bdev */
>>
>> -       struct page     *sb_page, *bb_page;
>> +       struct page     *sb_page;
>> +       struct folio    *bb_folio;
>>          int             sb_loaded;
>>          __u64           sb_events;
>>          sector_t        data_offset;    /* start of data in array */
>> diff --git a/drivers/md/md.c b/drivers/md/md.c
>> index 9dfd6f8da5b8..0732bbcdb95d 100644
>> --- a/drivers/md/md.c
>> +++ b/drivers/md/md.c
>> @@ -1073,9 +1073,9 @@ void md_rdev_clear(struct md_rdev *rdev)
>>                  rdev->sb_start = 0;
>>                  rdev->sectors = 0;
>>          }
>> -       if (rdev->bb_page) {
>> -               put_page(rdev->bb_page);
>> -               rdev->bb_page = NULL;
>> +       if (rdev->bb_folio) {
>> +               folio_put(rdev->bb_folio);
>> +               rdev->bb_folio = NULL;
>>          }
>>          badblocks_exit(&rdev->badblocks);
>>   }
>> @@ -1909,9 +1909,10 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_
>>
>>          rdev->desc_nr = le32_to_cpu(sb->dev_number);
>>
>> -       if (!rdev->bb_page) {
>> -               rdev->bb_page = alloc_page(GFP_KERNEL);
>> -               if (!rdev->bb_page)
>> +       if (!rdev->bb_folio) {
>> +               rdev->bb_folio = folio_alloc(GFP_KERNEL, 0);
>> +
>> +               if (!rdev->bb_folio)
>>                          return -ENOMEM;
>>          }
>>          if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_BAD_BLOCKS) &&
>> @@ -1930,10 +1931,10 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_
>>                  if (offset == 0)
>>                          return -EINVAL;
>>                  bb_sector = (long long)offset;
>> -               if (!sync_page_io(rdev, bb_sector, sectors << 9,
>> -                                 rdev->bb_page, REQ_OP_READ, true))
>> +               if (!sync_folio_io(rdev, bb_sector, sectors << 9, 0,
>> +                                 rdev->bb_folio, REQ_OP_READ, true))
>>                          return -EIO;
>> -               bbp = (__le64 *)page_address(rdev->bb_page);
>> +               bbp = (__le64 *)folio_address(rdev->bb_folio);
>>                  rdev->badblocks.shift = sb->bblog_shift;
>>                  for (i = 0 ; i < (sectors << (9-3)) ; i++, bbp++) {
>>                          u64 bb = le64_to_cpu(*bbp);
>> @@ -2300,7 +2301,7 @@ static void super_1_sync(struct mddev *mddev, struct md_rdev *rdev)
>>                  md_error(mddev, rdev);
>>          else {
>>                  struct badblocks *bb = &rdev->badblocks;
>> -               __le64 *bbp = (__le64 *)page_address(rdev->bb_page);
>> +               __le64 *bbp = (__le64 *)folio_address(rdev->bb_folio);
>>                  u64 *p = bb->page;
>>                  sb->feature_map |= cpu_to_le32(MD_FEATURE_BAD_BLOCKS);
>>                  if (bb->changed) {
>> @@ -2953,7 +2954,7 @@ void md_update_sb(struct mddev *mddev, int force_change)
>>                                  md_write_metadata(mddev, rdev,
>>                                                    rdev->badblocks.sector,
>>                                                    rdev->badblocks.size << 9,
>> -                                                 rdev->bb_page, 0);
>> +                                                 folio_page(rdev->bb_folio, 0), 0);
>>                                  rdev->badblocks.size = 0;
>>                          }
>>
>> @@ -3809,7 +3810,7 @@ int md_rdev_init(struct md_rdev *rdev)
>>          rdev->sb_events = 0;
>>          rdev->last_read_error = 0;
>>          rdev->sb_loaded = 0;
>> -       rdev->bb_page = NULL;
>> +       rdev->bb_folio = NULL;
>>          atomic_set(&rdev->nr_pending, 0);
>>          atomic_set(&rdev->read_errors, 0);
>>          atomic_set(&rdev->corrected_errors, 0);
>> --
>> 2.39.2
>>
> 
> Hi Nan
> 
> Bad block page is only one single page. I don't think it's necessary
> to use folio here. And it uses folio_page to get the page again. Or do
> you plan to replace all page apis to folio apis? Looking through all
> patches, sync_page_io is not removed. In patch02, it says sync_page_io
> will be removed. So maybe it's better to switch bb_page to bb_folio in
> your second patch set? And this patch set only focuses on replacing
> sync pages with folio. It's my 2 cents point. If you think it's better
> to change the bad block page here, I'm still ok.
> 
> Best Regards
> Xiao
> 

Hi Xiao,

Thanks for your review. Move it to next patch set is fine. I will delete
this patch in v2.

-- 
Thanks,
Nan