Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1237093 > unrolled thread
| Started by | Dave Chinner <david@fromorbit.com> |
|---|---|
| First post | 2015-10-01 09:50 +0200 |
| Last post | 2015-10-02 01:00 +0200 |
| Articles | 13 — 4 participants |
Back to article view | Back to linux.kernel
[PATCH 0/7] xfs, dax: fix the page fault/allocation mess Dave Chinner <david@fromorbit.com> - 2015-10-01 09:50 +0200
[PATCH 4/7] xfs: introduce BMAPI_ZERO for allocating zeroed extents Dave Chinner <david@fromorbit.com> - 2015-10-01 09:50 +0200
[PATCH 6/7] xfs: DAX does not use IO completion callbacks Dave Chinner <david@fromorbit.com> - 2015-10-01 09:50 +0200
[PATCH 7/7] xfs: add ->pfn_mkwrite support for DAX Dave Chinner <david@fromorbit.com> - 2015-10-01 09:50 +0200
[PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" Dave Chinner <david@fromorbit.com> - 2015-10-01 10:00 +0200
Re: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" kbuild test robot <lkp@intel.com> - 2015-10-01 10:40 +0200
Re: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" Ross Zwisler <ross.zwisler@linux.intel.com> - 2015-10-01 22:30 +0200
Re: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" "Williams, Dan J" <dan.j.williams@intel.com> - 2015-10-02 00:20 +0200
Re: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" Ross Zwisler <ross.zwisler@linux.intel.com> - 2015-10-02 00:50 +0200
Re: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" Dave Chinner <david@fromorbit.com> - 2015-10-02 00:40 +0200
Re: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" Ross Zwisler <ross.zwisler@linux.intel.com> - 2015-10-02 00:50 +0200
Re: [PATCH 0/7] xfs, dax: fix the page fault/allocation mess Ross Zwisler <ross.zwisler@linux.intel.com> - 2015-10-01 22:40 +0200
Re: [PATCH 0/7] xfs, dax: fix the page fault/allocation mess Dave Chinner <david@fromorbit.com> - 2015-10-02 01:00 +0200
| From | Dave Chinner <david@fromorbit.com> |
|---|---|
| Date | 2015-10-01 09:50 +0200 |
| Subject | [PATCH 0/7] xfs, dax: fix the page fault/allocation mess |
| Message-ID | <qeGMO-5IY-11@gated-at.bofh.it> |
Hi folks, As discussed in the recent thread about problems with DAX locking: http://www.gossamer-threads.com/lists/linux/kernel/2264090?do=post_view_threaded I said that I'd post the patch set that fixed the problems for XFS as soon as I had something sane and workable. That's what this series is. To start with, it passes xfstests "auto" group with only the only failures being expected failures or failures due to unexpected allocation patterns or trying to use unsupported block sizes. That makes it better than any previous version of the XFS/DAX code. The patchset starts by reverting the two patches that were introduced in 4.3-rc1 to try to fix the fault vs fault and fault vs truncate races that caused deadlocks. This fixes the hangs in generic/075 that these patches introduced. Patch 3 enables XFS to handle the behaviour of DAX and DIO when asking to allocate the block at (2^63 - 1FSB), where the offset + count s technically illegal (larger than sb->s_maxbytes) and overflows a s64 variable. This is currently hidden by the fact that all DAX and DIO allocation is currently unwritten, but patch 5 exposes it for DAX. Patch 4 introduces the ability for XFS to allocate physically zeroed data blocks. This is done for each physical extent that is allocated, deep inside the allocator itself and guaranteed to be atomic with the allocation transaction and hence has no crash+recovery exposure issues. This is necessary because the BMAPI layer merges allocated extents in the BMBT before it returns the mapped extent back to the high level get_blocks() code. Hence the high level code can have a single extent presented that is made of merged new and existing extents, and so zeroing can't be done at this layer. The advantage of driving the zeroing deep into the allocator is the functionality is now available to all XFS code. Hence we can allocate pre-zeroed blocks on any type of storage, and we can utilise storage-based hardware acceleration (e.g. discard to zero, WRITE_SAME, etc) to do the zeroing. From this POV, DAX is just another hardware accelerated physical zeroing mechanism for XFS. :) [ This is an example of the mantra I repeat a lot: solve the problem properly the first time and it will make everything simpler! Sure, it took me three attempts to work out how to solve it in a sane manner, but that's pretty much par for the course with anything non-trivial. ] Patch 5 makes __xfs_get_blocks() aware that it is being called from the DAX fault path and makes sure it returns zeroed blocks rather than unwritten extents via XFS_BMAPI_ZERO. It also now sets XFS_BMAPI_CONVERT, which tells it to convert unwritten extents to written, zeroed blocks. This is the major change of behaviour. Patch 6 removes the IO completion callbacks from the XFS DAX code as they are not longer necessary after patch 5. Patch 7 adds pfn_mkwrite support to XFS. This is needed to fix generic/080, which detects a failure to update the inode timestamp on a pfn fault. It also adds the same locking as the XFS implementation of ->fault and ->page_mkwrite and hence provide correct serialisation against truncate, hole punching, etc that doesn't currently exist. The next steps that are needed are to do the same "block zeroing during allocation" to ext4, and then the block zeroing and complete_unwritten callbacks can be removed from the DAX API and code. I've had a breif look at the ext4 code - the block zeroing should be able to be done by overloading the existing zeroout code that ext4 has in the unwritten extent allocation code. I'd much prefer that an ext4 expert does this work, and then we can clean up the DAX code... Cheers, Dave. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | Dave Chinner <david@fromorbit.com> |
|---|---|
| Date | 2015-10-01 09:50 +0200 |
| Subject | [PATCH 4/7] xfs: introduce BMAPI_ZERO for allocating zeroed extents |
| Message-ID | <qeGMP-5IY-37@gated-at.bofh.it> |
| In reply to | #1237093 |
From: Dave Chinner <dchinner@redhat.com>
To enable DAX to do atomic allocation of zeroed extents, we need to
drive the block zeroing deep into the allocator. Because
xfs_bmapi_write() can return merged extents on allocation that were
only partially allocated (i.e. requested range spans allocated and
hole regions, allocation into the hole was contiguous), we cannot
zero the extent returned from xfs_bmapi_write() as that can
overwrite existing data with zeros.
Hence we have to drive the extent zeroing into the allocation code,
prior to where we merge the extents into the BMBT and return the
resultant map. This means we need to propagate this need down to
the xfs_alloc_vextent() and issue the block zeroing at this point.
While this functionality is being introduced for DAX, there is no
reason why it is specific to DAX - we can per-zero blocks during the
allocation transaction on any type of device. It's just slow (and
usually slower than unwritten allocation and conversion) on
traditional block devices so doesn't tend to get used. We can,
however, hook hardware zeroing optimisations via sb_issue_zeroout()
to this operation, so it may be useful in future and hence the
"allocate zeroed blocks" API needs to be implementation neutral.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
fs/xfs/libxfs/xfs_alloc.c | 10 +++++++++-
fs/xfs/libxfs/xfs_alloc.h | 8 +++++---
fs/xfs/libxfs/xfs_bmap.c | 25 +++++++++++++++++++++++--
fs/xfs/libxfs/xfs_bmap.h | 13 +++++++++++--
fs/xfs/xfs_bmap_util.c | 36 ++++++++++++++++++++++++++++++++++++
fs/xfs/xfs_mount.h | 3 +++
6 files changed, 87 insertions(+), 8 deletions(-)
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index ffad7f2..4cffc17 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -2503,7 +2503,7 @@ xfs_alloc_vextent(
* Try near allocation first, then anywhere-in-ag after
* the first a.g. fails.
*/
- if ((args->userdata == XFS_ALLOC_INITIAL_USER_DATA) &&
+ if ((args->userdata & XFS_ALLOC_INITIAL_USER_DATA) &&
(mp->m_flags & XFS_MOUNT_32BITINODES)) {
args->fsbno = XFS_AGB_TO_FSB(mp,
((mp->m_agfrotor / rotorstep) %
@@ -2634,6 +2634,14 @@ xfs_alloc_vextent(
XFS_AG_CHECK_DADDR(mp, XFS_FSB_TO_DADDR(mp, args->fsbno),
args->len);
#endif
+
+ /* Zero the extent if we were asked to do so */
+ if (args->userdata & XFS_ALLOC_USERDATA_ZERO) {
+ error = xfs_zero_extent(args->ip, args->fsbno, args->len);
+ if (error)
+ goto error0;
+ }
+
}
xfs_perag_put(args->pag);
return 0;
diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h
index ca1c816..0ecde4d 100644
--- a/fs/xfs/libxfs/xfs_alloc.h
+++ b/fs/xfs/libxfs/xfs_alloc.h
@@ -101,6 +101,7 @@ typedef struct xfs_alloc_arg {
struct xfs_mount *mp; /* file system mount point */
struct xfs_buf *agbp; /* buffer for a.g. freelist header */
struct xfs_perag *pag; /* per-ag struct for this agno */
+ struct xfs_inode *ip; /* for userdata zeroing method */
xfs_fsblock_t fsbno; /* file system block number */
xfs_agnumber_t agno; /* allocation group number */
xfs_agblock_t agbno; /* allocation group-relative block # */
@@ -120,15 +121,16 @@ typedef struct xfs_alloc_arg {
char wasdel; /* set if allocation was prev delayed */
char wasfromfl; /* set if allocation is from freelist */
char isfl; /* set if is freelist blocks - !acctg */
- char userdata; /* set if this is user data */
+ char userdata; /* mask defining userdata treatment */
xfs_fsblock_t firstblock; /* io first block allocated */
} xfs_alloc_arg_t;
/*
* Defines for userdata
*/
-#define XFS_ALLOC_USERDATA 1 /* allocation is for user data*/
-#define XFS_ALLOC_INITIAL_USER_DATA 2 /* special case start of file */
+#define XFS_ALLOC_USERDATA (1 << 0)/* allocation is for user data*/
+#define XFS_ALLOC_INITIAL_USER_DATA (1 << 1)/* special case start of file */
+#define XFS_ALLOC_USERDATA_ZERO (1 << 2)/* zero extent on allocation */
xfs_extlen_t xfs_alloc_longest_free_extent(struct xfs_mount *mp,
struct xfs_perag *pag, xfs_extlen_t need);
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 8e2010d..8f607ed 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -3800,8 +3800,13 @@ xfs_bmap_btalloc(
args.wasdel = ap->wasdel;
args.isfl = 0;
args.userdata = ap->userdata;
- if ((error = xfs_alloc_vextent(&args)))
+ if (ap->userdata & XFS_ALLOC_USERDATA_ZERO)
+ args.ip = ap->ip;
+
+ error = xfs_alloc_vextent(&args);
+ if (error)
return error;
+
if (tryagain && args.fsbno == NULLFSBLOCK) {
/*
* Exact allocation failed. Now try with alignment
@@ -4300,11 +4305,14 @@ xfs_bmapi_allocate(
/*
* Indicate if this is the first user data in the file, or just any
- * user data.
+ * user data. And if it is userdata, indicate whether it needs to
+ * be initialised to zero during allocation.
*/
if (!(bma->flags & XFS_BMAPI_METADATA)) {
bma->userdata = (bma->offset == 0) ?
XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA;
+ if (bma->flags & XFS_BMAPI_ZERO)
+ bma->userdata |= XFS_ALLOC_USERDATA_ZERO;
}
bma->minlen = (bma->flags & XFS_BMAPI_CONTIG) ? bma->length : 1;
@@ -4419,6 +4427,17 @@ xfs_bmapi_convert_unwritten(
mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN)
? XFS_EXT_NORM : XFS_EXT_UNWRITTEN;
+ /*
+ * Before insertion into the bmbt, zero the range being converted
+ * if required.
+ */
+ if (flags & XFS_BMAPI_ZERO) {
+ error = xfs_zero_extent(bma->ip, mval->br_startblock,
+ mval->br_blockcount);
+ if (error)
+ return error;
+ }
+
error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, &bma->idx,
&bma->cur, mval, bma->firstblock, bma->flist,
&tmp_logflags);
@@ -4511,6 +4530,8 @@ xfs_bmapi_write(
ASSERT(len > 0);
ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL);
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
+ ASSERT((flags & (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO)) !=
+ (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO));
if (unlikely(XFS_TEST_ERROR(
(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h
index 6aaa0c1..a160f8a 100644
--- a/fs/xfs/libxfs/xfs_bmap.h
+++ b/fs/xfs/libxfs/xfs_bmap.h
@@ -52,9 +52,9 @@ struct xfs_bmalloca {
xfs_extlen_t minleft; /* amount must be left after alloc */
bool eof; /* set if allocating past last extent */
bool wasdel; /* replacing a delayed allocation */
- bool userdata;/* set if is user data */
bool aeof; /* allocated space at eof */
bool conv; /* overwriting unwritten extents */
+ char userdata;/* userdata mask */
int flags;
};
@@ -109,6 +109,14 @@ typedef struct xfs_bmap_free
*/
#define XFS_BMAPI_CONVERT 0x040
+/*
+ * allocate zeroed extents - this requires all newly allocated user data extents
+ * to be initialised to zero. It will be ignored if XFS_BMAPI_METADATA is set.
+ * Use in conjunction with XFS_BMAPI_CONVERT to convert unwritten extents found
+ * during the allocation range to zeroed written extents.
+ */
+#define XFS_BMAPI_ZERO 0x080
+
#define XFS_BMAPI_FLAGS \
{ XFS_BMAPI_ENTIRE, "ENTIRE" }, \
{ XFS_BMAPI_METADATA, "METADATA" }, \
@@ -116,7 +124,8 @@ typedef struct xfs_bmap_free
{ XFS_BMAPI_PREALLOC, "PREALLOC" }, \
{ XFS_BMAPI_IGSTATE, "IGSTATE" }, \
{ XFS_BMAPI_CONTIG, "CONTIG" }, \
- { XFS_BMAPI_CONVERT, "CONVERT" }
+ { XFS_BMAPI_CONVERT, "CONVERT" }, \
+ { XFS_BMAPI_ZERO, "ZERO" }
static inline int xfs_bmapi_aflag(int w)
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index 3bf4ad0..3f59698 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -57,6 +57,35 @@ xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb)
}
/*
+ * Routine to zero an extent on disk allocated to the specific inode.
+ *
+ * The VFS functions take a linearised filesystem block offset, so we have to
+ * convert the sparse xfs fsb to the right format first.
+ * VFS types are real funky, too.
+ */
+int
+xfs_zero_extent(
+ struct xfs_inode *ip,
+ xfs_fsblock_t start_fsb,
+ xfs_off_t count_fsb)
+{
+ struct xfs_mount *mp = ip->i_mount;
+ xfs_daddr_t sector = xfs_fsb_to_db(ip, start_fsb);
+ sector_t block = XFS_BB_TO_FSBT(mp, sector);
+ ssize_t size = XFS_FSB_TO_B(mp, count_fsb);
+
+ if (IS_DAX(VFS_I(ip)))
+ return dax_clear_blocks(VFS_I(ip), block, size);
+
+ /*
+ * let the block layer decide on the fastest method of
+ * implementing the zeroing.
+ */
+ return sb_issue_zeroout(mp->m_super, block, count_fsb, GFP_NOFS);
+
+}
+
+/*
* Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi
* caller. Frees all the extents that need freeing, which must be done
* last due to locking considerations. We never free any extents in
@@ -229,6 +258,13 @@ xfs_bmap_rtalloc(
xfs_trans_mod_dquot_byino(ap->tp, ap->ip,
ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT :
XFS_TRANS_DQ_RTBCOUNT, (long) ralen);
+
+ /* Zero the extent if we were asked to do so */
+ if (ap->userdata & XFS_ALLOC_USERDATA_ZERO) {
+ error = xfs_zero_extent(ap->ip, ap->blkno, ap->length);
+ if (error)
+ return error;
+ }
} else {
ap->length = 0;
}
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 7999e91..404bfa5 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -336,4 +336,7 @@ extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
extern void xfs_set_low_space_thresholds(struct xfs_mount *);
+int xfs_zero_extent(struct xfs_inode *ip, xfs_fsblock_t start_fsb,
+ xfs_off_t count_fsb);
+
#endif /* __XFS_MOUNT_H__ */
--
2.5.0
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Dave Chinner <david@fromorbit.com> |
|---|---|
| Date | 2015-10-01 09:50 +0200 |
| Subject | [PATCH 6/7] xfs: DAX does not use IO completion callbacks |
| Message-ID | <qeGMP-5IY-39@gated-at.bofh.it> |
| In reply to | #1237093 |
From: Dave Chinner <dchinner@redhat.com>
For DAX, we are now doing block zeroing and
we are updating the file size during allocation. This means we no
longer need an IO completion callback to do these things, so remove
the completion callbacks from the __dax_fault and __dax_mkwrite
calls.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
fs/xfs/xfs_aops.c | 39 ---------------------------------------
fs/xfs/xfs_aops.h | 1 -
fs/xfs/xfs_file.c | 5 ++---
3 files changed, 2 insertions(+), 43 deletions(-)
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index df3dabd..69c2dbc 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -1657,45 +1657,6 @@ xfs_end_io_direct_write(
__xfs_end_io_direct_write(inode, ioend, offset, size);
}
-/*
- * For DAX we need a mapping buffer callback for unwritten extent conversion
- * when page faults allocate blocks and then zero them. Note that in this
- * case the mapping indicated by the ioend may extend beyond EOF. We most
- * definitely do not want to extend EOF here, so we trim back the ioend size to
- * EOF.
- */
-#ifdef CONFIG_FS_DAX
-void
-xfs_end_io_dax_write(
- struct buffer_head *bh,
- int uptodate)
-{
- struct xfs_ioend *ioend = bh->b_private;
- struct inode *inode = ioend->io_inode;
- ssize_t size = ioend->io_size;
-
- ASSERT(IS_DAX(ioend->io_inode));
-
- /* if there was an error zeroing, then don't convert it */
- if (!uptodate)
- ioend->io_error = -EIO;
-
- /*
- * Trim update to EOF, so we don't extend EOF during unwritten extent
- * conversion of partial EOF blocks.
- */
- spin_lock(&XFS_I(inode)->i_flags_lock);
- if (ioend->io_offset + size > i_size_read(inode))
- size = i_size_read(inode) - ioend->io_offset;
- spin_unlock(&XFS_I(inode)->i_flags_lock);
-
- __xfs_end_io_direct_write(inode, ioend, ioend->io_offset, size);
-
-}
-#else
-void xfs_end_io_dax_write(struct buffer_head *bh, int uptodate) { }
-#endif
-
static inline ssize_t
xfs_vm_do_dio(
struct inode *inode,
diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h
index d39ba25..f6ffc9a 100644
--- a/fs/xfs/xfs_aops.h
+++ b/fs/xfs/xfs_aops.h
@@ -60,7 +60,6 @@ int xfs_get_blocks_direct(struct inode *inode, sector_t offset,
struct buffer_head *map_bh, int create);
int xfs_get_blocks_dax_fault(struct inode *inode, sector_t offset,
struct buffer_head *map_bh, int create);
-void xfs_end_io_dax_write(struct buffer_head *bh, int uptodate);
extern void xfs_count_page_state(struct page *, int *, int *);
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 27abe1c..9c8eef7 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -1503,8 +1503,7 @@ xfs_filemap_page_mkwrite(
xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED);
if (IS_DAX(inode)) {
- ret = __dax_mkwrite(vma, vmf, xfs_get_blocks_dax_fault,
- xfs_end_io_dax_write);
+ ret = __dax_mkwrite(vma, vmf, xfs_get_blocks_dax_fault, NULL);
} else {
ret = __block_page_mkwrite(vma, vmf, xfs_get_blocks);
ret = block_page_mkwrite_return(ret);
@@ -1566,7 +1565,7 @@ xfs_filemap_pmd_fault(
file_update_time(vma->vm_file);
xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED);
ret = __dax_pmd_fault(vma, addr, pmd, flags, xfs_get_blocks_dax_fault,
- xfs_end_io_dax_write);
+ NULL);
xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED);
sb_end_pagefault(inode->i_sb);
--
2.5.0
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Dave Chinner <david@fromorbit.com> |
|---|---|
| Date | 2015-10-01 09:50 +0200 |
| Subject | [PATCH 7/7] xfs: add ->pfn_mkwrite support for DAX |
| Message-ID | <qeGMP-5IY-41@gated-at.bofh.it> |
| In reply to | #1237093 |
From: Dave Chinner <dchinner@redhat.com>
->pfn_mkwrite support is needed so that when a page with allocated
backing store takes a write fault we can check that the fault has
not raced with a truncate and is pointing to a region beyond the
current end of file.
This also allows us to update the timestamp on the inode, too, which
fixes a generic/080 failure.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
fs/xfs/xfs_file.c | 35 +++++++++++++++++++++++++++++++++++
fs/xfs/xfs_trace.h | 1 +
2 files changed, 36 insertions(+)
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 9c8eef7..f429662 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -1572,11 +1572,46 @@ xfs_filemap_pmd_fault(
return ret;
}
+/*
+ * pfn_mkwrite was originally inteneded to ensure we capture time stamp
+ * updates on write faults. In reality, it's need to serialise against
+ * truncate similar to page_mkwrite. Hence we open-code dax_pfn_mkwrite()
+ * here and cycle the XFS_MMAPLOCK_SHARED to ensure we serialise the fault
+ * barrier in place.
+ */
+static int
+xfs_filemap_pfn_mkwrite(
+ struct vm_area_struct *vma,
+ struct vm_fault *vmf)
+{
+
+ struct inode *inode = file_inode(vma->vm_file);
+ struct xfs_inode *ip = XFS_I(inode);
+ int ret = VM_FAULT_NOPAGE;
+ loff_t size;
+
+ trace_xfs_filemap_pfn_mkwrite(ip);
+
+ sb_start_pagefault(inode->i_sb);
+ file_update_time(vma->vm_file);
+
+ /* check if the faulting page hasn't raced with truncate */
+ xfs_ilock(ip, XFS_MMAPLOCK_SHARED);
+ size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ if (vmf->pgoff >= size)
+ ret = VM_FAULT_SIGBUS;
+ xfs_iunlock(ip, XFS_MMAPLOCK_SHARED);
+ sb_end_pagefault(inode->i_sb);
+ return ret;
+
+}
+
static const struct vm_operations_struct xfs_file_vm_ops = {
.fault = xfs_filemap_fault,
.pmd_fault = xfs_filemap_pmd_fault,
.map_pages = filemap_map_pages,
.page_mkwrite = xfs_filemap_page_mkwrite,
+ .pfn_mkwrite = xfs_filemap_pfn_mkwrite,
};
STATIC int
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 5ed36b1..c53beda 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -689,6 +689,7 @@ DEFINE_INODE_EVENT(xfs_inode_free_eofblocks_invalid);
DEFINE_INODE_EVENT(xfs_filemap_fault);
DEFINE_INODE_EVENT(xfs_filemap_pmd_fault);
DEFINE_INODE_EVENT(xfs_filemap_page_mkwrite);
+DEFINE_INODE_EVENT(xfs_filemap_pfn_mkwrite);
DECLARE_EVENT_CLASS(xfs_iref_class,
TP_PROTO(struct xfs_inode *ip, unsigned long caller_ip),
--
2.5.0
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Dave Chinner <david@fromorbit.com> |
|---|---|
| Date | 2015-10-01 10:00 +0200 |
| Subject | [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" |
| Message-ID | <qeGWu-5Xc-11@gated-at.bofh.it> |
| In reply to | #1237093 |
This reverts commit 46c043ede4711e8d598b9d63c5616c1fedb0605e.
---
fs/dax.c | 36 ++++++++++++++++--------------------
mm/memory.c | 11 +++++++++--
2 files changed, 25 insertions(+), 22 deletions(-)
diff --git a/fs/dax.c b/fs/dax.c
index 7ae6df7..400fe95 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -569,26 +569,6 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address,
if (!buffer_size_valid(&bh) || bh.b_size < PMD_SIZE)
goto fallback;
- if (buffer_unwritten(&bh) || buffer_new(&bh)) {
- int i;
- for (i = 0; i < PTRS_PER_PMD; i++)
- clear_pmem(kaddr + i * PAGE_SIZE, PAGE_SIZE);
- wmb_pmem();
- count_vm_event(PGMAJFAULT);
- mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT);
- result |= VM_FAULT_MAJOR;
- }
-
- /*
- * If we allocated new storage, make sure no process has any
- * zero pages covering this hole
- */
- if (buffer_new(&bh)) {
- i_mmap_unlock_write(mapping);
- unmap_mapping_range(mapping, pgoff << PAGE_SHIFT, PMD_SIZE, 0);
- i_mmap_lock_write(mapping);
- }
-
/*
* If a truncate happened while we were allocating blocks, we may
* leave blocks allocated to the file that are beyond EOF. We can't
@@ -603,6 +583,13 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address,
if ((pgoff | PG_PMD_COLOUR) >= size)
goto fallback;
+ /*
+ * If we allocated new storage, make sure no process has any
+ * zero pages covering this hole
+ */
+ if (buffer_new(&bh))
+ unmap_mapping_range(mapping, pgoff << PAGE_SHIFT, PMD_SIZE, 0);
+
if (!write && !buffer_mapped(&bh) && buffer_uptodate(&bh)) {
spinlock_t *ptl;
pmd_t entry;
@@ -633,6 +620,15 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address,
if ((length < PMD_SIZE) || (pfn & PG_PMD_COLOUR))
goto fallback;
+ if (buffer_unwritten(&bh) || buffer_new(&bh)) {
+ int i;
+ for (i = 0; i < PTRS_PER_PMD; i++)
+ clear_page(kaddr + i * PAGE_SIZE);
+ count_vm_event(PGMAJFAULT);
+ mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT);
+ result |= VM_FAULT_MAJOR;
+ }
+
result |= vmf_insert_pfn_pmd(vma, address, pmd, pfn, write);
}
diff --git a/mm/memory.c b/mm/memory.c
index 9cb2747..5ec066f 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2426,10 +2426,17 @@ void unmap_mapping_range(struct address_space *mapping,
if (details.last_index < details.first_index)
details.last_index = ULONG_MAX;
- i_mmap_lock_write(mapping);
+
+ /*
+ * DAX already holds i_mmap_lock to serialise file truncate vs
+ * page fault and page fault vs page fault.
+ */
+ if (!IS_DAX(mapping->host))
+ i_mmap_lock_write(mapping);
if (unlikely(!RB_EMPTY_ROOT(&mapping->i_mmap)))
unmap_mapping_range_tree(&mapping->i_mmap, &details);
- i_mmap_unlock_write(mapping);
+ if (!IS_DAX(mapping->host))
+ i_mmap_unlock_write(mapping);
}
EXPORT_SYMBOL(unmap_mapping_range);
--
2.5.0
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | kbuild test robot <lkp@intel.com> |
|---|---|
| Date | 2015-10-01 10:40 +0200 |
| Subject | Re: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" |
| Message-ID | <qeHzc-76i-11@gated-at.bofh.it> |
| In reply to | #1237101 |
Hi Dave,
[auto build test results on v4.3-rc3 -- if it's inappropriate base, please ignore]
reproduce:
# apt-get install sparse
make ARCH=x86_64 allmodconfig
make C=1 CF=-D__CHECK_ENDIAN__
sparse warnings: (new ones prefixed by >>)
>> fs/dax.c:626:50: sparse: incorrect type in argument 1 (different address spaces)
fs/dax.c:626:50: expected void *page
fs/dax.c:626:50: got void [noderef] <asn:5>*
vim +626 fs/dax.c
610 result = VM_FAULT_NOPAGE;
611 spin_unlock(ptl);
612 } else {
613 sector = bh.b_blocknr << (blkbits - 9);
614 length = bdev_direct_access(bh.b_bdev, sector, &kaddr, &pfn,
615 bh.b_size);
616 if (length < 0) {
617 result = VM_FAULT_SIGBUS;
618 goto out;
619 }
620 if ((length < PMD_SIZE) || (pfn & PG_PMD_COLOUR))
621 goto fallback;
622
623 if (buffer_unwritten(&bh) || buffer_new(&bh)) {
624 int i;
625 for (i = 0; i < PTRS_PER_PMD; i++)
> 626 clear_page(kaddr + i * PAGE_SIZE);
627 count_vm_event(PGMAJFAULT);
628 mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT);
629 result |= VM_FAULT_MAJOR;
630 }
631
632 result |= vmf_insert_pfn_pmd(vma, address, pmd, pfn, write);
633 }
634
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Ross Zwisler <ross.zwisler@linux.intel.com> |
|---|---|
| Date | 2015-10-01 22:30 +0200 |
| Subject | Re: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" |
| Message-ID | <qeSEh-6Qm-9@gated-at.bofh.it> |
| In reply to | #1237101 |
On Thu, Oct 01, 2015 at 05:46:33PM +1000, Dave Chinner wrote:
> This reverts commit 46c043ede4711e8d598b9d63c5616c1fedb0605e.
> ---
> fs/dax.c | 36 ++++++++++++++++--------------------
> mm/memory.c | 11 +++++++++--
> 2 files changed, 25 insertions(+), 22 deletions(-)
>
> diff --git a/fs/dax.c b/fs/dax.c
> index 7ae6df7..400fe95 100644
> --- a/fs/dax.c
> +++ b/fs/dax.c
> @@ -569,26 +569,6 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address,
> if (!buffer_size_valid(&bh) || bh.b_size < PMD_SIZE)
> goto fallback;
>
> - if (buffer_unwritten(&bh) || buffer_new(&bh)) {
> - int i;
> - for (i = 0; i < PTRS_PER_PMD; i++)
> - clear_pmem(kaddr + i * PAGE_SIZE, PAGE_SIZE);
> - wmb_pmem();
The above two lines were updated to use the PMEM API with this commit:
commit d77e92e270ed ("dax: update PMD fault handler with PMEM API")
but they aren't updated in the reverted version here:
> @@ -633,6 +620,15 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address,
> if ((length < PMD_SIZE) || (pfn & PG_PMD_COLOUR))
> goto fallback;
>
> + if (buffer_unwritten(&bh) || buffer_new(&bh)) {
> + int i;
> + for (i = 0; i < PTRS_PER_PMD; i++)
> + clear_page(kaddr + i * PAGE_SIZE);
> + count_vm_event(PGMAJFAULT);
> + mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT);
> + result |= VM_FAULT_MAJOR;
> + }
> +
> result |= vmf_insert_pfn_pmd(vma, address, pmd, pfn, write);
> }
This is the source of the follow-up sparse warning from the kbuild robot.
Also, if I understood your previous mails correctly you were targeting the
first two revert patches for v4.3 so we get back to v4.2 level locking, and
the rest of the series will target v4.4, correct? How does this work? Do the
patches need to be split into two series and tested separately?
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | "Williams, Dan J" <dan.j.williams@intel.com> |
|---|---|
| Date | 2015-10-02 00:20 +0200 |
| Subject | Re: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" |
| Message-ID | <qeUmK-12S-19@gated-at.bofh.it> |
| In reply to | #1237704 |
T24gVGh1LCAyMDE1LTEwLTAxIGF0IDE0OjI3IC0wNjAwLCBSb3NzIFp3aXNsZXIgd3JvdGU6DQo+ IE9uIFRodSwgT2N0IDAxLCAyMDE1IGF0IDA1OjQ2OjMzUE0gKzEwMDAsIERhdmUgQ2hpbm5lciB3 cm90ZToNCj4gPiBUaGlzIHJldmVydHMgY29tbWl0IDQ2YzA0M2VkZTQ3MTFlOGQ1OThiOWQ2M2M1 NjE2YzFmZWRiMDYwNWUuDQo+ID4gLS0tDQo+ID4gIGZzL2RheC5jICAgIHwgMzYgKysrKysrKysr KysrKysrKy0tLS0tLS0tLS0tLS0tLS0tLS0tDQo+ID4gIG1tL21lbW9yeS5jIHwgMTEgKysrKysr KysrLS0NCj4gPiAgMiBmaWxlcyBjaGFuZ2VkLCAyNSBpbnNlcnRpb25zKCspLCAyMiBkZWxldGlv bnMoLSkNCj4gPiANCj4gPiBkaWZmIC0tZ2l0IGEvZnMvZGF4LmMgYi9mcy9kYXguYw0KPiA+IGlu ZGV4IDdhZTZkZjcuLjQwMGZlOTUgMTAwNjQ0DQo+ID4gLS0tIGEvZnMvZGF4LmMNCj4gPiArKysg Yi9mcy9kYXguYw0KPiA+IEBAIC01NjksMjYgKzU2OSw2IEBAIGludCBfX2RheF9wbWRfZmF1bHQo c3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEsIHVuc2lnbmVkIGxvbmcgYWRkcmVzcywNCj4gPiAg CWlmICghYnVmZmVyX3NpemVfdmFsaWQoJmJoKSB8fCBiaC5iX3NpemUgPCBQTURfU0laRSkNCj4g PiAgCQlnb3RvIGZhbGxiYWNrOw0KPiA+ICANCj4gPiAtCWlmIChidWZmZXJfdW53cml0dGVuKCZi aCkgfHwgYnVmZmVyX25ldygmYmgpKSB7DQo+ID4gLQkJaW50IGk7DQo+ID4gLQkJZm9yIChpID0g MDsgaSA8IFBUUlNfUEVSX1BNRDsgaSsrKQ0KPiA+IC0JCQljbGVhcl9wbWVtKGthZGRyICsgaSAq IFBBR0VfU0laRSwgUEFHRV9TSVpFKTsNCj4gPiAtCQl3bWJfcG1lbSgpOw0KPiANCj4gVGhlIGFi b3ZlIHR3byBsaW5lcyB3ZXJlIHVwZGF0ZWQgdG8gdXNlIHRoZSBQTUVNIEFQSSB3aXRoIHRoaXMg Y29tbWl0Og0KPiANCj4gY29tbWl0IGQ3N2U5MmUyNzBlZCAoImRheDogdXBkYXRlIFBNRCBmYXVs dCBoYW5kbGVyIHdpdGggUE1FTSBBUEkiKQ0KPiANCj4gYnV0IHRoZXkgYXJlbid0IHVwZGF0ZWQg aW4gdGhlIHJldmVydGVkIHZlcnNpb24gaGVyZTogDQo+IA0KPiA+IEBAIC02MzMsNiArNjIwLDE1 IEBAIGludCBfX2RheF9wbWRfZmF1bHQoc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEsIHVuc2ln bmVkIGxvbmcgYWRkcmVzcywNCj4gPiAgCQlpZiAoKGxlbmd0aCA8IFBNRF9TSVpFKSB8fCAocGZu ICYgUEdfUE1EX0NPTE9VUikpDQo+ID4gIAkJCWdvdG8gZmFsbGJhY2s7DQo+ID4gIA0KPiA+ICsJ CWlmIChidWZmZXJfdW53cml0dGVuKCZiaCkgfHwgYnVmZmVyX25ldygmYmgpKSB7DQo+ID4gKwkJ CWludCBpOw0KPiA+ICsJCQlmb3IgKGkgPSAwOyBpIDwgUFRSU19QRVJfUE1EOyBpKyspDQo+ID4g KwkJCQljbGVhcl9wYWdlKGthZGRyICsgaSAqIFBBR0VfU0laRSk7DQo+ID4gKwkJCWNvdW50X3Zt X2V2ZW50KFBHTUFKRkFVTFQpOw0KPiA+ICsJCQltZW1fY2dyb3VwX2NvdW50X3ZtX2V2ZW50KHZt YS0+dm1fbW0sIFBHTUFKRkFVTFQpOw0KPiA+ICsJCQlyZXN1bHQgfD0gVk1fRkFVTFRfTUFKT1I7 DQo+ID4gKwkJfQ0KPiA+ICsNCj4gPiAgCQlyZXN1bHQgfD0gdm1mX2luc2VydF9wZm5fcG1kKHZt YSwgYWRkcmVzcywgcG1kLCBwZm4sIHdyaXRlKTsNCj4gPiAgCX0NCj4gDQo+IFRoaXMgaXMgdGhl IHNvdXJjZSBvZiB0aGUgZm9sbG93LXVwIHNwYXJzZSB3YXJuaW5nIGZyb20gdGhlIGtidWlsZCBy b2JvdC4NCj4gDQoNClRvIHRoYXQgZW5kIERhdmUgSGFuc2VuIGhhZCBhbHNvIG5vdGljZWQgdGhh dCBQVFJTX1BFUl9QTUQgc2hvdWxkIG5vdCBiZQ0KdXNlZCBpbiB0aGlzIGNvbnRleHQuICBIZXJl J3MgYW4gaW5jcmVtZW50YWwgY2xlYW51cDoNCg0KODwtLS0NClN1YmplY3Q6IHBtZW0sIGRheDog Y2xlYW4gdXAgY2xlYXJfcG1lbSgpDQoNCkZyb206IERhbiBXaWxsaWFtcyA8ZGFuLmoud2lsbGlh bXNAaW50ZWwuY29tPg0KDQpCb3RoLCBfX2RheF9wbWRfZmF1bHQsIGFuZCBjbGVhcl9wbWVtKCkg d2VyZSB0YWtpbmcgc3BlY2lhbCBzdGVwcyB0bw0KY2xlYXIgbWVtb3J5IGEgcGFnZSBhdCBhIHRp bWUgdG8gdGFrZSBhZHZhbnRhZ2Ugb2Ygbm9uLXRlbXBvcmFsDQpjbGVhcl9wYWdlKCkgaW1wbGVt ZW50YXRpb25zLiAgSG93ZXZlciwgeDg2XzY0IGRvZXMgbm90IHVzZQ0Kbm9uLXRlbXBvcmFsIGlu c3RydWN0aW9ucyBmb3IgY2xlYXJfcGFnZSgpLCBhbmQgYXJjaF9jbGVhcl9wbWVtKCkgd2FzDQph bHdheXMgaW5jdXJyaW5nIHRoZSBjb3N0IG9mIF9fYXJjaF93Yl9jYWNoZV9wbWVtKCkuDQoNCkNs ZWFuIHVwIHRoZSBhc3N1bXB0aW9uIHRoYXQgZG9pbmcgY2xlYXJfcG1lbSgpIGEgcGFnZSBhdCBh IHRpbWUgaXMgbW9yZQ0KcGVyZm9ybWFudC4NCg0KQ2M6IFJvc3MgWndpc2xlciA8cm9zcy56d2lz bGVyQGxpbnV4LmludGVsLmNvbT4NClJlcG9ydGVkLWJ5OiBEYXZlIEhhbnNlbiA8ZGF2ZS5oYW5z ZW5AbGludXguaW50ZWwuY29tPg0KU2lnbmVkLW9mZi1ieTogRGFuIFdpbGxpYW1zIDxkYW4uai53 aWxsaWFtc0BpbnRlbC5jb20+DQotLS0NCiBhcmNoL3g4Ni9pbmNsdWRlL2FzbS9wbWVtLmggfCAg ICA3ICstLS0tLS0NCiBmcy9kYXguYyAgICAgICAgICAgICAgICAgICAgfCAgICA0ICstLS0NCiAy IGZpbGVzIGNoYW5nZWQsIDIgaW5zZXJ0aW9ucygrKSwgOSBkZWxldGlvbnMoLSkNCg0KZGlmZiAt LWdpdCBhL2FyY2gveDg2L2luY2x1ZGUvYXNtL3BtZW0uaCBiL2FyY2gveDg2L2luY2x1ZGUvYXNt L3BtZW0uaA0KaW5kZXggZDhjZTNlYzgxNmFiLi4xNTQ0ZmFiY2Q3ZjkgMTAwNjQ0DQotLS0gYS9h cmNoL3g4Ni9pbmNsdWRlL2FzbS9wbWVtLmgNCisrKyBiL2FyY2gveDg2L2luY2x1ZGUvYXNtL3Bt ZW0uaA0KQEAgLTEzMiwxMiArMTMyLDcgQEAgc3RhdGljIGlubGluZSB2b2lkIGFyY2hfY2xlYXJf cG1lbSh2b2lkIF9fcG1lbSAqYWRkciwgc2l6ZV90IHNpemUpDQogew0KIAl2b2lkICp2YWRkciA9 ICh2b2lkIF9fZm9yY2UgKilhZGRyOw0KIA0KLQkvKiBUT0RPOiBpbXBsZW1lbnQgdGhlIHplcm9p bmcgdmlhIG5vbi10ZW1wb3JhbCB3cml0ZXMgKi8NCi0JaWYgKHNpemUgPT0gUEFHRV9TSVpFICYm ICgodW5zaWduZWQgbG9uZyl2YWRkciAmIH5QQUdFX01BU0spID09IDApDQotCQljbGVhcl9wYWdl KHZhZGRyKTsNCi0JZWxzZQ0KLQkJbWVtc2V0KHZhZGRyLCAwLCBzaXplKTsNCi0NCisJbWVtc2V0 KHZhZGRyLCAwLCBzaXplKTsNCiAJX19hcmNoX3diX2NhY2hlX3BtZW0odmFkZHIsIHNpemUpOw0K IH0NCiANCmRpZmYgLS1naXQgYS9mcy9kYXguYyBiL2ZzL2RheC5jDQppbmRleCBiMzZkNmQyZTdm ODcuLjNmYWZmOTIyNzEzNSAxMDA2NDQNCi0tLSBhL2ZzL2RheC5jDQorKysgYi9mcy9kYXguYw0K QEAgLTYyNSw5ICs2MjUsNyBAQCBpbnQgX19kYXhfcG1kX2ZhdWx0KHN0cnVjdCB2bV9hcmVhX3N0 cnVjdCAqdm1hLCB1bnNpZ25lZCBsb25nIGFkZHJlc3MsDQogCQkJZ290byBmYWxsYmFjazsNCiAN CiAJCWlmIChidWZmZXJfdW53cml0dGVuKCZiaCkgfHwgYnVmZmVyX25ldygmYmgpKSB7DQotCQkJ aW50IGk7DQotCQkJZm9yIChpID0gMDsgaSA8IFBUUlNfUEVSX1BNRDsgaSsrKQ0KLQkJCQljbGVh cl9wYWdlKGthZGRyICsgaSAqIFBBR0VfU0laRSk7DQorCQkJY2xlYXJfcG1lbShrYWRkciwgSFBB R0VfU0laRSk7DQogCQkJY291bnRfdm1fZXZlbnQoUEdNQUpGQVVMVCk7DQogCQkJbWVtX2Nncm91 cF9jb3VudF92bV9ldmVudCh2bWEtPnZtX21tLCBQR01BSkZBVUxUKTsNCiAJCQlyZXN1bHQgfD0g Vk1fRkFVTFRfTUFKT1I7DQoNCg== -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Ross Zwisler <ross.zwisler@linux.intel.com> |
|---|---|
| Date | 2015-10-02 00:50 +0200 |
| Subject | Re: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" |
| Message-ID | <qeUPM-1B8-31@gated-at.bofh.it> |
| In reply to | #1237784 |
On Thu, Oct 01, 2015 at 10:14:22PM +0000, Williams, Dan J wrote:
> Subject: pmem, dax: clean up clear_pmem()
>
> From: Dan Williams <dan.j.williams@intel.com>
>
> Both, __dax_pmd_fault, and clear_pmem() were taking special steps to
> clear memory a page at a time to take advantage of non-temporal
> clear_page() implementations. However, x86_64 does not use
> non-temporal instructions for clear_page(), and arch_clear_pmem() was
> always incurring the cost of __arch_wb_cache_pmem().
>
> Clean up the assumption that doing clear_pmem() a page at a time is more
> performant.
>
> Cc: Ross Zwisler <ross.zwisler@linux.intel.com>
> Reported-by: Dave Hansen <dave.hansen@linux.intel.com>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
> ---
> arch/x86/include/asm/pmem.h | 7 +------
> fs/dax.c | 4 +---
> 2 files changed, 2 insertions(+), 9 deletions(-)
>
> diff --git a/arch/x86/include/asm/pmem.h b/arch/x86/include/asm/pmem.h
> index d8ce3ec816ab..1544fabcd7f9 100644
> --- a/arch/x86/include/asm/pmem.h
> +++ b/arch/x86/include/asm/pmem.h
> @@ -132,12 +132,7 @@ static inline void arch_clear_pmem(void __pmem *addr, size_t size)
> {
> void *vaddr = (void __force *)addr;
>
> - /* TODO: implement the zeroing via non-temporal writes */
> - if (size == PAGE_SIZE && ((unsigned long)vaddr & ~PAGE_MASK) == 0)
> - clear_page(vaddr);
> - else
> - memset(vaddr, 0, size);
> -
> + memset(vaddr, 0, size);
> __arch_wb_cache_pmem(vaddr, size);
> }
>
> diff --git a/fs/dax.c b/fs/dax.c
> index b36d6d2e7f87..3faff9227135 100644
> --- a/fs/dax.c
> +++ b/fs/dax.c
> @@ -625,9 +625,7 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address,
> goto fallback;
>
> if (buffer_unwritten(&bh) || buffer_new(&bh)) {
> - int i;
> - for (i = 0; i < PTRS_PER_PMD; i++)
> - clear_page(kaddr + i * PAGE_SIZE);
> + clear_pmem(kaddr, HPAGE_SIZE);
> count_vm_event(PGMAJFAULT);
> mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT);
> result |= VM_FAULT_MAJOR;
>
This clear_pmem() needs a wmb_pmem() after it. I'll make a quick series with
the clean revert and this guy at the end and try and get them in v4.3 - sound
good?
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Dave Chinner <david@fromorbit.com> |
|---|---|
| Date | 2015-10-02 00:40 +0200 |
| Subject | Re: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" |
| Message-ID | <qeUG6-1pD-17@gated-at.bofh.it> |
| In reply to | #1237704 |
On Thu, Oct 01, 2015 at 02:27:29PM -0600, Ross Zwisler wrote:
> On Thu, Oct 01, 2015 at 05:46:33PM +1000, Dave Chinner wrote:
> > This reverts commit 46c043ede4711e8d598b9d63c5616c1fedb0605e.
> > ---
> > fs/dax.c | 36 ++++++++++++++++--------------------
> > mm/memory.c | 11 +++++++++--
> > 2 files changed, 25 insertions(+), 22 deletions(-)
> >
> > diff --git a/fs/dax.c b/fs/dax.c
> > index 7ae6df7..400fe95 100644
> > --- a/fs/dax.c
> > +++ b/fs/dax.c
> > @@ -569,26 +569,6 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address,
> > if (!buffer_size_valid(&bh) || bh.b_size < PMD_SIZE)
> > goto fallback;
> >
> > - if (buffer_unwritten(&bh) || buffer_new(&bh)) {
> > - int i;
> > - for (i = 0; i < PTRS_PER_PMD; i++)
> > - clear_pmem(kaddr + i * PAGE_SIZE, PAGE_SIZE);
> > - wmb_pmem();
>
> The above two lines were updated to use the PMEM API with this commit:
>
> commit d77e92e270ed ("dax: update PMD fault handler with PMEM API")
>
> but they aren't updated in the reverted version here:
>
> > @@ -633,6 +620,15 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address,
> > if ((length < PMD_SIZE) || (pfn & PG_PMD_COLOUR))
> > goto fallback;
> >
> > + if (buffer_unwritten(&bh) || buffer_new(&bh)) {
> > + int i;
> > + for (i = 0; i < PTRS_PER_PMD; i++)
> > + clear_page(kaddr + i * PAGE_SIZE);
> > + count_vm_event(PGMAJFAULT);
> > + mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT);
> > + result |= VM_FAULT_MAJOR;
> > + }
> > +
> > result |= vmf_insert_pfn_pmd(vma, address, pmd, pfn, write);
> > }
>
> This is the source of the follow-up sparse warning from the kbuild robot.
I couldn't work out what set of commits I needed to revert to get a
clean revert, so I just reverted the commits and hacked out the
revert failures to what looked ok. Feel free to send me a clean set
of reverts, and I'll replace these patches with them... :)
> Also, if I understood your previous mails correctly you were targeting the
> first two revert patches for v4.3 so we get back to v4.2 level locking, and
> the rest of the series will target v4.4, correct? How does this work? Do the
> patches need to be split into two series and tested separately?
Test it and push the reverts however you like. I don't care how the
reverts get to 4.3 - I'll be carrying them locally in my trees from
now and so my development and testing is now unaffected by the bugs
that are in the 4.3 code. If you aren't going to push them for 4.3
then I'd suggest that they go to linus along with the rest of the
XFS changes in this series.
FWIW, I'm quite happy to host all the pending DAX changes in a
public git tree and ask for it to be included in linux-next. It's
probably a good idea to do this because it makes it much easier to
co-ordinate merges when we are touching multiple subsystems (ext4,
xfs, dax, mm, etc). And it will help prevent the "patches molder on
the list until Andrew hoovers them up" problem and so prevent this
situation from happening in the future...
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Ross Zwisler <ross.zwisler@linux.intel.com> |
|---|---|
| Date | 2015-10-02 00:50 +0200 |
| Subject | Re: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" |
| Message-ID | <qeUPM-1B8-25@gated-at.bofh.it> |
| In reply to | #1237803 |
On Fri, Oct 02, 2015 at 08:32:40AM +1000, Dave Chinner wrote: > I couldn't work out what set of commits I needed to revert to get a > clean revert, so I just reverted the commits and hacked out the > revert failures to what looked ok. Feel free to send me a clean set > of reverts, and I'll replace these patches with them... :) Will do. I will queue the reverts in my external tree & ask Linus to pull them into v4.3 so we don't ship with deadlocks. > > Also, if I understood your previous mails correctly you were targeting the > > first two revert patches for v4.3 so we get back to v4.2 level locking, and > > the rest of the series will target v4.4, correct? How does this work? Do the > > patches need to be split into two series and tested separately? > > Test it and push the reverts however you like. I don't care how the > reverts get to 4.3 - I'll be carrying them locally in my trees from > now and so my development and testing is now unaffected by the bugs > that are in the 4.3 code. If you aren't going to push them for 4.3 > then I'd suggest that they go to linus along with the rest of the > XFS changes in this series. > > FWIW, I'm quite happy to host all the pending DAX changes in a > public git tree and ask for it to be included in linux-next. It's > probably a good idea to do this because it makes it much easier to > co-ordinate merges when we are touching multiple subsystems (ext4, > xfs, dax, mm, etc). And it will help prevent the "patches molder on > the list until Andrew hoovers them up" problem and so prevent this > situation from happening in the future... No objections from me. :) I agree that it would be nice to have a central home for all the DAX patches. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Ross Zwisler <ross.zwisler@linux.intel.com> |
|---|---|
| Date | 2015-10-01 22:40 +0200 |
| Message-ID | <qeSNX-71t-13@gated-at.bofh.it> |
| In reply to | #1237093 |
On Thu, Oct 01, 2015 at 05:46:32PM +1000, Dave Chinner wrote: > Hi folks, > > As discussed in the recent thread about problems with DAX locking: > > http://www.gossamer-threads.com/lists/linux/kernel/2264090?do=post_view_threaded > > I said that I'd post the patch set that fixed the problems for XFS > as soon as I had something sane and workable. That's what this > series is. > > To start with, it passes xfstests "auto" group with only the only > failures being expected failures or failures due to unexpected > allocation patterns or trying to use unsupported block sizes. That > makes it better than any previous version of the XFS/DAX code. > > The patchset starts by reverting the two patches that were > introduced in 4.3-rc1 to try to fix the fault vs fault and fault vs > truncate races that caused deadlocks. This fixes the hangs in > generic/075 that these patches introduced. > > Patch 3 enables XFS to handle the behaviour of DAX and DIO when > asking to allocate the block at (2^63 - 1FSB), where the offset + > count s technically illegal (larger than sb->s_maxbytes) and > overflows a s64 variable. This is currently hidden by the fact that > all DAX and DIO allocation is currently unwritten, but patch 5 > exposes it for DAX. > > Patch 4 introduces the ability for XFS to allocate physically zeroed > data blocks. This is done for each physical extent that is > allocated, deep inside the allocator itself and guaranteed to be > atomic with the allocation transaction and hence has no > crash+recovery exposure issues. > > This is necessary because the BMAPI layer merges allocated extents > in the BMBT before it returns the mapped extent back to the high > level get_blocks() code. Hence the high level code can have a single > extent presented that is made of merged new and existing extents, > and so zeroing can't be done at this layer. > > The advantage of driving the zeroing deep into the allocator is the > functionality is now available to all XFS code. Hence we can > allocate pre-zeroed blocks on any type of storage, and we can > utilise storage-based hardware acceleration (e.g. discard to zero, > WRITE_SAME, etc) to do the zeroing. From this POV, DAX is just > another hardware accelerated physical zeroing mechanism for XFS. :) > > [ This is an example of the mantra I repeat a lot: solve the problem > properly the first time and it will make everything simpler! Sure, > it took me three attempts to work out how to solve it in a sane > manner, but that's pretty much par for the course with anything > non-trivial. ] > > Patch 5 makes __xfs_get_blocks() aware that it is being called from > the DAX fault path and makes sure it returns zeroed blocks rather > than unwritten extents via XFS_BMAPI_ZERO. It also now sets > XFS_BMAPI_CONVERT, which tells it to convert unwritten extents to > written, zeroed blocks. This is the major change of behaviour. > > Patch 6 removes the IO completion callbacks from the XFS DAX code as > they are not longer necessary after patch 5. > > Patch 7 adds pfn_mkwrite support to XFS. This is needed to fix > generic/080, which detects a failure to update the inode timestamp > on a pfn fault. It also adds the same locking as the XFS > implementation of ->fault and ->page_mkwrite and hence provide > correct serialisation against truncate, hole punching, etc that > doesn't currently exist. > > The next steps that are needed are to do the same "block zeroing > during allocation" to ext4, and then the block zeroing and > complete_unwritten callbacks can be removed from the DAX API and > code. I've had a breif look at the ext4 code - the block zeroing > should be able to be done by overloading the existing zeroout code > that ext4 has in the unwritten extent allocation code. I'd much > prefer that an ext4 expert does this work, and then we can clean up > the DAX code... Thank you for working on this, and for documenting your thinking so clearly. One thing I noticed is that in my test setup XFS+DAX is now failing generic/274: # diff -u tests/generic/274.out /root/xfstests/results//generic/274.out.bad --- tests/generic/274.out 2015-08-24 11:05:41.490926305 -0600 +++ /root/xfstests/results//generic/274.out.bad 2015-10-01 13:53:50.498354091 -0600 @@ -2,4 +2,5 @@ ------------------------------ preallocation test ------------------------------ -done +failed to write to test file +(see /root/xfstests/results//generic/274.full for details) I've verified that the test passes 100% of the time with my baseline (v4.3-rc3), and with the set applied but without the DAX mount option. With the series and with DAX it fails 100% of the time. I haven't looked into the details of the failure yet, I just wanted to let you know that it was happening. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Dave Chinner <david@fromorbit.com> |
|---|---|
| Date | 2015-10-02 01:00 +0200 |
| Message-ID | <qeUZs-1Mq-19@gated-at.bofh.it> |
| In reply to | #1237709 |
On Thu, Oct 01, 2015 at 02:31:21PM -0600, Ross Zwisler wrote: > On Thu, Oct 01, 2015 at 05:46:32PM +1000, Dave Chinner wrote: > > Hi folks, > > > > As discussed in the recent thread about problems with DAX locking: > > > > http://www.gossamer-threads.com/lists/linux/kernel/2264090?do=post_view_threaded > > > > I said that I'd post the patch set that fixed the problems for XFS > > as soon as I had something sane and workable. That's what this > > series is. > > > > To start with, it passes xfstests "auto" group with only the only > > failures being expected failures or failures due to unexpected > > allocation patterns or trying to use unsupported block sizes. That > > makes it better than any previous version of the XFS/DAX code. ..... > Thank you for working on this, and for documenting your thinking so clearly. To put this in perspective, "patch 0" descriptions like this is a requirement for any non-trivial XFS modification. It saves reviewers so much time and many round trips in email and IRC to understand the changes being proposed that it's a no-brainer. Lead by example, and all that... > One thing I noticed is that in my test setup XFS+DAX is now failing > generic/274: > > # diff -u tests/generic/274.out /root/xfstests/results//generic/274.out.bad > --- tests/generic/274.out 2015-08-24 11:05:41.490926305 -0600 > +++ /root/xfstests/results//generic/274.out.bad 2015-10-01 13:53:50.498354091 -0600 > @@ -2,4 +2,5 @@ > ------------------------------ > preallocation test > ------------------------------ > -done > +failed to write to test file > +(see /root/xfstests/results//generic/274.full for details) > > I've verified that the test passes 100% of the time with my baseline > (v4.3-rc3), and with the set applied but without the DAX mount option. With > the series and with DAX it fails 100% of the time. I haven't looked into the > details of the failure yet, I just wanted to let you know that it was > happening. See above - I classified this under the "failures due to unexpected allocation patterns". This is a ENOSPC test, and we've change the allocation pattern and the unwritten extent conversion algorithm and so changed the metadata allocation demand of the test. I haven't looked any further than this yet, but I suspect the issue is that the up-front unwritten extent conversion is not being allowed to dip into the reserve block pool for BMBT allocations when the extent list grows past a single block. If that's the case, then it's a couple of lines of code to conditionally at XFS_TRANS_RESERVE to the transaction handle to allow it access to the reserve pool... Cheers, Dave. -- Dave Chinner david@fromorbit.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web