[PATCH 3/8] block: convert bio kmap helpers to use blk_kmap helpers

From: Tejun Heo
Date: Fri Jan 13 2006 - 10:24:55 EST


Convert __bio_kmap_atomic, bvec_kmap_irq, __bio_kmap_irq, bio_kmap_irq
and their unmap counterparts such that they take @dir argument and use
blk_kmap helpers instead of directly calling kmap/unmap. This patch
also converts all users accordingly.

Signed-off-by: Tejun Heo <htejun@xxxxxxxxx>

---

drivers/ide/ide-floppy.c | 8 +++---
drivers/md/raid5.c | 9 +++++--
drivers/md/raid6main.c | 9 +++++--
drivers/scsi/scsi_lib.c | 5 ++--
fs/bio.c | 5 ++--
include/linux/bio.h | 59 --------------------------------------------
include/linux/blkdev.h | 61 ++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 84 insertions(+), 72 deletions(-)

b35899fcc1babe0d74c9eb6d05beddb5992f4a60
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 5945f55..af39130 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -615,9 +615,9 @@ static void idefloppy_input_buffers (ide

count = min(bvec->bv_len, bcount);

- data = bvec_kmap_irq(bvec, &flags);
+ data = bvec_kmap_irq(bvec, &flags, DMA_FROM_DEVICE);
drive->hwif->atapi_input_bytes(drive, data, count);
- bvec_kunmap_irq(data, &flags);
+ bvec_kunmap_irq(data, &flags, DMA_FROM_DEVICE);

bcount -= count;
pc->b_count += count;
@@ -649,9 +649,9 @@ static void idefloppy_output_buffers (id

count = min(bvec->bv_len, bcount);

- data = bvec_kmap_irq(bvec, &flags);
+ data = bvec_kmap_irq(bvec, &flags, DMA_TO_DEVICE);
drive->hwif->atapi_output_bytes(drive, data, count);
- bvec_kunmap_irq(data, &flags);
+ bvec_kunmap_irq(data, &flags, DMA_TO_DEVICE);

bcount -= count;
pc->b_count += count;
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 54f4a98..db1fcd2 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -689,12 +689,17 @@ static void copy_data(int frombio, struc
else clen = len;

if (clen > 0) {
- char *ba = __bio_kmap_atomic(bio, i, KM_USER0);
+ enum dma_data_direction dir;
+ char *ba;
+
+ dir = frombio ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+ ba = __bio_kmap_atomic(bio, i, KM_USER0, dir);
+
if (frombio)
memcpy(pa+page_offset, ba+b_offset, clen);
else
memcpy(ba+b_offset, pa+page_offset, clen);
- __bio_kunmap_atomic(ba, KM_USER0);
+ __bio_kunmap_atomic(ba, KM_USER0, dir);
}
if (clen < len) /* hit end of page */
break;
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c
index 8c823d6..f320291 100644
--- a/drivers/md/raid6main.c
+++ b/drivers/md/raid6main.c
@@ -720,12 +720,17 @@ static void copy_data(int frombio, struc
else clen = len;

if (clen > 0) {
- char *ba = __bio_kmap_atomic(bio, i, KM_USER0);
+ enum dma_data_direction dir;
+ char *ba;
+
+ dir = frombio ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+ ba = __bio_kmap_atomic(bio, i, KM_USER0, dir);
+
if (frombio)
memcpy(pa+page_offset, ba+b_offset, clen);
else
memcpy(ba+b_offset, pa+page_offset, clen);
- __bio_kunmap_atomic(ba, KM_USER0);
+ __bio_kunmap_atomic(ba, KM_USER0, dir);
}
if (clen < len) /* hit end of page */
break;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 00c9bf3..73285eb 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -942,9 +942,10 @@ void scsi_io_completion(struct scsi_cmnd
else if (cmd->buffer != req->buffer) {
if (rq_data_dir(req) == READ) {
unsigned long flags;
- char *to = bio_kmap_irq(req->bio, &flags);
+ char *to = bio_kmap_irq(req->bio, &flags,
+ DMA_FROM_DEVICE);
memcpy(to, cmd->buffer, cmd->bufflen);
- bio_kunmap_irq(to, &flags);
+ bio_kunmap_irq(to, &flags, DMA_FROM_DEVICE);
}
kfree(cmd->buffer);
}
diff --git a/fs/bio.c b/fs/bio.c
index 7b30695..c7b5442 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -199,10 +199,9 @@ void zero_fill_bio(struct bio *bio)
int i;

bio_for_each_segment(bv, bio, i) {
- char *data = bvec_kmap_irq(bv, &flags);
+ char *data = bvec_kmap_irq(bv, &flags, DMA_FROM_DEVICE);
memset(data, 0, bv->bv_len);
- flush_dcache_page(bv->bv_page);
- bvec_kunmap_irq(data, &flags);
+ bvec_kunmap_irq(data, &flags, DMA_FROM_DEVICE);
}
}
EXPORT_SYMBOL(zero_fill_bio);
diff --git a/include/linux/bio.h b/include/linux/bio.h
index b60ffe3..8c80a14 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -186,18 +186,6 @@ struct bio {
#define bvec_to_phys(bv) (page_to_phys((bv)->bv_page) + (unsigned long) (bv)->bv_offset)

/*
- * queues that have highmem support enabled may still need to revert to
- * PIO transfers occasionally and thus map high pages temporarily. For
- * permanent PIO fall back, user is probably better off disabling highmem
- * I/O completely on that queue (see ide-dma for example)
- */
-#define __bio_kmap_atomic(bio, idx, kmtype) \
- (kmap_atomic(bio_iovec_idx((bio), (idx))->bv_page, kmtype) + \
- bio_iovec_idx((bio), (idx))->bv_offset)
-
-#define __bio_kunmap_atomic(addr, kmtype) kunmap_atomic(addr, kmtype)
-
-/*
* merge helpers etc
*/

@@ -310,51 +298,4 @@ extern struct bio *bio_copy_user(struct
extern int bio_uncopy_user(struct bio *);
void zero_fill_bio(struct bio *bio);

-#ifdef CONFIG_HIGHMEM
-/*
- * remember to add offset! and never ever reenable interrupts between a
- * bvec_kmap_irq and bvec_kunmap_irq!!
- *
- * This function MUST be inlined - it plays with the CPU interrupt flags.
- */
-static inline char *bvec_kmap_irq(struct bio_vec *bvec, unsigned long *flags)
-{
- unsigned long addr;
-
- /*
- * might not be a highmem page, but the preempt/irq count
- * balancing is a lot nicer this way
- */
- local_irq_save(*flags);
- addr = (unsigned long) kmap_atomic(bvec->bv_page, KM_BIO_SRC_IRQ);
-
- BUG_ON(addr & ~PAGE_MASK);
-
- return (char *) addr + bvec->bv_offset;
-}
-
-static inline void bvec_kunmap_irq(char *buffer, unsigned long *flags)
-{
- unsigned long ptr = (unsigned long) buffer & PAGE_MASK;
-
- kunmap_atomic((void *) ptr, KM_BIO_SRC_IRQ);
- local_irq_restore(*flags);
-}
-
-#else
-#define bvec_kmap_irq(bvec, flags) (page_address((bvec)->bv_page) + (bvec)->bv_offset)
-#define bvec_kunmap_irq(buf, flags) do { *(flags) = 0; } while (0)
-#endif
-
-static inline char *__bio_kmap_irq(struct bio *bio, unsigned short idx,
- unsigned long *flags)
-{
- return bvec_kmap_irq(bio_iovec_idx(bio, idx), flags);
-}
-#define __bio_kunmap_irq(buf, flags) bvec_kunmap_irq(buf, flags)
-
-#define bio_kmap_irq(bio, flags) \
- __bio_kmap_irq((bio), (bio)->bi_idx, (flags))
-#define bio_kunmap_irq(buf,flags) __bio_kunmap_irq(buf, flags)
-
#endif /* __LINUX_BIO_H */
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 1040029..ed432cf 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -850,6 +850,67 @@ static inline void blk_kunmap(struct pag
kunmap(page);
}

+static inline void * __bio_kmap_atomic(struct bio *bio, unsigned short idx,
+ enum km_type type,
+ enum dma_data_direction dir)
+{
+ struct bio_vec *bvec = bio_iovec_idx(bio, idx);
+ return blk_kmap_atomic(bvec->bv_page, type, dir) + bvec->bv_offset;
+}
+
+static inline void __bio_kunmap_atomic(void *addr, enum km_type type,
+ enum dma_data_direction dir)
+{
+ addr = (void *)((unsigned long)addr & PAGE_MASK);
+ return blk_kunmap_atomic(addr, type, dir);
+}
+
+/*
+ * Never ever reenable interrupts between a bvec_kmap_irq and
+ * bvec_kunmap_irq!! This function MUST be inlined - it plays with
+ * the CPU interrupt flags.
+ */
+static inline char * bvec_kmap_irq(struct bio_vec *bvec, unsigned long *flags,
+ enum dma_data_direction dir)
+{
+ char *addr;
+
+ /*
+ * might not be a highmem page, but the preempt/irq count
+ * balancing is a lot nicer this way
+ */
+#ifdef CONFIG_HIGHMEM
+ local_irq_save(*flags);
+#endif
+ addr = blk_kmap_atomic(bvec->bv_page, KM_BIO_SRC_IRQ, dir);
+
+ BUG_ON(((unsigned long)addr) & ~PAGE_MASK);
+
+ return addr + bvec->bv_offset;
+}
+
+static inline void bvec_kunmap_irq(char *addr, unsigned long *flags,
+ enum dma_data_direction dir)
+{
+ addr = (char *)((unsigned long)addr & PAGE_MASK);
+ blk_kunmap_atomic(addr, KM_BIO_SRC_IRQ, dir);
+#ifdef CONFIG_HIGHMEM
+ local_irq_restore(*flags);
+#endif
+}
+
+static inline char *__bio_kmap_irq(struct bio *bio, unsigned short idx,
+ unsigned long *flags,
+ enum dma_data_direction dir)
+{
+ return bvec_kmap_irq(bio_iovec_idx(bio, idx), flags, dir);
+}
+#define __bio_kunmap_irq(buf, flags, dir) bvec_kunmap_irq(buf, flags, dir)
+
+#define bio_kmap_irq(bio, flags, dir) \
+ __bio_kmap_irq((bio), (bio)->bi_idx, (flags), dir)
+#define bio_kunmap_irq(buf,flags, dir) __bio_kunmap_irq(buf, flags, dir)
+
struct work_struct;
int kblockd_schedule_work(struct work_struct *work);
void kblockd_flush(void);
--
1.0.6


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/