]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
block: add pgmap check to biovec_phys_mergeable
authorNaman Jain <namjain@linux.microsoft.com>
Fri, 10 Apr 2026 15:34:13 +0000 (15:34 +0000)
committerJens Axboe <axboe@kernel.dk>
Fri, 17 Apr 2026 20:37:08 +0000 (14:37 -0600)
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: 49580e690755 ("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>
Link: https://patch.msgid.link/20260410153414.4159050-2-namjain@linux.microsoft.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/blk.h

index ec4674cdf2ead4fd259ff5fc42401f591e684ee9..50a41db0391331f9d0abe4fcf81e60cb6fd31fdf 100644 (file)
@@ -127,6 +127,8 @@ static inline bool biovec_phys_mergeable(struct request_queue *q,
 
        if (addr1 + vec1->bv_len != addr2)
                return false;
+       if (!zone_device_pages_have_same_pgmap(vec1->bv_page, vec2->bv_page))
+               return false;
        if (xen_domain() && !xen_biovec_phys_mergeable(vec1, vec2->bv_page))
                return false;
        if ((addr1 | mask) != ((addr2 + vec2->bv_len - 1) | mask))