Skip to content

Commit 7ddf8de

Browse files
keithbuschkawasaki
authored andcommitted
blk-mq-dma: add support for mapping integrity metadata
Provide integrity metadata helpers equivalent to the data payload helpers for iterating a request for dma setup. Signed-off-by: Keith Busch <[email protected]>
1 parent ffb1e9f commit 7ddf8de

3 files changed

Lines changed: 71 additions & 7 deletions

File tree

block/blk-mq-dma.c

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,28 @@
22
/*
33
* Copyright (C) 2025 Christoph Hellwig
44
*/
5+
#include <linux/blk-integrity.h>
56
#include <linux/blk-mq-dma.h>
67
#include "blk.h"
78

9+
static bool __blk_map_iter_next(struct blk_map_iter *iter)
10+
{
11+
if (iter->iter.bi_size)
12+
return true;
13+
if (!iter->bio || !iter->bio->bi_next)
14+
return false;
15+
16+
iter->bio = iter->bio->bi_next;
17+
if (iter->is_integrity) {
18+
iter->iter = iter->bio->bi_integrity->bip_iter;
19+
iter->bvec = iter->bio->bi_integrity->bip_vec;
20+
} else {
21+
iter->iter = iter->bio->bi_iter;
22+
iter->bvec = iter->bio->bi_io_vec;
23+
}
24+
return true;
25+
}
26+
827
static bool blk_map_iter_next(struct request *req, struct blk_map_iter *iter)
928
{
1029
unsigned int max_size;
@@ -27,13 +46,8 @@ static bool blk_map_iter_next(struct request *req, struct blk_map_iter *iter)
2746
while (!iter->iter.bi_size || !iter->iter.bi_bvec_done) {
2847
struct bio_vec next;
2948

30-
if (!iter->iter.bi_size) {
31-
if (!iter->bio || !iter->bio->bi_next)
32-
break;
33-
iter->bio = iter->bio->bi_next;
34-
iter->iter = iter->bio->bi_iter;
35-
iter->bvec = iter->bio->bi_io_vec;
36-
}
49+
if (!__blk_map_iter_next(iter))
50+
break;
3751

3852
next = mp_bvec_iter_bvec(iter->bvec, iter->iter);
3953
if (bv.bv_len + next.bv_len > max_size ||
@@ -232,6 +246,38 @@ bool blk_rq_dma_map_iter_next(struct request *req, struct device *dma_dev,
232246
}
233247
EXPORT_SYMBOL_GPL(blk_rq_dma_map_iter_next);
234248

249+
#ifdef CONFIG_BLK_DEV_INTEGRITY
250+
bool blk_rq_integrity_dma_map_iter_start(struct request *req,
251+
struct device *dma_dev, struct dma_iova_state *state,
252+
struct blk_dma_iter *iter)
253+
{
254+
unsigned len = bio_integrity_bytes(&req->q->limits.integrity,
255+
blk_rq_sectors(req));
256+
struct bio *bio = req->bio;
257+
258+
iter->iter = (struct blk_map_iter) {
259+
.bio = bio,
260+
.iter = bio->bi_integrity->bip_iter,
261+
.bvec = bio->bi_integrity->bip_vec,
262+
.is_integrity = true,
263+
};
264+
return blk_dma_map_iter_start(req, dma_dev, state, iter, len);
265+
}
266+
EXPORT_SYMBOL_GPL(blk_rq_integrity_dma_map_iter_start);
267+
268+
bool blk_rq_integrity_dma_map_iter_next(struct request *req,
269+
struct device *dma_dev, struct blk_dma_iter *iter)
270+
{
271+
if (!blk_map_iter_next(req, &iter->iter))
272+
return false;
273+
274+
if (iter->p2pdma.map == PCI_P2PDMA_MAP_BUS_ADDR)
275+
return blk_dma_map_bus(iter);
276+
return blk_dma_map_direct(req, dma_dev, iter);
277+
}
278+
EXPORT_SYMBOL_GPL(blk_rq_integrity_dma_map_iter_next);
279+
#endif
280+
235281
static inline struct scatterlist *
236282
blk_next_sg(struct scatterlist **sg, struct scatterlist *sglist)
237283
{

include/linux/blk-integrity.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include <linux/blk-mq.h>
66
#include <linux/bio-integrity.h>
7+
#include <linux/blk-mq-dma.h>
78

89
struct request;
910

@@ -31,6 +32,11 @@ int blk_rq_integrity_map_user(struct request *rq, void __user *ubuf,
3132
ssize_t bytes);
3233
int blk_get_meta_cap(struct block_device *bdev, unsigned int cmd,
3334
struct logical_block_metadata_cap __user *argp);
35+
bool blk_rq_integrity_dma_map_iter_start(struct request *req,
36+
struct device *dma_dev, struct dma_iova_state *state,
37+
struct blk_dma_iter *iter);
38+
bool blk_rq_integrity_dma_map_iter_next(struct request *req,
39+
struct device *dma_dev, struct blk_dma_iter *iter);
3440

3541
static inline bool
3642
blk_integrity_queue_supports_integrity(struct request_queue *q)
@@ -115,6 +121,17 @@ static inline int blk_rq_integrity_map_user(struct request *rq,
115121
{
116122
return -EINVAL;
117123
}
124+
static inline bool blk_rq_integrity_dma_map_iter_start(struct request *req,
125+
struct device *dma_dev, struct dma_iova_state *state,
126+
struct blk_dma_iter *iter)
127+
{
128+
return false;
129+
}
130+
static inline bool blk_rq_integrity_dma_map_iter_next(struct request *req,
131+
struct device *dma_dev, struct blk_dma_iter *iter)
132+
{
133+
return false;
134+
}
118135
static inline struct blk_integrity *bdev_get_integrity(struct block_device *b)
119136
{
120137
return NULL;

include/linux/blk-mq-dma.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ struct blk_map_iter {
1111
struct bio_vec *bvec;
1212
struct bvec_iter iter;
1313
struct bio *bio;
14+
bool is_integrity;
1415
};
1516

1617
struct blk_dma_iter {

0 commit comments

Comments
 (0)