Skip to content

Commit 1c8bb61

Browse files
Naman Jainkawasaki
authored andcommitted
block: allow different-pgmap pages as separate bvecs in bio_add_page
bio_add_page() and bio_integrity_add_page() reject pages from a different dev_pagemap entirely, returning 0 even when the page could be added as a new bvec entry. The pgmap check was intended only to prevent merging into the same bvec segment, not to block the page from being added at all. This causes callers to unnecessarily start a new bio when a buffer spans pages from two different pgmaps, even though the bio has room for another bvec. Fix both functions by moving the zone_device_pages_have_same_pgmap() check into the merge conditional. Pages from different pgmaps now skip the merge attempt and fall through to be added as new separate bvec entries. This is safe because biovec_phys_mergeable() now also checks for pgmap mismatches, preventing the downstream merge, DMA mapping, and request coalescing paths from combining segments across pgmaps. Fixes: 49580e6 ("block: add check when merging zone device pages") Cc: [email protected] Signed-off-by: Naman Jain <[email protected]>
1 parent ef07a93 commit 1c8bb61

2 files changed

Lines changed: 4 additions & 8 deletions

File tree

block/bio-integrity.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,8 @@ int bio_integrity_add_page(struct bio *bio, struct page *page,
167167
if (bip->bip_vcnt > 0) {
168168
struct bio_vec *bv = &bip->bip_vec[bip->bip_vcnt - 1];
169169

170-
if (!zone_device_pages_have_same_pgmap(bv->bv_page, page))
171-
return 0;
172-
173-
if (bvec_try_merge_hw_page(q, bv, page, len, offset)) {
170+
if (zone_device_pages_have_same_pgmap(bv->bv_page, page) &&
171+
bvec_try_merge_hw_page(q, bv, page, len, offset)) {
174172
bip->bip_iter.bi_size += len;
175173
return len;
176174
}

block/bio.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,10 +1070,8 @@ int bio_add_page(struct bio *bio, struct page *page,
10701070
if (bio->bi_vcnt > 0) {
10711071
struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt - 1];
10721072

1073-
if (!zone_device_pages_have_same_pgmap(bv->bv_page, page))
1074-
return 0;
1075-
1076-
if (bvec_try_merge_page(bv, page, len, offset)) {
1073+
if (zone_device_pages_have_same_pgmap(bv->bv_page, page) &&
1074+
bvec_try_merge_page(bv, page, len, offset)) {
10771075
bio->bi_iter.bi_size += len;
10781076
return len;
10791077
}

0 commit comments

Comments
 (0)