Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1668122 > unrolled thread
| Started by | Dan Williams <dan.j.williams@intel.com> |
|---|---|
| First post | 2017-06-17 03:30 +0200 |
| Last post | 2017-06-19 04:00 +0200 |
| Articles | 11 — 4 participants |
Back to article view | Back to linux.kernel
[RFC PATCH 0/2] daxfile: enable byte-addressable updates to pmem Dan Williams <dan.j.williams@intel.com> - 2017-06-17 03:30 +0200
[RFC PATCH 2/2] mm, fs: daxfile, an interface for byte-addressable updates to pmem Dan Williams <dan.j.williams@intel.com> - 2017-06-17 03:30 +0200
Re: [RFC PATCH 2/2] mm, fs: daxfile, an interface for byte-addressable updates to pmem Andy Lutomirski <luto@kernel.org> - 2017-06-17 18:30 +0200
Re: [RFC PATCH 2/2] mm, fs: daxfile, an interface for byte-addressable updates to pmem Dan Williams <dan.j.williams@intel.com> - 2017-06-18 00:00 +0200
Re: [RFC PATCH 2/2] mm, fs: daxfile, an interface for byte-addressable updates to pmem Andy Lutomirski <luto@kernel.org> - 2017-06-18 02:00 +0200
Re: [RFC PATCH 2/2] mm, fs: daxfile, an interface for byte-addressable updates to pmem Dan Williams <dan.j.williams@intel.com> - 2017-06-18 05:20 +0200
Re: [RFC PATCH 2/2] mm, fs: daxfile, an interface for byte-addressable updates to pmem Andy Lutomirski <luto@kernel.org> - 2017-06-18 07:10 +0200
Re: [RFC PATCH 2/2] mm, fs: daxfile, an interface for byte-addressable updates to pmem Dave Chinner <david@fromorbit.com> - 2017-06-19 15:30 +0200
Re: [RFC PATCH 2/2] mm, fs: daxfile, an interface for byte-addressable updates to pmem Andy Lutomirski <luto@kernel.org> - 2017-06-19 17:30 +0200
Re: [RFC PATCH 2/2] mm, fs: daxfile, an interface for byte-addressable updates to pmem Christoph Hellwig <hch@lst.de> - 2017-06-18 10:20 +0200
Re: [RFC PATCH 2/2] mm, fs: daxfile, an interface for byte-addressable updates to pmem Dan Williams <dan.j.williams@intel.com> - 2017-06-19 04:00 +0200
| From | Dan Williams <dan.j.williams@intel.com> |
|---|---|
| Date | 2017-06-17 03:30 +0200 |
| Subject | [RFC PATCH 0/2] daxfile: enable byte-addressable updates to pmem |
| Message-ID | <tTaIN-8fC-5@gated-at.bofh.it> |
Quoting PATCH 2/2:
To date, the full promise of byte-addressable access to persistent
memory has only been half realized via the filesystem-dax interface. The
current filesystem-dax mechanism allows an application to consume (read)
data from persistent storage at byte-size granularity, bypassing the
full page reads required by traditional storage devices.
Now, for writes, applications still need to contend with
page-granularity dirtying and flushing semantics as well as filesystem
coordination for metadata updates after any mmap write. The current
situation precludes use cases that leverage byte-granularity / in-place
updates to persistent media.
To get around this limitation there are some specialized applications
that are using the device-dax interface to bypass the overhead and
data-safety problems of the current filesystem-dax mmap-write path.
QEMU-KVM is forced to use device-dax to safely pass through persistent
memory to a guest [1]. Some specialized databases are using device-dax
for byte-granularity writes. Outside of those cases, device-dax is
difficult for general purpose persistent memory applications to consume.
There is demand for access to pmem without needing to contend with
special device configuration and other device-dax limitations.
The 'daxfile' interface satisfies this demand and realizes one of Dave
Chinner's ideas for allowing pmem applications to safely bypass
fsync/msync requirements. The idea is to make the file immutable with
respect to the offset-to-block mappings for every extent in the file
[2]. It turns out that filesystems already need to make this guarantee
today. This property is needed for files marked as swap files.
The new daxctl() syscall manages setting a file into 'static-dax' mode
whereby it arranges for the file to be treated as a swapfile as far as
the filesystem is concerned, but not registered with the core-mm as
swapfile space. A file in this mode is then safe to be mapped and
written without the requirement to fsync/msync the writes. The cpu
cache management for flushing data to persistence can be handled
completely in userspace.
As can be seen in the patches there are still some TODOs to resolve in
the code, but this otherwise appears to solve the problem of persistent
memory applications needing to coordinate any and all writes to a file
mapping with fsync/msync.
[1]: https://lists.gnu.org/archive/html/qemu-devel/2017-06/msg01207.html
[2]: https://lkml.org/lkml/2016/9/11/159
---
Dan Williams (2):
mm: introduce bmap_walk()
mm, fs: daxfile, an interface for byte-addressable updates to pmem
arch/x86/entry/syscalls/syscall_64.tbl | 1
include/linux/dax.h | 9 ++
include/linux/fs.h | 3 +
include/linux/syscalls.h | 1
include/uapi/linux/dax.h | 8 +
mm/Kconfig | 5 +
mm/Makefile | 1
mm/daxfile.c | 186 ++++++++++++++++++++++++++++++++
mm/page_io.c | 117 +++++++++++++++++---
9 files changed, 312 insertions(+), 19 deletions(-)
create mode 100644 include/uapi/linux/dax.h
create mode 100644 mm/daxfile.c
[toc] | [next] | [standalone]
| From | Dan Williams <dan.j.williams@intel.com> |
|---|---|
| Date | 2017-06-17 03:30 +0200 |
| Subject | [RFC PATCH 2/2] mm, fs: daxfile, an interface for byte-addressable updates to pmem |
| Message-ID | <tTaIN-8fC-7@gated-at.bofh.it> |
| In reply to | #1668122 |
To date, the full promise of byte-addressable access to persistent
memory has only been half realized via the filesystem-dax interface. The
current filesystem-dax mechanism allows an application to consume (read)
data from persistent storage at byte-size granularity, bypassing the
full page reads required by traditional storage devices.
Now, for writes, applications still need to contend with
page-granularity dirtying and flushing semantics as well as filesystem
coordination for metadata updates after any mmap write. The current
situation precludes use cases that leverage byte-granularity / in-place
updates to persistent media.
To get around this limitation there are some specialized applications
that are using the device-dax interface to bypass the overhead and
data-safety problems of the current filesystem-dax mmap-write path.
QEMU-KVM is forced to use device-dax to safely pass through persistent
memory to a guest [1]. Some specialized databases are using device-dax
for byte-granularity writes. Outside of those cases, device-dax is
difficult for general purpose persistent memory applications to consume.
There is demand for access to pmem without needing to contend with
special device configuration and other device-dax limitations.
The 'daxfile' interface satisfies this demand and realizes one of Dave
Chinner's ideas for allowing pmem applications to safely bypass
fsync/msync requirements. The idea is to make the file immutable with
respect to the offset-to-block mappings for every extent in the file
[2]. It turns out that filesystems already need to make this guarantee
today. This property is needed for files marked as swap files.
The new daxctl() syscall manages setting a file into 'static-dax' mode
whereby it arranges for the file to be treated as a swapfile as far as
the filesystem is concerned, but not registered with the core-mm as
swapfile space. A file in this mode is then safe to be mapped and
written without the requirement to fsync/msync the writes. The cpu
cache management for flushing data to persistence can be handled
completely in userspace.
[1]: https://lists.gnu.org/archive/html/qemu-devel/2017-06/msg01207.html
[2]: https://lkml.org/lkml/2016/9/11/159
Cc: Jan Kara <jack@suse.cz>
Cc: Jeff Moyer <jmoyer@redhat.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Ross Zwisler <ross.zwisler@linux.intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
arch/x86/entry/syscalls/syscall_64.tbl | 1
include/linux/dax.h | 9 ++
include/linux/fs.h | 3 +
include/linux/syscalls.h | 1
include/uapi/linux/dax.h | 8 +
mm/Kconfig | 5 +
mm/Makefile | 1
mm/daxfile.c | 186 ++++++++++++++++++++++++++++++++
mm/page_io.c | 31 +++++
9 files changed, 245 insertions(+)
create mode 100644 include/uapi/linux/dax.h
create mode 100644 mm/daxfile.c
diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
index 5aef183e2f85..795eb93d6beb 100644
--- a/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/arch/x86/entry/syscalls/syscall_64.tbl
@@ -339,6 +339,7 @@
330 common pkey_alloc sys_pkey_alloc
331 common pkey_free sys_pkey_free
332 common statx sys_statx
+333 64 daxctl sys_daxctl
#
# x32-specific system call numbers start at 512 to avoid cache impact
diff --git a/include/linux/dax.h b/include/linux/dax.h
index 5ec1f6c47716..5f1d0e0ed30f 100644
--- a/include/linux/dax.h
+++ b/include/linux/dax.h
@@ -4,8 +4,17 @@
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/radix-tree.h>
+#include <uapi/linux/dax.h>
#include <asm/pgtable.h>
+/*
+ * TODO: make sys_daxctl() be the generic interface for toggling S_DAX
+ * across filesystems. For now, mark DAXCTL_F_DAX as an invalid flag
+ */
+#define DAXCTL_VALID_FLAGS (DAXCTL_F_GET | DAXCTL_F_STATIC)
+
+int daxfile_activate(struct file *daxfile, unsigned align);
+
struct iomap_ops;
struct dax_device;
struct dax_operations {
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 3e68cabb8457..3af649fb669f 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1824,8 +1824,10 @@ struct super_operations {
#define S_NOSEC 4096 /* no suid or xattr security attributes */
#ifdef CONFIG_FS_DAX
#define S_DAX 8192 /* Direct Access, avoiding the page cache */
+#define S_DAXFILE 16384 /* no truncate (swapfile) semantics + dax */
#else
#define S_DAX 0 /* Make all the DAX code disappear */
+#define S_DAXFILE 0
#endif
/*
@@ -1865,6 +1867,7 @@ struct super_operations {
#define IS_AUTOMOUNT(inode) ((inode)->i_flags & S_AUTOMOUNT)
#define IS_NOSEC(inode) ((inode)->i_flags & S_NOSEC)
#define IS_DAX(inode) ((inode)->i_flags & S_DAX)
+#define IS_DAXFILE(inode) ((inode)->i_flags & S_DAXFILE)
#define IS_WHITEOUT(inode) (S_ISCHR(inode->i_mode) && \
(inode)->i_rdev == WHITEOUT_DEV)
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 980c3c9b06f8..49e5cc4c192e 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -701,6 +701,7 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
unsigned long arg4, unsigned long arg5);
asmlinkage long sys_swapon(const char __user *specialfile, int swap_flags);
asmlinkage long sys_swapoff(const char __user *specialfile);
+asmlinkage long sys_daxctl(const char __user *path, int flags, int align);
asmlinkage long sys_sysctl(struct __sysctl_args __user *args);
asmlinkage long sys_sysinfo(struct sysinfo __user *info);
asmlinkage long sys_sysfs(int option,
diff --git a/include/uapi/linux/dax.h b/include/uapi/linux/dax.h
new file mode 100644
index 000000000000..78a41bb392c0
--- /dev/null
+++ b/include/uapi/linux/dax.h
@@ -0,0 +1,8 @@
+#ifndef _UAPI_LINUX_DAX_H
+#define _UAPI_LINUX_DAX_H
+
+#define DAXCTL_F_GET (1 << 0)
+#define DAXCTL_F_DAX (1 << 1)
+#define DAXCTL_F_STATIC (1 << 2)
+
+#endif /* _UAPI_LINUX_DAX_H */
diff --git a/mm/Kconfig b/mm/Kconfig
index beb7a455915d..b874565c34eb 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -450,6 +450,11 @@ config TRANSPARENT_HUGE_PAGECACHE
def_bool y
depends on TRANSPARENT_HUGEPAGE
+config DAXFILE
+ def_bool y
+ depends on FS_DAX
+ depends on SWAP
+
#
# UP and nommu archs use km based percpu allocator
#
diff --git a/mm/Makefile b/mm/Makefile
index 026f6a828a50..38d9025a3e37 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -56,6 +56,7 @@ endif
obj-$(CONFIG_HAVE_MEMBLOCK) += memblock.o
obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o
+obj-$(CONFIG_DAXFILE) += daxfile.o
obj-$(CONFIG_FRONTSWAP) += frontswap.o
obj-$(CONFIG_ZSWAP) += zswap.o
obj-$(CONFIG_HAS_DMA) += dmapool.o
diff --git a/mm/daxfile.c b/mm/daxfile.c
new file mode 100644
index 000000000000..fe230199c855
--- /dev/null
+++ b/mm/daxfile.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+#include <linux/dax.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/pagemap.h>
+#include <linux/syscalls.h>
+
+/*
+ * TODO: a list to lookup daxfiles assumes a low number of instances,
+ * revisit.
+ */
+static LIST_HEAD(daxfiles);
+static DEFINE_SPINLOCK(dax_lock);
+
+struct dax_info {
+ struct list_head list;
+ struct file *daxfile;
+};
+
+static int daxfile_disable(struct file *victim)
+{
+ int found = 0;
+ struct dax_info *d;
+ struct inode *inode;
+ struct file *daxfile;
+ struct address_space *mapping;
+
+ mapping = victim->f_mapping;
+ spin_lock(&dax_lock);
+ list_for_each_entry(d, &daxfiles, list)
+ if (d->daxfile->f_mapping == mapping) {
+ list_del(&d->list);
+ found = 1;
+ break;
+ }
+ spin_unlock(&dax_lock);
+
+ if (!found)
+ return -EINVAL;
+
+ daxfile = d->daxfile;
+
+ inode = mapping->host;
+ inode->i_flags &= ~(S_SWAPFILE | S_DAXFILE);
+ filp_close(daxfile, NULL);
+
+ return 0;
+}
+
+static int claim_daxfile_checks(struct inode *inode)
+{
+ if (!S_ISREG(inode->i_mode))
+ return -EINVAL;
+
+ if (!IS_DAX(inode))
+ return -EINVAL;
+
+ if (IS_SWAPFILE(inode) || IS_DAXFILE(inode))
+ return -EBUSY;
+
+ return 0;
+}
+
+int daxfile_enable(struct file *daxfile, int align)
+{
+ struct address_space *mapping;
+ struct inode *inode;
+ struct dax_info *d;
+ int rc;
+
+ if (align < 0)
+ return -EINVAL;
+
+ mapping = daxfile->f_mapping;
+ inode = mapping->host;
+
+ rc = claim_daxfile_checks(inode);
+ if (rc)
+ return rc;
+
+ rc = daxfile_activate(daxfile, align);
+ if (rc)
+ return rc;
+
+ d = kzalloc(sizeof(*d), GFP_KERNEL);
+ if (!d)
+ return -ENOMEM;
+ INIT_LIST_HEAD(&d->list);
+ d->daxfile = daxfile;
+
+ spin_lock(&dax_lock);
+ list_add(&d->list, &daxfiles);
+ spin_unlock(&dax_lock);
+
+ /*
+ * We set S_SWAPFILE to gain "no truncate" / static block
+ * allocation semantics, and S_DAXFILE so we can differentiate
+ * traditional swapfiles and assume static block mappings in the
+ * dax mmap path.
+ */
+ inode->i_flags |= S_SWAPFILE | S_DAXFILE;
+ return 0;
+}
+
+SYSCALL_DEFINE3(daxctl, const char __user *, path, int, flags, int, align)
+{
+ int rc;
+ struct filename *name;
+ struct inode *inode = NULL;
+ struct file *daxfile = NULL;
+ struct address_space *mapping;
+
+ if (flags & ~DAXCTL_VALID_FLAGS)
+ return -EINVAL;
+
+ name = getname(path);
+ if (IS_ERR(name))
+ return PTR_ERR(name);
+
+ daxfile = file_open_name(name, O_RDWR|O_LARGEFILE, 0);
+ if (IS_ERR(daxfile)) {
+ rc = PTR_ERR(daxfile);
+ daxfile = NULL;
+ goto out;
+ }
+
+ mapping = daxfile->f_mapping;
+ inode = mapping->host;
+ if (flags & DAXCTL_F_GET) {
+ /*
+ * We only report the state of DAXCTL_F_STATIC since
+ * there is no actions for applications to take based on
+ * the setting of S_DAX. However, if this interface is
+ * used for toggling S_DAX presumably userspace would
+ * want to know the state of the flag.
+ *
+ * TODO: revisit whether we want to report DAXCTL_F_DAX
+ * in the IS_DAX() case.
+ */
+ if (IS_DAXFILE(inode))
+ rc = DAXCTL_F_STATIC;
+ else
+ rc = 0;
+
+ goto out;
+ }
+
+ /*
+ * TODO: Should unprivileged users be allowed to control daxfile
+ * behavior? Perhaps a mount flag... is -o dax that flag?
+ */
+ if (!capable(CAP_LINUX_IMMUTABLE)) {
+ rc = -EPERM;
+ goto out;
+ }
+
+ inode_lock(inode);
+ if (!IS_DAXFILE(inode) && (flags & DAXCTL_F_STATIC)) {
+ rc = daxfile_enable(daxfile, align);
+ /* if successfully enabled hold daxfile open */
+ if (rc == 0)
+ daxfile = NULL;
+ } else if (IS_DAXFILE(inode) && !(flags & DAXCTL_F_STATIC))
+ rc = daxfile_disable(daxfile);
+ else
+ rc = 0;
+ inode_unlock(inode);
+
+out:
+ if (daxfile)
+ filp_close(daxfile, NULL);
+ if (name)
+ putname(name);
+ return rc;
+}
diff --git a/mm/page_io.c b/mm/page_io.c
index 5cec9a3d49f2..35160ad9c51f 100644
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -244,6 +244,37 @@ static int bmap_walk(struct file *file, const unsigned page_size,
goto out;
}
+static int daxfile_check(sector_t block, unsigned long page_no,
+ enum bmap_check type, void *none)
+{
+ if (type == BMAP_WALK_DONE)
+ return 0;
+
+ /*
+ * Unlike the swapfile case, fail daxfile_activate() if any file
+ * extent is not page aligned.
+ */
+ if (type != BMAP_WALK_FULLPAGE)
+ return -EINVAL;
+ return 0;
+}
+
+int daxfile_activate(struct file *daxfile, unsigned align)
+{
+ int rc;
+
+ if (!align)
+ align = PAGE_SIZE;
+
+ if (align < PAGE_SIZE || !is_power_of_2(align))
+ return -EINVAL;
+
+ rc = bmap_walk(daxfile, align, ULONG_MAX, NULL, daxfile_check, NULL);
+ if (rc)
+ pr_debug("daxctl: daxfile has holes\n");
+ return rc;
+}
+
static int swapfile_check(sector_t block, unsigned long page_no,
enum bmap_check type, void *_sis)
{
[toc] | [prev] | [next] | [standalone]
| From | Andy Lutomirski <luto@kernel.org> |
|---|---|
| Date | 2017-06-17 18:30 +0200 |
| Subject | Re: [RFC PATCH 2/2] mm, fs: daxfile, an interface for byte-addressable updates to pmem |
| Message-ID | <tToLM-1dz-5@gated-at.bofh.it> |
| In reply to | #1668123 |
On Fri, Jun 16, 2017 at 6:15 PM, Dan Williams <dan.j.williams@intel.com> wrote: > To date, the full promise of byte-addressable access to persistent > memory has only been half realized via the filesystem-dax interface. The > current filesystem-dax mechanism allows an application to consume (read) > data from persistent storage at byte-size granularity, bypassing the > full page reads required by traditional storage devices. > > Now, for writes, applications still need to contend with > page-granularity dirtying and flushing semantics as well as filesystem > coordination for metadata updates after any mmap write. The current > situation precludes use cases that leverage byte-granularity / in-place > updates to persistent media. > > To get around this limitation there are some specialized applications > that are using the device-dax interface to bypass the overhead and > data-safety problems of the current filesystem-dax mmap-write path. > QEMU-KVM is forced to use device-dax to safely pass through persistent > memory to a guest [1]. Some specialized databases are using device-dax > for byte-granularity writes. Outside of those cases, device-dax is > difficult for general purpose persistent memory applications to consume. > There is demand for access to pmem without needing to contend with > special device configuration and other device-dax limitations. > > The 'daxfile' interface satisfies this demand and realizes one of Dave > Chinner's ideas for allowing pmem applications to safely bypass > fsync/msync requirements. The idea is to make the file immutable with > respect to the offset-to-block mappings for every extent in the file > [2]. It turns out that filesystems already need to make this guarantee > today. This property is needed for files marked as swap files. > > The new daxctl() syscall manages setting a file into 'static-dax' mode > whereby it arranges for the file to be treated as a swapfile as far as > the filesystem is concerned, but not registered with the core-mm as > swapfile space. A file in this mode is then safe to be mapped and > written without the requirement to fsync/msync the writes. The cpu > cache management for flushing data to persistence can be handled > completely in userspace. Can you remind those of us who haven't played with DAX in a while what the problem is with mmapping a DAX file without this patchset? If there's some bookkkeeping needed to make sure that the filesystem will invalidate all the mappings if it decides to move the file, maybe that should be the default rather than needing a new syscall. --Andy
[toc] | [prev] | [next] | [standalone]
| From | Dan Williams <dan.j.williams@intel.com> |
|---|---|
| Date | 2017-06-18 00:00 +0200 |
| Subject | Re: [RFC PATCH 2/2] mm, fs: daxfile, an interface for byte-addressable updates to pmem |
| Message-ID | <tTtV7-4Gm-1@gated-at.bofh.it> |
| In reply to | #1668363 |
On Sat, Jun 17, 2017 at 9:25 AM, Andy Lutomirski <luto@kernel.org> wrote: > On Fri, Jun 16, 2017 at 6:15 PM, Dan Williams <dan.j.williams@intel.com> wrote: >> To date, the full promise of byte-addressable access to persistent >> memory has only been half realized via the filesystem-dax interface. The >> current filesystem-dax mechanism allows an application to consume (read) >> data from persistent storage at byte-size granularity, bypassing the >> full page reads required by traditional storage devices. >> >> Now, for writes, applications still need to contend with >> page-granularity dirtying and flushing semantics as well as filesystem >> coordination for metadata updates after any mmap write. The current >> situation precludes use cases that leverage byte-granularity / in-place >> updates to persistent media. >> >> To get around this limitation there are some specialized applications >> that are using the device-dax interface to bypass the overhead and >> data-safety problems of the current filesystem-dax mmap-write path. >> QEMU-KVM is forced to use device-dax to safely pass through persistent >> memory to a guest [1]. Some specialized databases are using device-dax >> for byte-granularity writes. Outside of those cases, device-dax is >> difficult for general purpose persistent memory applications to consume. >> There is demand for access to pmem without needing to contend with >> special device configuration and other device-dax limitations. >> >> The 'daxfile' interface satisfies this demand and realizes one of Dave >> Chinner's ideas for allowing pmem applications to safely bypass >> fsync/msync requirements. The idea is to make the file immutable with >> respect to the offset-to-block mappings for every extent in the file >> [2]. It turns out that filesystems already need to make this guarantee >> today. This property is needed for files marked as swap files. >> >> The new daxctl() syscall manages setting a file into 'static-dax' mode >> whereby it arranges for the file to be treated as a swapfile as far as >> the filesystem is concerned, but not registered with the core-mm as >> swapfile space. A file in this mode is then safe to be mapped and >> written without the requirement to fsync/msync the writes. The cpu >> cache management for flushing data to persistence can be handled >> completely in userspace. > > Can you remind those of us who haven't played with DAX in a while what > the problem is with mmapping a DAX file without this patchset? If > there's some bookkkeeping needed to make sure that the filesystem will > invalidate all the mappings if it decides to move the file, maybe that > should be the default rather than needing a new syscall. The bookkeeping to invalidate mappings when the filesystem moves a block is already there. Without this patchset an application needs to call fsync/msync after any write to a DAX mapping otherwise there is no guarantee the filesystem has written the metadata to find the updated block after a crash or power loss event. Even if the sync operation is reduced to a minimal cmpxchg in userspace to check if the filesystem-metadata is dirty, that mechanism doesn't translate to a virtualized environment, as requiring guests to trigger host fsync()s is not feasible. It's a half-step solution when you can instead just ask the filesystem to never move blocks, as Dave proposed many months back. We stepped back from that proposal when it looked like a significant amount of per-filesystem work to introduce the capability and it was not clear that application developers would tolerate the side effects of this 'immutable' semantic. However, the implementation is dead simple since ext4 and xfs already need to make block-allocation-immutable semantics available for swapfiles. We also have application developers telling us they are ok with the semantics, especially because it catches Linux up to other operating environments that are already on board with allowing this type of access to pmem through a filesystem. This patchset gives pmem application developers what they want without any additional burden on filesystem implementations.
[toc] | [prev] | [next] | [standalone]
| From | Andy Lutomirski <luto@kernel.org> |
|---|---|
| Date | 2017-06-18 02:00 +0200 |
| Subject | Re: [RFC PATCH 2/2] mm, fs: daxfile, an interface for byte-addressable updates to pmem |
| Message-ID | <tTvNg-5Xy-3@gated-at.bofh.it> |
| In reply to | #1668400 |
On Sat, Jun 17, 2017 at 2:52 PM, Dan Williams <dan.j.williams@intel.com> wrote: > On Sat, Jun 17, 2017 at 9:25 AM, Andy Lutomirski <luto@kernel.org> wrote: >> >> Can you remind those of us who haven't played with DAX in a while what >> the problem is with mmapping a DAX file without this patchset? If >> there's some bookkkeeping needed to make sure that the filesystem will >> invalidate all the mappings if it decides to move the file, maybe that >> should be the default rather than needing a new syscall. > > The bookkeeping to invalidate mappings when the filesystem moves a > block is already there. > > Without this patchset an application needs to call fsync/msync after > any write to a DAX mapping otherwise there is no guarantee the > filesystem has written the metadata to find the updated block after a > crash or power loss event. Even if the sync operation is reduced to a > minimal cmpxchg in userspace to check if the filesystem-metadata is > dirty, that mechanism doesn't translate to a virtualized environment, > as requiring guests to trigger host fsync()s is not feasible. It's a > half-step solution when you can instead just ask the filesystem to > never move blocks, as Dave proposed many months back. > > We stepped back from that proposal when it looked like a significant > amount of per-filesystem work to introduce the capability and it was > not clear that application developers would tolerate the side effects > of this 'immutable' semantic. However, the implementation is dead > simple since ext4 and xfs already need to make > block-allocation-immutable semantics available for swapfiles. We also > have application developers telling us they are ok with the semantics, > especially because it catches Linux up to other operating environments > that are already on board with allowing this type of access to pmem > through a filesystem. This patchset gives pmem application developers > what they want without any additional burden on filesystem > implementations. I see. I have a couple of minor-ish issues with the current proposal, then. One is that I think the terminology should be changed to still make sense if filesystems or VFS improves to make this approach unnecessary. Rather than saying "this file is now static", perhaps users should set a flag with the explicit semantics that "mmaps of this file are guaranteed not to lose data due to the kernel's activities", IOW that mmaps will be at least as durable as a direct mapping of DAX memory. Then the kernel has the flexibility to add a future implementation in which, instead of pinning the file, the filesystem just knows to keep metadata synced before allowing page_mkwrite to re-enable writes to an mmapped DAX file. My other objection is that the syscall intentionally leaks a reference to the file. This means it needs overflow protection and it probably shouldn't ever be allowed to use it without privilege. Why can't the underlying issue be easily fixed, though? Could .page_mkwrite just make sure that metadata is synced when the FS uses DAX? On a DAX fs, syncing metadata should be extremely fast. This could be conditioned on an madvise or mmap flag if performance might be an issue. As far as I know, this change alone should be sufficient.
[toc] | [prev] | [next] | [standalone]
| From | Dan Williams <dan.j.williams@intel.com> |
|---|---|
| Date | 2017-06-18 05:20 +0200 |
| Subject | Re: [RFC PATCH 2/2] mm, fs: daxfile, an interface for byte-addressable updates to pmem |
| Message-ID | <tTyUN-8aj-11@gated-at.bofh.it> |
| In reply to | #1668492 |
On Sat, Jun 17, 2017 at 4:50 PM, Andy Lutomirski <luto@kernel.org> wrote: > On Sat, Jun 17, 2017 at 2:52 PM, Dan Williams <dan.j.williams@intel.com> wrote: >> On Sat, Jun 17, 2017 at 9:25 AM, Andy Lutomirski <luto@kernel.org> wrote: >>> >>> Can you remind those of us who haven't played with DAX in a while what >>> the problem is with mmapping a DAX file without this patchset? If >>> there's some bookkkeeping needed to make sure that the filesystem will >>> invalidate all the mappings if it decides to move the file, maybe that >>> should be the default rather than needing a new syscall. >> >> The bookkeeping to invalidate mappings when the filesystem moves a >> block is already there. >> >> Without this patchset an application needs to call fsync/msync after >> any write to a DAX mapping otherwise there is no guarantee the >> filesystem has written the metadata to find the updated block after a >> crash or power loss event. Even if the sync operation is reduced to a >> minimal cmpxchg in userspace to check if the filesystem-metadata is >> dirty, that mechanism doesn't translate to a virtualized environment, >> as requiring guests to trigger host fsync()s is not feasible. It's a >> half-step solution when you can instead just ask the filesystem to >> never move blocks, as Dave proposed many months back. >> >> We stepped back from that proposal when it looked like a significant >> amount of per-filesystem work to introduce the capability and it was >> not clear that application developers would tolerate the side effects >> of this 'immutable' semantic. However, the implementation is dead >> simple since ext4 and xfs already need to make >> block-allocation-immutable semantics available for swapfiles. We also >> have application developers telling us they are ok with the semantics, >> especially because it catches Linux up to other operating environments >> that are already on board with allowing this type of access to pmem >> through a filesystem. This patchset gives pmem application developers >> what they want without any additional burden on filesystem >> implementations. > > I see. > > I have a couple of minor-ish issues with the current proposal, then. > One is that I think the terminology should be changed to still make > sense if filesystems or VFS improves to make this approach > unnecessary. Rather than saying "this file is now static", perhaps > users should set a flag with the explicit semantics that "mmaps of > this file are guaranteed not to lose data due to the kernel's > activities", IOW that mmaps will be at least as durable as a direct > mapping of DAX memory. Then the kernel has the flexibility to add a > future implementation in which, instead of pinning the file, the > filesystem just knows to keep metadata synced before allowing > page_mkwrite to re-enable writes to an mmapped DAX file. Yes, sounds good to me. Rename the flag to DAXCTL_F_SYNC to indicate updates via mmap to this file are synchronous as far as block allocation metadata is concerned. Future filesystems are then free to always support this synchronous mode without using the swapfile hack. > My other objection is that the syscall intentionally leaks a reference > to the file. This means it needs overflow protection and it probably > shouldn't ever be allowed to use it without privilege. We only hold the one reference while S_DAXFILE is set, so I think the protection is there, and per Dave's original proposal this requires CAP_LINUX_IMMUTABLE. > Why can't the underlying issue be easily fixed, though? Could > .page_mkwrite just make sure that metadata is synced when the FS uses > DAX? Yes, it most definitely could and that idea has been floated. > On a DAX fs, syncing metadata should be extremely fast. This > could be conditioned on an madvise or mmap flag if performance might > be an issue. As far as I know, this change alone should be > sufficient. The hang up is that it requires per-fs enabling as it needs to be careful to manage mmap_sem vs fs journal locks for example. I know the in-development NOVA [1] filesystem is planning to support this out of the gate. ext4 would be open to implementing it, but I think xfs is cold on the idea. Christoph originally proposed it here [2], before Dave went on to propose immutable semantics. [1]: https://github.com/NVSL/NOVA [2]: https://lists.01.org/pipermail/linux-nvdimm/2016-February/004609.html
[toc] | [prev] | [next] | [standalone]
| From | Andy Lutomirski <luto@kernel.org> |
|---|---|
| Date | 2017-06-18 07:10 +0200 |
| Subject | Re: [RFC PATCH 2/2] mm, fs: daxfile, an interface for byte-addressable updates to pmem |
| Message-ID | <tTADf-Qd-1@gated-at.bofh.it> |
| In reply to | #1668522 |
On Sat, Jun 17, 2017 at 8:15 PM, Dan Williams <dan.j.williams@intel.com> wrote:
> On Sat, Jun 17, 2017 at 4:50 PM, Andy Lutomirski <luto@kernel.org> wrote:
>> My other objection is that the syscall intentionally leaks a reference
>> to the file. This means it needs overflow protection and it probably
>> shouldn't ever be allowed to use it without privilege.
>
> We only hold the one reference while S_DAXFILE is set, so I think the
> protection is there, and per Dave's original proposal this requires
> CAP_LINUX_IMMUTABLE.
>
>> Why can't the underlying issue be easily fixed, though? Could
>> .page_mkwrite just make sure that metadata is synced when the FS uses
>> DAX?
>
> Yes, it most definitely could and that idea has been floated.
>
>> On a DAX fs, syncing metadata should be extremely fast. This
>> could be conditioned on an madvise or mmap flag if performance might
>> be an issue. As far as I know, this change alone should be
>> sufficient.
>
> The hang up is that it requires per-fs enabling as it needs to be
> careful to manage mmap_sem vs fs journal locks for example. I know the
> in-development NOVA [1] filesystem is planning to support this out of
> the gate. ext4 would be open to implementing it, but I think xfs is
> cold on the idea. Christoph originally proposed it here [2], before
> Dave went on to propose immutable semantics.
Hmm. Given a choice between a very clean API that works without
privilege but is awkward to implement on XFS and an awkward-to-use
API, I'd personally choose the former.
Dave, even with the lock ordering issue, couldn't XFS implement
MAP_PMEM_AWARE by having .page_mkwrite work roughly like this:
if (metadata is dirty) {
up_write(&mmap_sem);
sync the metadata;
down_write(&mmap_sem);
return 0; /* retry the fault */
} else {
return whatever success code;
}
This might require returning VM_FAULT_RETRY instead of 0 and it might
require auditing the core mm code to make sure that it can handle
mmap_sem being dropped like this. I don't see why it couldn't work in
principle, though.
[toc] | [prev] | [next] | [standalone]
| From | Dave Chinner <david@fromorbit.com> |
|---|---|
| Date | 2017-06-19 15:30 +0200 |
| Subject | Re: [RFC PATCH 2/2] mm, fs: daxfile, an interface for byte-addressable updates to pmem |
| Message-ID | <tU4UH-3bd-41@gated-at.bofh.it> |
| In reply to | #1668545 |
On Sat, Jun 17, 2017 at 10:05:45PM -0700, Andy Lutomirski wrote:
> On Sat, Jun 17, 2017 at 8:15 PM, Dan Williams <dan.j.williams@intel.com> wrote:
> > On Sat, Jun 17, 2017 at 4:50 PM, Andy Lutomirski <luto@kernel.org> wrote:
> >> My other objection is that the syscall intentionally leaks a reference
> >> to the file. This means it needs overflow protection and it probably
> >> shouldn't ever be allowed to use it without privilege.
> >
> > We only hold the one reference while S_DAXFILE is set, so I think the
> > protection is there, and per Dave's original proposal this requires
> > CAP_LINUX_IMMUTABLE.
> >
> >> Why can't the underlying issue be easily fixed, though? Could
> >> .page_mkwrite just make sure that metadata is synced when the FS uses
> >> DAX?
> >
> > Yes, it most definitely could and that idea has been floated.
> >
> >> On a DAX fs, syncing metadata should be extremely fast.
<sigh>
This again....
Persistent memory means the *I/O* is fast. It does not mean that
*complex filesystem operations* are fast.
Don't forget that there's an shitload of CPU that gets burnt to make
sure that the metadata is synced correctly. Do that /synchronously/
on *every* write page fault (which, BTW, modify mtime, so will
always have dirty metadata to sync) and now you have a serious
performance problem with your "fast" DAX access method.
And that's before we even consider all the problems with running
sync operations in page fault context....
> >> This
> >> could be conditioned on an madvise or mmap flag if performance might
> >> be an issue. As far as I know, this change alone should be
> >> sufficient.
> >
> > The hang up is that it requires per-fs enabling as it needs to be
> > careful to manage mmap_sem vs fs journal locks for example. I know the
> > in-development NOVA [1] filesystem is planning to support this out of
> > the gate. ext4 would be open to implementing it, but I think xfs is
> > cold on the idea. Christoph originally proposed it here [2], before
> > Dave went on to propose immutable semantics.
>
> Hmm. Given a choice between a very clean API that works without
> privilege but is awkward to implement on XFS and an awkward-to-use
> API, I'd personally choose the former.
Yup, you have the choice of a clean kernel API that will be
substantially slower than the existing "dirty page" tracking and
having the app run fsync() when necessary, or having to do a little
more work in a library routine that preallocates a file and sets a
flag on it?
The apps will use the library API, not the kernel API, so who really
cares if there's a few steps to setting up the file state
appropriately?
> Dave, even with the lock ordering issue, couldn't XFS implement
> MAP_PMEM_AWARE by having .page_mkwrite work roughly like this:
>
> if (metadata is dirty) {
> up_write(&mmap_sem);
> sync the metadata;
> down_write(&mmap_sem);
> return 0; /* retry the fault */
> } else {
> return whatever success code;
> }
How do you know that there is dependent filesystem metadata that
needs syncing at a level that you can safely manipulate the
mmap_sem? And how, exactly, do you do this without races? It'd be
trivial to DOS such retryable DAX faults simply by touching the file
in a tight loop in a separate process...
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
[toc] | [prev] | [next] | [standalone]
| From | Andy Lutomirski <luto@kernel.org> |
|---|---|
| Date | 2017-06-19 17:30 +0200 |
| Subject | Re: [RFC PATCH 2/2] mm, fs: daxfile, an interface for byte-addressable updates to pmem |
| Message-ID | <tU6MS-4pB-115@gated-at.bofh.it> |
| In reply to | #1669068 |
On Mon, Jun 19, 2017 at 6:21 AM, Dave Chinner <david@fromorbit.com> wrote:
> On Sat, Jun 17, 2017 at 10:05:45PM -0700, Andy Lutomirski wrote:
>> On Sat, Jun 17, 2017 at 8:15 PM, Dan Williams <dan.j.williams@intel.com> wrote:
>> > On Sat, Jun 17, 2017 at 4:50 PM, Andy Lutomirski <luto@kernel.org> wrote:
>> >> My other objection is that the syscall intentionally leaks a reference
>> >> to the file. This means it needs overflow protection and it probably
>> >> shouldn't ever be allowed to use it without privilege.
>> >
>> > We only hold the one reference while S_DAXFILE is set, so I think the
>> > protection is there, and per Dave's original proposal this requires
>> > CAP_LINUX_IMMUTABLE.
>> >
>> >> Why can't the underlying issue be easily fixed, though? Could
>> >> .page_mkwrite just make sure that metadata is synced when the FS uses
>> >> DAX?
>> >
>> > Yes, it most definitely could and that idea has been floated.
>> >
>> >> On a DAX fs, syncing metadata should be extremely fast.
>
> <sigh>
>
> This again....
>
> Persistent memory means the *I/O* is fast. It does not mean that
> *complex filesystem operations* are fast.
>
> Don't forget that there's an shitload of CPU that gets burnt to make
> sure that the metadata is synced correctly. Do that /synchronously/
> on *every* write page fault (which, BTW, modify mtime, so will
> always have dirty metadata to sync) and now you have a serious
> performance problem with your "fast" DAX access method.
I think the mtime issue can and should be solved separately. But it'
s a fair point that there would be workloads for which this could be
excessively expensive. In particular, simply creating a file,
mmapping a large range, and touching the pages one by one -- delalloc
would be completely defeated.
But here's a strawman for solving both issues. First, mtime. I
consider it to be either a bug or a misfeature that .page_mkwrite
*ever* dirties an inode just to update mtime. I have old patches to
fix this, and those patches could be updated and merged. With them
applied, there's just a set_bit() in .page_mkwrite() to handle mtime.
https://git.kernel.org/pub/scm/linux/kernel/git/luto/linux.git/log/?h=mmap_mtime/patch_v4
Second: syncing extents. Here's a straw man. Forget the mmap() flag.
Instead add a new msync() operation:
msync(start, length, MSYNC_PMEM_PREPARE_WRITE);
If this operation succeeds, it guarantees that all future writes
through this mapping on this range will hit actual storage and that
all the metadata operations needed to make this write persistent will
hit storage such that they are ordered before the user's writes.
As an implementation detail, this will flush out the extents if
needed. In addition, if the FS has any mechanism that would cause
problems asyncronously later on (dedupe? deallocated extents full of
zeros? defrag?), it may also need to set a flag on the VMA that
changes the behavior of future .page_mkwrite operations.
(On x86, for example, this would permit the FS to do WC/streaming
writes without SFENCE if the FS were structured in a way that this
worked.)
Now we have an API that should work going forward without introducing
baggage. And XFS is free to implement this API by making the entire
file act like a swap file if XFS wants to do so, but this doesn't
force other filesystems (ext4? NOVA?) to do the same thing.
>
> And that's before we even consider all the problems with running
> sync operations in page fault context....
>
>> >> This
>> >> could be conditioned on an madvise or mmap flag if performance might
>> >> be an issue. As far as I know, this change alone should be
>> >> sufficient.
>> >
>> > The hang up is that it requires per-fs enabling as it needs to be
>> > careful to manage mmap_sem vs fs journal locks for example. I know the
>> > in-development NOVA [1] filesystem is planning to support this out of
>> > the gate. ext4 would be open to implementing it, but I think xfs is
>> > cold on the idea. Christoph originally proposed it here [2], before
>> > Dave went on to propose immutable semantics.
>>
>> Hmm. Given a choice between a very clean API that works without
>> privilege but is awkward to implement on XFS and an awkward-to-use
>> API, I'd personally choose the former.
>
> Yup, you have the choice of a clean kernel API that will be
> substantially slower than the existing "dirty page" tracking and
> having the app run fsync() when necessary, or having to do a little
> more work in a library routine that preallocates a file and sets a
> flag on it?
>
> The apps will use the library API, not the kernel API, so who really
> cares if there's a few steps to setting up the file state
> appropriately?
>
>> Dave, even with the lock ordering issue, couldn't XFS implement
>> MAP_PMEM_AWARE by having .page_mkwrite work roughly like this:
>>
>> if (metadata is dirty) {
>> up_write(&mmap_sem);
>> sync the metadata;
>> down_write(&mmap_sem);
>> return 0; /* retry the fault */
>> } else {
>> return whatever success code;
>> }
>
> How do you know that there is dependent filesystem metadata that
> needs syncing at a level that you can safely manipulate the
> mmap_sem? And how, exactly, do you do this without races?
I have no idea, but I expect that all the locking issues are solvable.
> It'd be
> trivial to DOS such retryable DAX faults simply by touching the file
> in a tight loop in a separate process...
If the code were smart enough to only cause a retry when the extent
being touched is dirty, this problem wouldn't exist.
[toc] | [prev] | [next] | [standalone]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2017-06-18 10:20 +0200 |
| Subject | Re: [RFC PATCH 2/2] mm, fs: daxfile, an interface for byte-addressable updates to pmem |
| Message-ID | <tTDB8-2Ev-1@gated-at.bofh.it> |
| In reply to | #1668522 |
On Sat, Jun 17, 2017 at 08:15:05PM -0700, Dan Williams wrote: > The hang up is that it requires per-fs enabling as it needs to be > careful to manage mmap_sem vs fs journal locks for example. I know the > in-development NOVA [1] filesystem is planning to support this out of > the gate. ext4 would be open to implementing it, but I think xfs is > cold on the idea. Christoph originally proposed it here [2], before > Dave went on to propose immutable semantics. > > [1]: https://github.com/NVSL/NOVA > [2]: https://lists.01.org/pipermail/linux-nvdimm/2016-February/004609.html And I stand to that statement. Let's get DAX stable first, and properly cleaned up (e.g. follow on work with separating it entirely from the block device). Then think hard about how most of the persistent memory technologies actually work, including the point that for a lot of workloads page cache will be required at least on the write side. And then come up with actual real use cases and we can look into it. And stop trying to shoe-horn crap like this in.
[toc] | [prev] | [next] | [standalone]
| From | Dan Williams <dan.j.williams@intel.com> |
|---|---|
| Date | 2017-06-19 04:00 +0200 |
| Subject | Re: [RFC PATCH 2/2] mm, fs: daxfile, an interface for byte-addressable updates to pmem |
| Message-ID | <tTU8V-4tZ-1@gated-at.bofh.it> |
| In reply to | #1668557 |
On Sun, Jun 18, 2017 at 1:18 AM, Christoph Hellwig <hch@lst.de> wrote: > On Sat, Jun 17, 2017 at 08:15:05PM -0700, Dan Williams wrote: >> The hang up is that it requires per-fs enabling as it needs to be >> careful to manage mmap_sem vs fs journal locks for example. I know the >> in-development NOVA [1] filesystem is planning to support this out of >> the gate. ext4 would be open to implementing it, but I think xfs is >> cold on the idea. Christoph originally proposed it here [2], before >> Dave went on to propose immutable semantics. >> >> [1]: https://github.com/NVSL/NOVA >> [2]: https://lists.01.org/pipermail/linux-nvdimm/2016-February/004609.html > > And I stand to that statement. Let's get DAX stable first, and > properly cleaned up (e.g. follow on work with separating it entirely > from the block device). Then think hard about how most of the > persistent memory technologies actually work, including the point that > for a lot of workloads page cache will be required at least on the > write side. And then come up with actual real use cases and we can > look into it. I see it differently. We're already at a good point in time to start iterating on a fix for this issue. Ross and Jan have done a lot of good work on the dax stability front, and the block-device separation of dax is well underway. > And stop trying to shoe-horn crap like this in. The kernel shoe-horning all pmem+filesystem-dax applications into abiding page-cache semantics is a problem, and this RFC has already helped move the needle on a couple fronts. 1/ Swapfiles are subtly broken which is something worth fixing, and if it gets us a synchronous-dax mode without major filesystem surgery then that's all for the better. 2/ There's an appetite for just fixing this incrementally in each filesystem's fault handler, so if ext4 was able to prove out an interface / implementation for synchronous faults we could go with that instead of a pre-allocated + immutable interface and let other filesystems set their own timelines.
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web