diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2008-08-28 02:05:58 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2008-10-09 02:56:11 -0400 |
commit | 879040742cf09f2360a9ac41846288707e4e567c (patch) | |
tree | 7768750efd0d8ef28a183f8cd781b0c878212795 | |
parent | 4d8ab62e087d9300883b82c2662e73e6eef803a3 (diff) |
block: add blk_rq_aligned helper function
This adds blk_rq_aligned helper function to see if alignment and
padding requirement is satisfied for DMA transfer. This also converts
blk_rq_map_kern and __blk_rq_map_user to use the helper function.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Cc: Jens Axboe <jens.axboe@oracle.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-rw-r--r-- | block/blk-map.c | 12 | ||||
-rw-r--r-- | include/linux/blkdev.h | 7 |
2 files changed, 9 insertions, 10 deletions
diff --git a/block/blk-map.c b/block/blk-map.c index dad6a2907835..572140cda5ff 100644 --- a/block/blk-map.c +++ b/block/blk-map.c | |||
@@ -45,7 +45,6 @@ static int __blk_rq_map_user(struct request_queue *q, struct request *rq, | |||
45 | unsigned int len, gfp_t gfp_mask) | 45 | unsigned int len, gfp_t gfp_mask) |
46 | { | 46 | { |
47 | unsigned long uaddr; | 47 | unsigned long uaddr; |
48 | unsigned int alignment; | ||
49 | struct bio *bio, *orig_bio; | 48 | struct bio *bio, *orig_bio; |
50 | int reading, ret; | 49 | int reading, ret; |
51 | 50 | ||
@@ -56,8 +55,7 @@ static int __blk_rq_map_user(struct request_queue *q, struct request *rq, | |||
56 | * direct dma. else, set up kernel bounce buffers | 55 | * direct dma. else, set up kernel bounce buffers |
57 | */ | 56 | */ |
58 | uaddr = (unsigned long) ubuf; | 57 | uaddr = (unsigned long) ubuf; |
59 | alignment = queue_dma_alignment(q) | q->dma_pad_mask; | 58 | if (blk_rq_aligned(q, ubuf, len) && !map_data) |
60 | if (!(uaddr & alignment) && !(len & alignment) && !map_data) | ||
61 | bio = bio_map_user(q, NULL, uaddr, len, reading, gfp_mask); | 59 | bio = bio_map_user(q, NULL, uaddr, len, reading, gfp_mask); |
62 | else | 60 | else |
63 | bio = bio_copy_user(q, map_data, uaddr, len, reading, gfp_mask); | 61 | bio = bio_copy_user(q, map_data, uaddr, len, reading, gfp_mask); |
@@ -274,8 +272,6 @@ EXPORT_SYMBOL(blk_rq_unmap_user); | |||
274 | int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf, | 272 | int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf, |
275 | unsigned int len, gfp_t gfp_mask) | 273 | unsigned int len, gfp_t gfp_mask) |
276 | { | 274 | { |
277 | unsigned long kaddr; | ||
278 | unsigned int alignment; | ||
279 | int reading = rq_data_dir(rq) == READ; | 275 | int reading = rq_data_dir(rq) == READ; |
280 | int do_copy = 0; | 276 | int do_copy = 0; |
281 | struct bio *bio; | 277 | struct bio *bio; |
@@ -285,11 +281,7 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf, | |||
285 | if (!len || !kbuf) | 281 | if (!len || !kbuf) |
286 | return -EINVAL; | 282 | return -EINVAL; |
287 | 283 | ||
288 | kaddr = (unsigned long)kbuf; | 284 | do_copy = !blk_rq_aligned(q, kbuf, len) || object_is_on_stack(kbuf); |
289 | alignment = queue_dma_alignment(q) | q->dma_pad_mask; | ||
290 | do_copy = ((kaddr & alignment) || (len & alignment) || | ||
291 | object_is_on_stack(kbuf)); | ||
292 | |||
293 | if (do_copy) | 285 | if (do_copy) |
294 | bio = bio_copy_kern(q, kbuf, len, gfp_mask, reading); | 286 | bio = bio_copy_kern(q, kbuf, len, gfp_mask, reading); |
295 | else | 287 | else |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 358ac423ed2f..9c2549260427 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -899,6 +899,13 @@ static inline int queue_dma_alignment(struct request_queue *q) | |||
899 | return q ? q->dma_alignment : 511; | 899 | return q ? q->dma_alignment : 511; |
900 | } | 900 | } |
901 | 901 | ||
902 | static inline int blk_rq_aligned(struct request_queue *q, void *addr, | ||
903 | unsigned int len) | ||
904 | { | ||
905 | unsigned int alignment = queue_dma_alignment(q) | q->dma_pad_mask; | ||
906 | return !((unsigned long)addr & alignment) && !(len & alignment); | ||
907 | } | ||
908 | |||
902 | /* assumes size > 256 */ | 909 | /* assumes size > 256 */ |
903 | static inline unsigned int blksize_bits(unsigned int size) | 910 | static inline unsigned int blksize_bits(unsigned int size) |
904 | { | 911 | { |