Skip to content

Commit c7c4005

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 6f136e1 commit c7c4005

3 files changed

Lines changed: 69 additions & 7 deletions

File tree

block/blk-mq-dma.c

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
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

@@ -10,6 +11,24 @@ struct phys_vec {
1011
u32 len;
1112
};
1213

14+
static bool blk_dma_iter_next(struct blk_dma_iter *iter)
15+
{
16+
if (iter->iter.bi_size)
17+
return true;
18+
if (!iter->bio->bi_next)
19+
return false;
20+
21+
iter->bio = iter->bio->bi_next;
22+
if (iter->integrity) {
23+
iter->iter = iter->bio->bi_integrity->bip_iter;
24+
iter->bvec = iter->bio->bi_integrity->bip_vec;
25+
} else {
26+
iter->iter = iter->bio->bi_iter;
27+
iter->bvec = iter->bio->bi_io_vec;
28+
}
29+
return true;
30+
}
31+
1332
static bool blk_map_iter_next(struct request *req, struct blk_dma_iter *iter,
1433
struct phys_vec *vec)
1534
{
@@ -36,13 +55,8 @@ static bool blk_map_iter_next(struct request *req, struct blk_dma_iter *iter,
3655
while (!iter->iter.bi_size || !iter->iter.bi_bvec_done) {
3756
struct bio_vec next;
3857

39-
if (!iter->iter.bi_size) {
40-
if (!iter->bio->bi_next)
41-
break;
42-
iter->bio = iter->bio->bi_next;
43-
iter->iter = iter->bio->bi_iter;
44-
iter->bvec = iter->bio->bi_io_vec;
45-
}
58+
if (!blk_dma_iter_next(iter))
59+
break;
4660

4761
next = mp_bvec_iter_bvec(iter->bvec, iter->iter);
4862
if (bv.bv_len + next.bv_len > max_size ||
@@ -185,6 +199,7 @@ bool blk_rq_dma_map_iter_start(struct request *req, struct device *dma_dev,
185199
struct dma_iova_state *state, struct blk_dma_iter *iter)
186200
{
187201
iter->iter = req->bio->bi_iter;
202+
iter->integrity = false;
188203
if (req->rq_flags & RQF_SPECIAL_PAYLOAD)
189204
iter->bvec = &req->special_vec;
190205
else
@@ -227,6 +242,35 @@ bool blk_rq_dma_map_iter_next(struct request *req, struct device *dma_dev,
227242
}
228243
EXPORT_SYMBOL_GPL(blk_rq_dma_map_iter_next);
229244

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

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

@@ -29,6 +30,11 @@ int blk_rq_map_integrity_sg(struct request *, struct scatterlist *);
2930
int blk_rq_count_integrity_sg(struct request_queue *, struct bio *);
3031
int blk_rq_integrity_map_user(struct request *rq, void __user *ubuf,
3132
ssize_t bytes);
33+
bool blk_rq_integrity_dma_map_iter_start(struct request *req,
34+
struct device *dma_dev, struct dma_iova_state *state,
35+
struct blk_dma_iter *iter);
36+
bool blk_rq_integrity_dma_map_iter_next(struct request *req,
37+
struct device *dma_dev, struct blk_dma_iter *iter);
3238

3339
static inline bool
3440
blk_integrity_queue_supports_integrity(struct request_queue *q)
@@ -108,6 +114,17 @@ static inline int blk_rq_integrity_map_user(struct request *rq,
108114
{
109115
return -EINVAL;
110116
}
117+
bool blk_rq_integrity_dma_map_iter_start(struct request *req,
118+
struct device *dma_dev, struct dma_iova_state *state,
119+
struct blk_dma_iter *iter)
120+
{
121+
return false;
122+
}
123+
bool blk_rq_integrity_dma_map_iter_next(struct request *req,
124+
struct device *dma_dev, struct blk_dma_iter *iter)
125+
{
126+
return false;
127+
}
111128
static inline struct blk_integrity *bdev_get_integrity(struct block_device *b)
112129
{
113130
return NULL;

include/linux/blk-mq-dma.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ struct blk_dma_iter {
1818
struct bvec_iter iter;
1919
struct bio *bio;
2020
struct pci_p2pdma_map_state p2pdma;
21+
bool integrity;
2122
};
2223

2324
bool blk_rq_dma_map_iter_start(struct request *req, struct device *dma_dev,

0 commit comments

Comments
 (0)