diff options
| author | Martin K. Petersen <martin.petersen@oracle.com> | 2010-09-10 14:50:10 -0400 |
|---|---|---|
| committer | Jens Axboe <axboe@carl.home.kernel.dk> | 2010-09-10 14:50:10 -0400 |
| commit | 13f05c8d8e98bbdce89158bfdb2e380940695a88 (patch) | |
| tree | 055215e7e2b1bdc684ead64daa61b30b35eaa3c5 /include/linux | |
| parent | c8bf1336824ebd698d37b71763e1c43190f2229a (diff) | |
block/scsi: Provide a limit on the number of integrity segments
Some controllers have a hardware limit on the number of protection
information scatter-gather list segments they can handle.
Introduce a max_integrity_segments limit in the block layer and provide
a new scsi_host_template setting that allows HBA drivers to provide a
value suitable for the hardware.
Add support for honoring the integrity segment limit when merging both
bios and requests.
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Jens Axboe <axboe@carl.home.kernel.dk>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/bio.h | 4 | ||||
| -rw-r--r-- | include/linux/blkdev.h | 33 |
2 files changed, 33 insertions, 4 deletions
diff --git a/include/linux/bio.h b/include/linux/bio.h index 5274103434a..2c3fd742160 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h | |||
| @@ -496,6 +496,10 @@ static inline struct bio *bio_list_get(struct bio_list *bl) | |||
| 496 | #define bip_for_each_vec(bvl, bip, i) \ | 496 | #define bip_for_each_vec(bvl, bip, i) \ |
| 497 | __bip_for_each_vec(bvl, bip, i, (bip)->bip_idx) | 497 | __bip_for_each_vec(bvl, bip, i, (bip)->bip_idx) |
| 498 | 498 | ||
| 499 | #define bio_for_each_integrity_vec(_bvl, _bio, _iter) \ | ||
| 500 | for_each_bio(_bio) \ | ||
| 501 | bip_for_each_vec(_bvl, _bio->bi_integrity, _iter) | ||
| 502 | |||
| 499 | #define bio_integrity(bio) (bio->bi_integrity != NULL) | 503 | #define bio_integrity(bio) (bio->bi_integrity != NULL) |
| 500 | 504 | ||
| 501 | extern struct bio_integrity_payload *bio_integrity_alloc_bioset(struct bio *, gfp_t, unsigned int, struct bio_set *); | 505 | extern struct bio_integrity_payload *bio_integrity_alloc_bioset(struct bio *, gfp_t, unsigned int, struct bio_set *); |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 2c54906f678..7e661106270 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
| @@ -124,6 +124,9 @@ struct request { | |||
| 124 | * physical address coalescing is performed. | 124 | * physical address coalescing is performed. |
| 125 | */ | 125 | */ |
| 126 | unsigned short nr_phys_segments; | 126 | unsigned short nr_phys_segments; |
| 127 | #if defined(CONFIG_BLK_DEV_INTEGRITY) | ||
| 128 | unsigned short nr_integrity_segments; | ||
| 129 | #endif | ||
| 127 | 130 | ||
| 128 | unsigned short ioprio; | 131 | unsigned short ioprio; |
| 129 | 132 | ||
| @@ -243,6 +246,7 @@ struct queue_limits { | |||
| 243 | 246 | ||
| 244 | unsigned short logical_block_size; | 247 | unsigned short logical_block_size; |
| 245 | unsigned short max_segments; | 248 | unsigned short max_segments; |
| 249 | unsigned short max_integrity_segments; | ||
| 246 | 250 | ||
| 247 | unsigned char misaligned; | 251 | unsigned char misaligned; |
| 248 | unsigned char discard_misaligned; | 252 | unsigned char discard_misaligned; |
| @@ -1213,8 +1217,13 @@ struct blk_integrity { | |||
| 1213 | extern int blk_integrity_register(struct gendisk *, struct blk_integrity *); | 1217 | extern int blk_integrity_register(struct gendisk *, struct blk_integrity *); |
| 1214 | extern void blk_integrity_unregister(struct gendisk *); | 1218 | extern void blk_integrity_unregister(struct gendisk *); |
| 1215 | extern int blk_integrity_compare(struct gendisk *, struct gendisk *); | 1219 | extern int blk_integrity_compare(struct gendisk *, struct gendisk *); |
| 1216 | extern int blk_rq_map_integrity_sg(struct request *, struct scatterlist *); | 1220 | extern int blk_rq_map_integrity_sg(struct request_queue *, struct bio *, |
| 1217 | extern int blk_rq_count_integrity_sg(struct request *); | 1221 | struct scatterlist *); |
| 1222 | extern int blk_rq_count_integrity_sg(struct request_queue *, struct bio *); | ||
| 1223 | extern int blk_integrity_merge_rq(struct request_queue *, struct request *, | ||
| 1224 | struct request *); | ||
| 1225 | extern int blk_integrity_merge_bio(struct request_queue *, struct request *, | ||
| 1226 | struct bio *); | ||
| 1218 | 1227 | ||
| 1219 | static inline | 1228 | static inline |
| 1220 | struct blk_integrity *bdev_get_integrity(struct block_device *bdev) | 1229 | struct blk_integrity *bdev_get_integrity(struct block_device *bdev) |
| @@ -1235,16 +1244,32 @@ static inline int blk_integrity_rq(struct request *rq) | |||
| 1235 | return bio_integrity(rq->bio); | 1244 | return bio_integrity(rq->bio); |
| 1236 | } | 1245 | } |
| 1237 | 1246 | ||
| 1247 | static inline void blk_queue_max_integrity_segments(struct request_queue *q, | ||
| 1248 | unsigned int segs) | ||
| 1249 | { | ||
| 1250 | q->limits.max_integrity_segments = segs; | ||
| 1251 | } | ||
| 1252 | |||
| 1253 | static inline unsigned short | ||
| 1254 | queue_max_integrity_segments(struct request_queue *q) | ||
| 1255 | { | ||
| 1256 | return q->limits.max_integrity_segments; | ||
| 1257 | } | ||
| 1258 | |||
| 1238 | #else /* CONFIG_BLK_DEV_INTEGRITY */ | 1259 | #else /* CONFIG_BLK_DEV_INTEGRITY */ |
| 1239 | 1260 | ||
| 1240 | #define blk_integrity_rq(rq) (0) | 1261 | #define blk_integrity_rq(rq) (0) |
| 1241 | #define blk_rq_count_integrity_sg(a) (0) | 1262 | #define blk_rq_count_integrity_sg(a, b) (0) |
| 1242 | #define blk_rq_map_integrity_sg(a, b) (0) | 1263 | #define blk_rq_map_integrity_sg(a, b, c) (0) |
| 1243 | #define bdev_get_integrity(a) (0) | 1264 | #define bdev_get_integrity(a) (0) |
| 1244 | #define blk_get_integrity(a) (0) | 1265 | #define blk_get_integrity(a) (0) |
| 1245 | #define blk_integrity_compare(a, b) (0) | 1266 | #define blk_integrity_compare(a, b) (0) |
| 1246 | #define blk_integrity_register(a, b) (0) | 1267 | #define blk_integrity_register(a, b) (0) |
| 1247 | #define blk_integrity_unregister(a) do { } while (0); | 1268 | #define blk_integrity_unregister(a) do { } while (0); |
| 1269 | #define blk_queue_max_integrity_segments(a, b) do { } while (0); | ||
| 1270 | #define queue_max_integrity_segments(a) (0) | ||
| 1271 | #define blk_integrity_merge_rq(a, b, c) (0) | ||
| 1272 | #define blk_integrity_merge_bio(a, b, c) (0) | ||
| 1248 | 1273 | ||
| 1249 | #endif /* CONFIG_BLK_DEV_INTEGRITY */ | 1274 | #endif /* CONFIG_BLK_DEV_INTEGRITY */ |
| 1250 | 1275 | ||
