[PATCHv2 2/7] file: add ops to dma map bvec
Keith Busch
kbusch at fb.com
Tue Aug 2 12:36:28 PDT 2022
From: Keith Busch <kbusch at kernel.org>
The same buffer may be used for many subsequent IO's. Instead of setting
up the mapping per-IO, provide an interface that can allow a buffer to
be premapped just once and referenced again later, and implement for the
block device file.
Signed-off-by: Keith Busch <kbusch at kernel.org>
---
block/fops.c | 20 ++++++++++++++++++++
fs/file.c | 15 +++++++++++++++
include/linux/fs.h | 20 ++++++++++++++++++++
3 files changed, 55 insertions(+)
diff --git a/block/fops.c b/block/fops.c
index 29066ac5a2fa..db2d1e848f4b 100644
--- a/block/fops.c
+++ b/block/fops.c
@@ -670,6 +670,22 @@ static long blkdev_fallocate(struct file *file, int mode, loff_t start,
return error;
}
+#ifdef CONFIG_HAS_DMA
+void *blkdev_dma_map(struct file *filp, struct bio_vec *bvec, int nr_vecs)
+{
+ struct block_device *bdev = filp->private_data;
+
+ return block_dma_map(bdev, bvec, nr_vecs);
+}
+
+void blkdev_dma_unmap(struct file *filp, void *dma_tag)
+{
+ struct block_device *bdev = filp->private_data;
+
+ return block_dma_unmap(bdev, dma_tag);
+}
+#endif
+
const struct file_operations def_blk_fops = {
.open = blkdev_open,
.release = blkdev_close,
@@ -686,6 +702,10 @@ const struct file_operations def_blk_fops = {
.splice_read = generic_file_splice_read,
.splice_write = iter_file_splice_write,
.fallocate = blkdev_fallocate,
+#ifdef CONFIG_HAS_DMA
+ .dma_map = blkdev_dma_map,
+ .dma_unmap = blkdev_dma_unmap,
+#endif
};
static __init int blkdev_init(void)
diff --git a/fs/file.c b/fs/file.c
index 3bcc1ecc314a..767bf9d3205e 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -1307,3 +1307,18 @@ int iterate_fd(struct files_struct *files, unsigned n,
return res;
}
EXPORT_SYMBOL(iterate_fd);
+
+#ifdef CONFIG_HAS_DMA
+void *file_dma_map(struct file *file, struct bio_vec *bvec, int nr_vecs)
+{
+ if (file->f_op->dma_map)
+ return file->f_op->dma_map(file, bvec, nr_vecs);
+ return ERR_PTR(-EINVAL);
+}
+
+void file_dma_unmap(struct file *file, void *dma_tag)
+{
+ if (file->f_op->dma_unmap)
+ return file->f_op->dma_unmap(file, dma_tag);
+}
+#endif
diff --git a/include/linux/fs.h b/include/linux/fs.h
index c0d99b5a166b..befd8ea5821a 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1964,6 +1964,10 @@ struct dir_context {
struct iov_iter;
struct io_uring_cmd;
+#ifdef CONFIG_HAS_DMA
+struct bio_vec;
+#endif
+
struct file_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
@@ -2006,6 +2010,10 @@ struct file_operations {
loff_t len, unsigned int remap_flags);
int (*fadvise)(struct file *, loff_t, loff_t, int);
int (*uring_cmd)(struct io_uring_cmd *ioucmd, unsigned int issue_flags);
+#ifdef CONFIG_HAS_DMA
+ void *(*dma_map)(struct file *, struct bio_vec *, int);
+ void (*dma_unmap)(struct file *, void *);
+#endif
} __randomize_layout;
struct inode_operations {
@@ -3467,4 +3475,16 @@ extern int vfs_fadvise(struct file *file, loff_t offset, loff_t len,
extern int generic_fadvise(struct file *file, loff_t offset, loff_t len,
int advice);
+#ifdef CONFIG_HAS_DMA
+void *file_dma_map(struct file *file, struct bio_vec *bvec, int nr_vecs);
+void file_dma_unmap(struct file *file, void *dma_tag);
+#else
+static inline void *file_dma_map(struct file *file, struct bio_vec *bvec,
+ int nr_vecs)
+{
+ return ERR_PTR(-ENOTSUPP);
+}
+static inline void file_dma_unmap(struct file *file, void *dma_tag) {}
+#endif
+
#endif /* _LINUX_FS_H */
--
2.30.2
More information about the Linux-nvme
mailing list