* [PATCH v3 0/2] Align mmap address for DAX pmd mappings @ 2016-04-14 16:48 Toshi Kani 2016-04-14 16:48 ` [PATCH v3 1/2] dax: add dax_get_unmapped_area for " Toshi Kani 2016-04-14 16:48 ` [PATCH v3 2/2] ext2/4, xfs, blk: call dax_get_unmapped_area() for DAX " Toshi Kani 0 siblings, 2 replies; 5+ messages in thread From: Toshi Kani @ 2016-04-14 16:48 UTC (permalink / raw) To: akpm, dan.j.williams, viro Cc: tytso, linux-nvdimm, jack, david, linux-kernel, linux-mm, adilger.kernel, linux-fsdevel, kirill.shutemov When CONFIG_FS_DAX_PMD is set, DAX supports mmap() using pmd page size. This feature relies on both mmap virtual address and FS block (i.e. physical address) to be aligned by the pmd page size. Users can use mkfs options to specify FS to align block allocations. However, aligning mmap address requires code changes to existing applications for providing a pmd-aligned address to mmap(). For instance, fio with "ioengine=mmap" performs I/Os with mmap() [1]. It calls mmap() with a NULL address, which needs to be changed to provide a pmd-aligned address for testing with DAX pmd mappings. Changing all applications that call mmap() with NULL is undesirable. This patch-set extends filesystems to align an mmap address for a DAX file so that unmodified applications can use DAX pmd mappings. [1]: https://github.com/axboe/fio/blob/master/engines/mmap.c v3: - Check overflow condition to offset + length. (Matthew Wilcox) - Remove indent by using gotos. (Matthew Wilcox) - Define dax_get_unmapped_area to NULL when CONFIG_FS_DAX is unset. (Matthew Wilcox) - Squash all filesystem patches together. (Matthew Wilcox) v2: - Change filesystems to provide their get_unmapped_area(). (Matthew Wilcox) - Add more description about the benefit. (Matthew Wilcox) --- Toshi Kani (2): 1/2 dax: add dax_get_unmapped_area for pmd mappings 2/2 ext2/4, xfs, blk: call dax_get_unmapped_area() for DAX pmd mappings --- fs/block_dev.c | 1 + fs/dax.c | 43 +++++++++++++++++++++++++++++++++++++++++++ fs/ext2/file.c | 1 + fs/ext4/file.c | 1 + fs/xfs/xfs_file.c | 1 + include/linux/dax.h | 3 +++ 6 files changed, 50 insertions(+) _______________________________________________ Linux-nvdimm mailing list Linux-nvdimm@lists.01.org https://lists.01.org/mailman/listinfo/linux-nvdimm ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 1/2] dax: add dax_get_unmapped_area for pmd mappings 2016-04-14 16:48 [PATCH v3 0/2] Align mmap address for DAX pmd mappings Toshi Kani @ 2016-04-14 16:48 ` Toshi Kani 2016-04-18 20:47 ` Jan Kara 2016-04-14 16:48 ` [PATCH v3 2/2] ext2/4, xfs, blk: call dax_get_unmapped_area() for DAX " Toshi Kani 1 sibling, 1 reply; 5+ messages in thread From: Toshi Kani @ 2016-04-14 16:48 UTC (permalink / raw) To: akpm, dan.j.williams, viro Cc: tytso, linux-nvdimm, jack, david, linux-kernel, linux-mm, adilger.kernel, linux-fsdevel, kirill.shutemov When CONFIG_FS_DAX_PMD is set, DAX supports mmap() using pmd page size. This feature relies on both mmap virtual address and FS block (i.e. physical address) to be aligned by the pmd page size. Users can use mkfs options to specify FS to align block allocations. However, aligning mmap address requires code changes to existing applications for providing a pmd-aligned address to mmap(). For instance, fio with "ioengine=mmap" performs I/Os with mmap() [1]. It calls mmap() with a NULL address, which needs to be changed to provide a pmd-aligned address for testing with DAX pmd mappings. Changing all applications that call mmap() with NULL is undesirable. Add dax_get_unmapped_area(), which can be called by filesystem's get_unmapped_area to align an mmap address by the pmd size for a DAX file. It calls the default handler, mm->get_unmapped_area(), to find a range and then aligns it for a DAX file. [1]: https://github.com/axboe/fio/blob/master/engines/mmap.c Signed-off-by: Toshi Kani <toshi.kani@hpe.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Alexander Viro <viro@zeniv.linux.org.uk> Cc: Dan Williams <dan.j.williams@intel.com> Cc: Matthew Wilcox <willy@linux.intel.com> Cc: Ross Zwisler <ross.zwisler@linux.intel.com> Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: Dave Chinner <david@fromorbit.com> Cc: Jan Kara <jack@suse.cz> Cc: Theodore Ts'o <tytso@mit.edu> Cc: Andreas Dilger <adilger.kernel@dilger.ca> --- fs/dax.c | 43 +++++++++++++++++++++++++++++++++++++++++++ include/linux/dax.h | 3 +++ 2 files changed, 46 insertions(+) diff --git a/fs/dax.c b/fs/dax.c index 75ba46d..f8ddd27 100644 --- a/fs/dax.c +++ b/fs/dax.c @@ -1158,3 +1158,46 @@ int dax_truncate_page(struct inode *inode, loff_t from, get_block_t get_block) return dax_zero_page_range(inode, from, length, get_block); } EXPORT_SYMBOL_GPL(dax_truncate_page); + +/** + * dax_get_unmapped_area - handle get_unmapped_area for a DAX file + * @filp: The file being mmap'd, if not NULL + * @addr: The mmap address. If NULL, the kernel assigns the address + * @len: The mmap size in bytes + * @pgoff: The page offset in the file where the mapping starts from. + * @flags: The mmap flags + * + * This function can be called by a filesystem for get_unmapped_area(). + * When a target file is a DAX file, it aligns the mmap address at the + * beginning of the file by the pmd size. + */ +unsigned long dax_get_unmapped_area(struct file *filp, unsigned long addr, + unsigned long len, unsigned long pgoff, unsigned long flags) +{ + unsigned long off, off_end, off_pmd, len_pmd, addr_pmd; + + if (!IS_ENABLED(CONFIG_FS_DAX_PMD) || + !filp || addr || !IS_DAX(filp->f_mapping->host)) + goto out; + + off = pgoff << PAGE_SHIFT; + off_end = off + len; + off_pmd = round_up(off, PMD_SIZE); /* pmd-aligned offset */ + + if ((off_end <= off_pmd) || ((off_end - off_pmd) < PMD_SIZE)) + goto out; + + len_pmd = len + PMD_SIZE; + if ((off + len_pmd) < off) + goto out; + + addr_pmd = current->mm->get_unmapped_area(filp, addr, len_pmd, + pgoff, flags); + if (!IS_ERR_VALUE(addr_pmd)) { + addr_pmd += (off - addr_pmd) & (PMD_SIZE - 1); + return addr_pmd; + } +out: + return current->mm->get_unmapped_area(filp, addr, len, pgoff, flags); +} +EXPORT_SYMBOL_GPL(dax_get_unmapped_area); diff --git a/include/linux/dax.h b/include/linux/dax.h index 636dd59..184b171 100644 --- a/include/linux/dax.h +++ b/include/linux/dax.h @@ -17,12 +17,15 @@ int __dax_fault(struct vm_area_struct *, struct vm_fault *, get_block_t, #ifdef CONFIG_FS_DAX struct page *read_dax_sector(struct block_device *bdev, sector_t n); +unsigned long dax_get_unmapped_area(struct file *filp, unsigned long addr, + unsigned long len, unsigned long pgoff, unsigned long flags); #else static inline struct page *read_dax_sector(struct block_device *bdev, sector_t n) { return ERR_PTR(-ENXIO); } +#define dax_get_unmapped_area NULL #endif #ifdef CONFIG_TRANSPARENT_HUGEPAGE _______________________________________________ Linux-nvdimm mailing list Linux-nvdimm@lists.01.org https://lists.01.org/mailman/listinfo/linux-nvdimm ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v3 1/2] dax: add dax_get_unmapped_area for pmd mappings 2016-04-14 16:48 ` [PATCH v3 1/2] dax: add dax_get_unmapped_area for " Toshi Kani @ 2016-04-18 20:47 ` Jan Kara 2016-04-19 2:36 ` Toshi Kani 0 siblings, 1 reply; 5+ messages in thread From: Jan Kara @ 2016-04-18 20:47 UTC (permalink / raw) To: Toshi Kani Cc: tytso, jack, linux-nvdimm, david, linux-kernel, linux-mm, adilger.kernel, viro, linux-fsdevel, akpm, kirill.shutemov On Thu 14-04-16 10:48:30, Toshi Kani wrote: > + > +/** > + * dax_get_unmapped_area - handle get_unmapped_area for a DAX file > + * @filp: The file being mmap'd, if not NULL > + * @addr: The mmap address. If NULL, the kernel assigns the address > + * @len: The mmap size in bytes > + * @pgoff: The page offset in the file where the mapping starts from. > + * @flags: The mmap flags > + * > + * This function can be called by a filesystem for get_unmapped_area(). > + * When a target file is a DAX file, it aligns the mmap address at the > + * beginning of the file by the pmd size. > + */ > +unsigned long dax_get_unmapped_area(struct file *filp, unsigned long addr, > + unsigned long len, unsigned long pgoff, unsigned long flags) > +{ > + unsigned long off, off_end, off_pmd, len_pmd, addr_pmd; I think we need to use 'loff_t' for the offsets for things to work on 32-bits. > + if (!IS_ENABLED(CONFIG_FS_DAX_PMD) || > + !filp || addr || !IS_DAX(filp->f_mapping->host)) > + goto out; > + > + off = pgoff << PAGE_SHIFT; And here we need to type to loff_t before the shift... > + off_end = off + len; > + off_pmd = round_up(off, PMD_SIZE); /* pmd-aligned offset */ > + > + if ((off_end <= off_pmd) || ((off_end - off_pmd) < PMD_SIZE)) None of these parenthesis is actually needed (and IMHO they make the code less readable, not more). > + goto out; > + > + len_pmd = len + PMD_SIZE; > + if ((off + len_pmd) < off) > + goto out; > + > + addr_pmd = current->mm->get_unmapped_area(filp, addr, len_pmd, > + pgoff, flags); > + if (!IS_ERR_VALUE(addr_pmd)) { > + addr_pmd += (off - addr_pmd) & (PMD_SIZE - 1); > + return addr_pmd; Otherwise the patch looks good to me. Honza -- Jan Kara <jack@suse.com> SUSE Labs, CR _______________________________________________ Linux-nvdimm mailing list Linux-nvdimm@lists.01.org https://lists.01.org/mailman/listinfo/linux-nvdimm ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v3 1/2] dax: add dax_get_unmapped_area for pmd mappings 2016-04-18 20:47 ` Jan Kara @ 2016-04-19 2:36 ` Toshi Kani 0 siblings, 0 replies; 5+ messages in thread From: Toshi Kani @ 2016-04-19 2:36 UTC (permalink / raw) To: Jan Kara Cc: tytso@mit.edu, linux-nvdimm@lists.01.org, david@fromorbit.com, linux-kernel@vger.kernel.org, linux-mm@kvack.org, adilger.kernel@dilger.ca, viro@zeniv.linux.org.uk, linux-fsdevel@vger.kernel.org, akpm@linux-foundation.org, kirill.shutemov@linux.intel.com On 4/18/2016 4:47 PM, Jan Kara wrote: > On Thu 14-04-16 10:48:30, Toshi Kani wrote: >> + >> +/** >> + * dax_get_unmapped_area - handle get_unmapped_area for a DAX file >> + * @filp: The file being mmap'd, if not NULL >> + * @addr: The mmap address. If NULL, the kernel assigns the address >> + * @len: The mmap size in bytes >> + * @pgoff: The page offset in the file where the mapping starts from. >> + * @flags: The mmap flags >> + * >> + * This function can be called by a filesystem for get_unmapped_area(). >> + * When a target file is a DAX file, it aligns the mmap address at the >> + * beginning of the file by the pmd size. >> + */ >> +unsigned long dax_get_unmapped_area(struct file *filp, unsigned long addr, >> + unsigned long len, unsigned long pgoff, unsigned long flags) >> +{ >> + unsigned long off, off_end, off_pmd, len_pmd, addr_pmd; > I think we need to use 'loff_t' for the offsets for things to work on > 32-bits. Agreed. Will change to loff_t. >> + if (!IS_ENABLED(CONFIG_FS_DAX_PMD) || >> + !filp || addr || !IS_DAX(filp->f_mapping->host)) >> + goto out; >> + >> + off = pgoff << PAGE_SHIFT; > And here we need to type to loff_t before the shift... Right. >> + off_end = off + len; >> + off_pmd = round_up(off, PMD_SIZE); /* pmd-aligned offset */ >> + >> + if ((off_end <= off_pmd) || ((off_end - off_pmd) < PMD_SIZE)) > None of these parenthesis is actually needed (and IMHO they make the code > less readable, not more). OK. Will remove the parenthesis. >> + goto out; >> + >> + len_pmd = len + PMD_SIZE; >> + if ((off + len_pmd) < off) >> + goto out; >> + >> + addr_pmd = current->mm->get_unmapped_area(filp, addr, len_pmd, >> + pgoff, flags); >> + if (!IS_ERR_VALUE(addr_pmd)) { >> + addr_pmd += (off - addr_pmd) & (PMD_SIZE - 1); >> + return addr_pmd; > Otherwise the patch looks good to me. Great. Thanks Jan! -Toshi _______________________________________________ Linux-nvdimm mailing list Linux-nvdimm@lists.01.org https://lists.01.org/mailman/listinfo/linux-nvdimm ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 2/2] ext2/4, xfs, blk: call dax_get_unmapped_area() for DAX pmd mappings 2016-04-14 16:48 [PATCH v3 0/2] Align mmap address for DAX pmd mappings Toshi Kani 2016-04-14 16:48 ` [PATCH v3 1/2] dax: add dax_get_unmapped_area for " Toshi Kani @ 2016-04-14 16:48 ` Toshi Kani 1 sibling, 0 replies; 5+ messages in thread From: Toshi Kani @ 2016-04-14 16:48 UTC (permalink / raw) To: akpm, dan.j.williams, viro Cc: tytso, linux-nvdimm, jack, david, linux-kernel, linux-mm, adilger.kernel, linux-fsdevel, kirill.shutemov To support DAX pmd mappings with unmodified applications, filesystems need to align an mmap address by the pmd size. Call dax_get_unmapped_area() from f_op->get_unmapped_area. Note, there is no change in behavior for a non-DAX file. Signed-off-by: Toshi Kani <toshi.kani@hpe.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Alexander Viro <viro@zeniv.linux.org.uk> Cc: Dan Williams <dan.j.williams@intel.com> Cc: Matthew Wilcox <willy@linux.intel.com> Cc: Ross Zwisler <ross.zwisler@linux.intel.com> Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: Dave Chinner <david@fromorbit.com> Cc: Jan Kara <jack@suse.cz> Cc: Theodore Ts'o <tytso@mit.edu> Cc: Andreas Dilger <adilger.kernel@dilger.ca> --- fs/block_dev.c | 1 + fs/ext2/file.c | 1 + fs/ext4/file.c | 1 + fs/xfs/xfs_file.c | 1 + 4 files changed, 4 insertions(+) diff --git a/fs/block_dev.c b/fs/block_dev.c index 20a2c02..52518e0 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -1798,6 +1798,7 @@ const struct file_operations def_blk_fops = { .write_iter = blkdev_write_iter, .mmap = blkdev_mmap, .fsync = blkdev_fsync, + .get_unmapped_area = dax_get_unmapped_area, .unlocked_ioctl = block_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = compat_blkdev_ioctl, diff --git a/fs/ext2/file.c b/fs/ext2/file.c index c1400b1..dbf11eb 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -172,6 +172,7 @@ const struct file_operations ext2_file_operations = { .open = dquot_file_open, .release = ext2_release_file, .fsync = ext2_fsync, + .get_unmapped_area = dax_get_unmapped_area, .splice_read = generic_file_splice_read, .splice_write = iter_file_splice_write, }; diff --git a/fs/ext4/file.c b/fs/ext4/file.c index fa2208b..6c268f8 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -708,6 +708,7 @@ const struct file_operations ext4_file_operations = { .open = ext4_file_open, .release = ext4_release_file, .fsync = ext4_sync_file, + .get_unmapped_area = dax_get_unmapped_area, .splice_read = generic_file_splice_read, .splice_write = iter_file_splice_write, .fallocate = ext4_fallocate, diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 569938a..1e409a6 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -1708,6 +1708,7 @@ const struct file_operations xfs_file_operations = { .open = xfs_file_open, .release = xfs_file_release, .fsync = xfs_file_fsync, + .get_unmapped_area = dax_get_unmapped_area, .fallocate = xfs_file_fallocate, }; _______________________________________________ Linux-nvdimm mailing list Linux-nvdimm@lists.01.org https://lists.01.org/mailman/listinfo/linux-nvdimm ^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2016-04-19 2:36 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-04-14 16:48 [PATCH v3 0/2] Align mmap address for DAX pmd mappings Toshi Kani 2016-04-14 16:48 ` [PATCH v3 1/2] dax: add dax_get_unmapped_area for " Toshi Kani 2016-04-18 20:47 ` Jan Kara 2016-04-19 2:36 ` Toshi Kani 2016-04-14 16:48 ` [PATCH v3 2/2] ext2/4, xfs, blk: call dax_get_unmapped_area() for DAX " Toshi Kani
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox