aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Busch <kbusch@kernel.org>2025-09-03 12:33:16 -0700
committerJens Axboe <axboe@kernel.dk>2025-09-09 10:33:27 -0600
commit05ceea5d3ec9a1b1d6858ffd4739fdb0ed1b8eaf (patch)
treefd373c112db75e22a7b18595c777725444c7966c
parentiov_iter: remove iov_iter_is_aligned (diff)
downloadlinux-05ceea5d3ec9a1b1d6858ffd4739fdb0ed1b8eaf.tar.gz
linux-05ceea5d3ec9a1b1d6858ffd4739fdb0ed1b8eaf.zip
blk-integrity: enable p2p source and destination
Set the extraction flags to allow p2p pages for the metadata buffer if the block device allows it. Similar to data payloads, ensure the bio does not use merging if we see a p2p page. Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Keith Busch <kbusch@kernel.org> Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--block/bio-integrity.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/block/bio-integrity.c b/block/bio-integrity.c
index 6d069a49b4aa..bed26f1ec869 100644
--- a/block/bio-integrity.c
+++ b/block/bio-integrity.c
@@ -230,7 +230,8 @@ static int bio_integrity_init_user(struct bio *bio, struct bio_vec *bvec,
}
static unsigned int bvec_from_pages(struct bio_vec *bvec, struct page **pages,
- int nr_vecs, ssize_t bytes, ssize_t offset)
+ int nr_vecs, ssize_t bytes, ssize_t offset,
+ bool *is_p2p)
{
unsigned int nr_bvecs = 0;
int i, j;
@@ -251,6 +252,9 @@ static unsigned int bvec_from_pages(struct bio_vec *bvec, struct page **pages,
bytes -= next;
}
+ if (is_pci_p2pdma_page(pages[i]))
+ *is_p2p = true;
+
bvec_set_page(&bvec[nr_bvecs], pages[i], size, offset);
offset = 0;
nr_bvecs++;
@@ -264,10 +268,11 @@ int bio_integrity_map_user(struct bio *bio, struct iov_iter *iter)
struct request_queue *q = bdev_get_queue(bio->bi_bdev);
struct page *stack_pages[UIO_FASTIOV], **pages = stack_pages;
struct bio_vec stack_vec[UIO_FASTIOV], *bvec = stack_vec;
+ iov_iter_extraction_t extraction_flags = 0;
size_t offset, bytes = iter->count;
+ bool copy, is_p2p = false;
unsigned int nr_bvecs;
int ret, nr_vecs;
- bool copy;
if (bio_integrity(bio))
return -EINVAL;
@@ -286,15 +291,23 @@ int bio_integrity_map_user(struct bio *bio, struct iov_iter *iter)
copy = iov_iter_alignment(iter) &
blk_lim_dma_alignment_and_pad(&q->limits);
- ret = iov_iter_extract_pages(iter, &pages, bytes, nr_vecs, 0, &offset);
+
+ if (blk_queue_pci_p2pdma(q))
+ extraction_flags |= ITER_ALLOW_P2PDMA;
+
+ ret = iov_iter_extract_pages(iter, &pages, bytes, nr_vecs,
+ extraction_flags, &offset);
if (unlikely(ret < 0))
goto free_bvec;
- nr_bvecs = bvec_from_pages(bvec, pages, nr_vecs, bytes, offset);
+ nr_bvecs = bvec_from_pages(bvec, pages, nr_vecs, bytes, offset,
+ &is_p2p);
if (pages != stack_pages)
kvfree(pages);
if (nr_bvecs > queue_max_integrity_segments(q))
copy = true;
+ if (is_p2p)
+ bio->bi_opf |= REQ_NOMERGE;
if (copy)
ret = bio_integrity_copy_user(bio, bvec, nr_bvecs, bytes);