block: fix pgmap handling for zone device pages in bio merge paths#712
block: fix pgmap handling for zone device pages in bio merge paths#712blktests-ci[bot] wants to merge 2 commits intolinus-master_basefrom
Conversation
|
Upstream branch: 9147566 |
|
Upstream branch: 9147566 |
91b056d to
3c59258
Compare
ecbdbb4 to
480b162
Compare
|
Upstream branch: 9147566 |
3c59258 to
17ca370
Compare
a96fba7 to
0cd6ac2
Compare
|
Upstream branch: 9147566 |
17ca370 to
1c8bb61
Compare
0cd6ac2 to
910d344
Compare
|
Upstream branch: d8a9a4b |
1c8bb61 to
043be15
Compare
910d344 to
ed862bc
Compare
|
Upstream branch: 7ca6d1c |
043be15 to
1de2fc3
Compare
ed862bc to
2d0c3d5
Compare
|
Upstream branch: 3aae938 |
1de2fc3 to
0f98c7c
Compare
2d0c3d5 to
931d9b0
Compare
|
Upstream branch: 3036cd0 |
0f98c7c to
f913d24
Compare
931d9b0 to
78a4682
Compare
|
Upstream branch: 9a9c8ce |
f913d24 to
216bd2b
Compare
|
Upstream branch: 9a9c8ce |
biovec_phys_mergeable() is used by the request merge, DMA mapping, and integrity merge paths to decide if two physically contiguous bvec segments can be coalesced into one. It currently has no check for whether the segments belong to different dev_pagemaps. When zone device memory is registered in multiple chunks, each chunk gets its own dev_pagemap. A single bio can legitimately contain bvecs from different pgmaps -- iov_iter_extract_bvecs() breaks at pgmap boundaries but the outer loop in bio_iov_iter_get_pages() continues filling the same bio. If such bvecs are physically contiguous, biovec_phys_mergeable() will coalesce them, making it impossible to recover the correct pgmap for the merged segment via page_pgmap(). Add a zone_device_pages_have_same_pgmap() check to prevent merging bvec segments that span different pgmaps. Fixes: 49580e6 ("block: add check when merging zone device pages") Cc: stable@vger.kernel.org Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
…ages bio_add_page() and bio_integrity_add_page() reject pages from different dev_pagemaps entirely, returning 0 even when those pages have compatible DMA mapping requirements. This forces callers to start a new bio when buffers span pgmap boundaries, even though the pages could safely coexist as separate bvec entries. This matters for guests where memory is registered through devm_memremap_pages() with MEMORY_DEVICE_GENERIC in multiple calls, creating separate dev_pagemaps for each chunk. When a direct I/O buffer spans two such chunks, bio_add_page() rejects the second page, forcing an unnecessary bio split or I/O failure. Introduce zone_device_pages_compatible() in blk.h to check whether two pages can coexist in the same bio as separate bvec entries. The block DMA iterator (blk_dma_map_iter_start) caches the P2PDMA mapping state from the first segment and applies it to all others, so P2PDMA pages from different pgmaps must not be mixed, and neither must P2PDMA and non-P2PDMA pages. All other combinations (MEMORY_DEVICE_GENERIC pages from different pgmaps, or MEMORY_DEVICE_GENERIC with normal RAM) use the same dma_map_phys path and are safe. Replace the blanket zone_device_pages_have_same_pgmap() rejection with zone_device_pages_compatible(), while keeping zone_device_pages_have_same_pgmap() as a merge guard. Pages from different pgmaps can be added as separate bvec entries but must not be coalesced into the same segment, as that would make it impossible to recover the correct pgmap via page_pgmap(). Fixes: 49580e6 ("block: add check when merging zone device pages") Cc: stable@vger.kernel.org Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
216bd2b to
f341413
Compare
Pull request for series with
subject: block: fix pgmap handling for zone device pages in bio merge paths
version: 1
url: https://patchwork.kernel.org/project/linux-block/list/?series=1075658