2022-04-11 18:09:14

by Shiyang Ruan

[permalink] [raw]
Subject: [PATCH v12 6/7] xfs: Implement ->notify_failure() for XFS

Introduce xfs_notify_failure.c to handle failure related works, such as
implement ->notify_failure(), register/unregister dax holder in xfs, and
so on.

If the rmap feature of XFS enabled, we can query it to find files and
metadata which are associated with the corrupt data. For now all we do
is kill processes with that file mapped into their address spaces, but
future patches could actually do something about corrupt metadata.

After that, the memory failure needs to notify the processes who are
using those files.

Signed-off-by: Shiyang Ruan <[email protected]>
---
fs/xfs/Makefile | 5 +
fs/xfs/xfs_buf.c | 7 +-
fs/xfs/xfs_fsops.c | 3 +
fs/xfs/xfs_mount.h | 1 +
fs/xfs/xfs_notify_failure.c | 219 ++++++++++++++++++++++++++++++++++++
fs/xfs/xfs_super.h | 1 +
6 files changed, 233 insertions(+), 3 deletions(-)
create mode 100644 fs/xfs/xfs_notify_failure.c

diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
index 04611a1068b4..09f5560e29f2 100644
--- a/fs/xfs/Makefile
+++ b/fs/xfs/Makefile
@@ -128,6 +128,11 @@ xfs-$(CONFIG_SYSCTL) += xfs_sysctl.o
xfs-$(CONFIG_COMPAT) += xfs_ioctl32.o
xfs-$(CONFIG_EXPORTFS_BLOCK_OPS) += xfs_pnfs.o

+# notify failure
+ifeq ($(CONFIG_MEMORY_FAILURE),y)
+xfs-$(CONFIG_FS_DAX) += xfs_notify_failure.o
+endif
+
# online scrub/repair
ifeq ($(CONFIG_XFS_ONLINE_SCRUB),y)

diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index f9ca08398d32..9064b8dfbc66 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -5,6 +5,7 @@
*/
#include "xfs.h"
#include <linux/backing-dev.h>
+#include <linux/dax.h>

#include "xfs_shared.h"
#include "xfs_format.h"
@@ -1911,7 +1912,7 @@ xfs_free_buftarg(
list_lru_destroy(&btp->bt_lru);

blkdev_issue_flush(btp->bt_bdev);
- fs_put_dax(btp->bt_daxdev, NULL);
+ fs_put_dax(btp->bt_daxdev, btp->bt_mount);

kmem_free(btp);
}
@@ -1964,8 +1965,8 @@ xfs_alloc_buftarg(
btp->bt_mount = mp;
btp->bt_dev = bdev->bd_dev;
btp->bt_bdev = bdev;
- btp->bt_daxdev = fs_dax_get_by_bdev(bdev, &btp->bt_dax_part_off, NULL,
- NULL);
+ btp->bt_daxdev = fs_dax_get_by_bdev(bdev, &btp->bt_dax_part_off, mp,
+ &xfs_dax_holder_operations);

/*
* Buffer IO error rate limiting. Limit it to no more than 10 messages
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 68f74549fa22..56530900bb86 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -536,6 +536,9 @@ xfs_do_force_shutdown(
} else if (flags & SHUTDOWN_CORRUPT_INCORE) {
tag = XFS_PTAG_SHUTDOWN_CORRUPT;
why = "Corruption of in-memory data";
+ } else if (flags & SHUTDOWN_CORRUPT_ONDISK) {
+ tag = XFS_PTAG_SHUTDOWN_CORRUPT;
+ why = "Corruption of on-disk metadata";
} else {
tag = XFS_PTAG_SHUTDOWN_IOERROR;
why = "Metadata I/O Error";
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index f6dc19de8322..9237cc159542 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -435,6 +435,7 @@ void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname,
#define SHUTDOWN_LOG_IO_ERROR 0x0002 /* write attempt to the log failed */
#define SHUTDOWN_FORCE_UMOUNT 0x0004 /* shutdown from a forced unmount */
#define SHUTDOWN_CORRUPT_INCORE 0x0008 /* corrupt in-memory data structures */
+#define SHUTDOWN_CORRUPT_ONDISK 0x0010 /* corrupt metadata on device */

#define XFS_SHUTDOWN_STRINGS \
{ SHUTDOWN_META_IO_ERROR, "metadata_io" }, \
diff --git a/fs/xfs/xfs_notify_failure.c b/fs/xfs/xfs_notify_failure.c
new file mode 100644
index 000000000000..aac44f54feb4
--- /dev/null
+++ b/fs/xfs/xfs_notify_failure.c
@@ -0,0 +1,219 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 Fujitsu. All Rights Reserved.
+ */
+
+#include "xfs.h"
+#include "xfs_shared.h"
+#include "xfs_format.h"
+#include "xfs_log_format.h"
+#include "xfs_trans_resv.h"
+#include "xfs_mount.h"
+#include "xfs_alloc.h"
+#include "xfs_bit.h"
+#include "xfs_btree.h"
+#include "xfs_inode.h"
+#include "xfs_icache.h"
+#include "xfs_rmap.h"
+#include "xfs_rmap_btree.h"
+#include "xfs_rtalloc.h"
+#include "xfs_trans.h"
+
+#include <linux/mm.h>
+#include <linux/dax.h>
+
+struct failure_info {
+ xfs_agblock_t startblock;
+ xfs_extlen_t blockcount;
+ int mf_flags;
+};
+
+static pgoff_t
+xfs_failure_pgoff(
+ struct xfs_mount *mp,
+ const struct xfs_rmap_irec *rec,
+ const struct failure_info *notify)
+{
+ uint64_t pos = rec->rm_offset;
+
+ if (notify->startblock > rec->rm_startblock)
+ pos += XFS_FSB_TO_B(mp,
+ notify->startblock - rec->rm_startblock);
+ return pos >> PAGE_SHIFT;
+}
+
+static unsigned long
+xfs_failure_pgcnt(
+ struct xfs_mount *mp,
+ const struct xfs_rmap_irec *rec,
+ const struct failure_info *notify)
+{
+ xfs_agblock_t end_rec;
+ xfs_agblock_t end_notify;
+ xfs_agblock_t start_cross;
+ xfs_agblock_t end_cross;
+
+ start_cross = max(rec->rm_startblock, notify->startblock);
+
+ end_rec = rec->rm_startblock + rec->rm_blockcount;
+ end_notify = notify->startblock + notify->blockcount;
+ end_cross = min(end_rec, end_notify);
+
+ return XFS_FSB_TO_B(mp, end_cross - start_cross) >> PAGE_SHIFT;
+}
+
+static int
+xfs_dax_failure_fn(
+ struct xfs_btree_cur *cur,
+ const struct xfs_rmap_irec *rec,
+ void *data)
+{
+ struct xfs_mount *mp = cur->bc_mp;
+ struct xfs_inode *ip;
+ struct failure_info *notify = data;
+ int error = 0;
+
+ if (XFS_RMAP_NON_INODE_OWNER(rec->rm_owner) ||
+ (rec->rm_flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK))) {
+ xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_ONDISK);
+ return -EFSCORRUPTED;
+ }
+
+ /* Get files that incore, filter out others that are not in use. */
+ error = xfs_iget(mp, cur->bc_tp, rec->rm_owner, XFS_IGET_INCORE,
+ 0, &ip);
+ /* Continue the rmap query if the inode isn't incore */
+ if (error == -ENODATA)
+ return 0;
+ if (error)
+ return error;
+
+ error = mf_dax_kill_procs(VFS_I(ip)->i_mapping,
+ xfs_failure_pgoff(mp, rec, notify),
+ xfs_failure_pgcnt(mp, rec, notify),
+ notify->mf_flags);
+ xfs_irele(ip);
+ return error;
+}
+
+static int
+xfs_dax_notify_ddev_failure(
+ struct xfs_mount *mp,
+ xfs_daddr_t daddr,
+ xfs_daddr_t bblen,
+ int mf_flags)
+{
+ struct xfs_trans *tp = NULL;
+ struct xfs_btree_cur *cur = NULL;
+ struct xfs_buf *agf_bp = NULL;
+ int error = 0;
+ xfs_fsblock_t fsbno = XFS_DADDR_TO_FSB(mp, daddr);
+ xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, fsbno);
+ xfs_fsblock_t end_fsbno = XFS_DADDR_TO_FSB(mp, daddr + bblen);
+ xfs_agnumber_t end_agno = XFS_FSB_TO_AGNO(mp, end_fsbno);
+
+ error = xfs_trans_alloc_empty(mp, &tp);
+ if (error)
+ return error;
+
+ for (; agno <= end_agno; agno++) {
+ struct xfs_rmap_irec ri_low = { };
+ struct xfs_rmap_irec ri_high;
+ struct failure_info notify;
+ struct xfs_agf *agf;
+ xfs_agblock_t agend;
+
+ error = xfs_alloc_read_agf(mp, tp, agno, 0, &agf_bp);
+ if (error)
+ break;
+
+ cur = xfs_rmapbt_init_cursor(mp, tp, agf_bp, agf_bp->b_pag);
+
+ /*
+ * Set the rmap range from ri_low to ri_high, which represents
+ * a [start, end] where we looking for the files or metadata.
+ * The part of range out of a AG will be ignored. So, it's fine
+ * to set ri_low to "startblock" in all loops. When it reaches
+ * the last AG, set the ri_high to "endblock" to make sure we
+ * actually end at the end.
+ */
+ memset(&ri_high, 0xFF, sizeof(ri_high));
+ ri_low.rm_startblock = XFS_FSB_TO_AGBNO(mp, fsbno);
+ if (agno == end_agno)
+ ri_high.rm_startblock = XFS_FSB_TO_AGBNO(mp, end_fsbno);
+
+ agf = agf_bp->b_addr;
+ agend = min(be32_to_cpu(agf->agf_length),
+ ri_high.rm_startblock);
+ notify.startblock = ri_low.rm_startblock;
+ notify.blockcount = agend - ri_low.rm_startblock;
+
+ error = xfs_rmap_query_range(cur, &ri_low, &ri_high,
+ xfs_dax_failure_fn, &notify);
+ xfs_btree_del_cursor(cur, error);
+ xfs_trans_brelse(tp, agf_bp);
+ if (error)
+ break;
+
+ fsbno = XFS_AGB_TO_FSB(mp, agno + 1, 0);
+ }
+
+ xfs_trans_cancel(tp);
+ return error;
+}
+
+static int
+xfs_dax_notify_failure(
+ struct dax_device *dax_dev,
+ u64 offset,
+ u64 len,
+ int mf_flags)
+{
+ struct xfs_mount *mp = dax_holder(dax_dev);
+ u64 ddev_start;
+ u64 ddev_end;
+
+ if (mp->m_rtdev_targp && mp->m_rtdev_targp->bt_daxdev == dax_dev) {
+ xfs_warn(mp,
+ "notify_failure() not supported on realtime device!");
+ return -EOPNOTSUPP;
+ }
+
+ if (mp->m_logdev_targp && mp->m_logdev_targp->bt_daxdev == dax_dev &&
+ mp->m_logdev_targp != mp->m_ddev_targp) {
+ xfs_err(mp, "ondisk log corrupt, shutting down fs!");
+ xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_ONDISK);
+ return -EFSCORRUPTED;
+ }
+
+ if (!xfs_has_rmapbt(mp)) {
+ xfs_warn(mp, "notify_failure() needs rmapbt enabled!");
+ return -EOPNOTSUPP;
+ }
+
+ ddev_start = mp->m_ddev_targp->bt_dax_part_off;
+ ddev_end = ddev_start + bdev_nr_bytes(mp->m_ddev_targp->bt_bdev) - 1;
+
+ /* Ignore the range out of filesystem area */
+ if (offset + len < ddev_start)
+ return -ENXIO;
+ if (offset > ddev_end)
+ return -ENXIO;
+
+ /* Calculate the real range when it touches the boundary */
+ if (offset > ddev_start)
+ offset -= ddev_start;
+ else {
+ len -= ddev_start - offset;
+ offset = 0;
+ }
+ if (offset + len > ddev_end)
+ len -= ddev_end - offset;
+
+ return xfs_dax_notify_ddev_failure(mp, BTOBB(offset), BTOBB(len),
+ mf_flags);
+}
+
+const struct dax_holder_operations xfs_dax_holder_operations = {
+ .notify_failure = xfs_dax_notify_failure,
+};
diff --git a/fs/xfs/xfs_super.h b/fs/xfs/xfs_super.h
index 167d23f92ffe..27ab5087d0b3 100644
--- a/fs/xfs/xfs_super.h
+++ b/fs/xfs/xfs_super.h
@@ -93,6 +93,7 @@ extern xfs_agnumber_t xfs_set_inode_alloc(struct xfs_mount *,
extern const struct export_operations xfs_export_operations;
extern const struct xattr_handler *xfs_xattr_handlers[];
extern const struct quotactl_ops xfs_quotactl_operations;
+extern const struct dax_holder_operations xfs_dax_holder_operations;

extern void xfs_reinit_percpu_counters(struct xfs_mount *mp);

--
2.35.1




2022-04-11 22:22:55

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH v12 6/7] xfs: Implement ->notify_failure() for XFS

> --- a/fs/xfs/xfs_super.h
> +++ b/fs/xfs/xfs_super.h
> @@ -93,6 +93,7 @@ extern xfs_agnumber_t xfs_set_inode_alloc(struct xfs_mount *,
> extern const struct export_operations xfs_export_operations;
> extern const struct xattr_handler *xfs_xattr_handlers[];
> extern const struct quotactl_ops xfs_quotactl_operations;


> +extern const struct dax_holder_operations xfs_dax_holder_operations;

This needs to be defined to NULL if at least one of CONFIG_FS_DAX or
CONFIG_MEMORY_FAILURE is not set.

Otherwise looks good:

Reviewed-by: Christoph Hellwig <[email protected]>

2022-04-12 07:17:23

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v12 6/7] xfs: Implement ->notify_failure() for XFS

Hi Shiyang,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on hnaz-mm/master]
[also build test ERROR on next-20220408]
[cannot apply to xfs-linux/for-next linus/master linux/master v5.18-rc1]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/intel-lab-lkp/linux/commits/Shiyang-Ruan/fsdax-introduce-fs-query-to-support-reflink/20220411-001048
base: https://github.com/hnaz/linux-mm master
config: s390-defconfig (https://download.01.org/0day-ci/archive/20220411/[email protected]/config)
compiler: s390-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/bf68be0c39b8ecc4223b948a9ee126af167d74f0
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Shiyang-Ruan/fsdax-introduce-fs-query-to-support-reflink/20220411-001048
git checkout bf68be0c39b8ecc4223b948a9ee126af167d74f0
# save the config file to linux build tree
mkdir build_dir
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=s390 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>

All errors (new ones prefixed by >>):

s390-linux-ld: fs/xfs/xfs_buf.o: in function `xfs_alloc_buftarg':
>> fs/xfs/xfs_buf.c:1968: undefined reference to `xfs_dax_holder_operations'
pahole: .tmp_vmlinux.btf: No such file or directory
.btf.vmlinux.bin.o: file not recognized: file format not recognized


vim +1968 fs/xfs/xfs_buf.c

1955
1956 struct xfs_buftarg *
1957 xfs_alloc_buftarg(
1958 struct xfs_mount *mp,
1959 struct block_device *bdev)
1960 {
1961 xfs_buftarg_t *btp;
1962
1963 btp = kmem_zalloc(sizeof(*btp), KM_NOFS);
1964
1965 btp->bt_mount = mp;
1966 btp->bt_dev = bdev->bd_dev;
1967 btp->bt_bdev = bdev;
> 1968 btp->bt_daxdev = fs_dax_get_by_bdev(bdev, &btp->bt_dax_part_off, mp,
1969 &xfs_dax_holder_operations);
1970
1971 /*
1972 * Buffer IO error rate limiting. Limit it to no more than 10 messages
1973 * per 30 seconds so as to not spam logs too much on repeated errors.
1974 */
1975 ratelimit_state_init(&btp->bt_ioerror_rl, 30 * HZ,
1976 DEFAULT_RATELIMIT_BURST);
1977
1978 if (xfs_setsize_buftarg_early(btp, bdev))
1979 goto error_free;
1980
1981 if (list_lru_init(&btp->bt_lru))
1982 goto error_free;
1983
1984 if (percpu_counter_init(&btp->bt_io_count, 0, GFP_KERNEL))
1985 goto error_lru;
1986
1987 btp->bt_shrinker.count_objects = xfs_buftarg_shrink_count;
1988 btp->bt_shrinker.scan_objects = xfs_buftarg_shrink_scan;
1989 btp->bt_shrinker.seeks = DEFAULT_SEEKS;
1990 btp->bt_shrinker.flags = SHRINKER_NUMA_AWARE;
1991 if (register_shrinker(&btp->bt_shrinker))
1992 goto error_pcpu;
1993 return btp;
1994
1995 error_pcpu:
1996 percpu_counter_destroy(&btp->bt_io_count);
1997 error_lru:
1998 list_lru_destroy(&btp->bt_lru);
1999 error_free:
2000 kmem_free(btp);
2001 return NULL;
2002 }
2003

--
0-DAY CI Kernel Test Service
https://01.org/lkp

2022-04-13 01:50:26

by Dave Chinner

[permalink] [raw]
Subject: Re: [PATCH v12 6/7] xfs: Implement ->notify_failure() for XFS

On Mon, Apr 11, 2022 at 12:09:03AM +0800, Shiyang Ruan wrote:
> Introduce xfs_notify_failure.c to handle failure related works, such as
> implement ->notify_failure(), register/unregister dax holder in xfs, and
> so on.
>
> If the rmap feature of XFS enabled, we can query it to find files and
> metadata which are associated with the corrupt data. For now all we do
> is kill processes with that file mapped into their address spaces, but
> future patches could actually do something about corrupt metadata.
>
> After that, the memory failure needs to notify the processes who are
> using those files.
>
> Signed-off-by: Shiyang Ruan <[email protected]>
> ---
> fs/xfs/Makefile | 5 +
> fs/xfs/xfs_buf.c | 7 +-
> fs/xfs/xfs_fsops.c | 3 +
> fs/xfs/xfs_mount.h | 1 +
> fs/xfs/xfs_notify_failure.c | 219 ++++++++++++++++++++++++++++++++++++
> fs/xfs/xfs_super.h | 1 +
> 6 files changed, 233 insertions(+), 3 deletions(-)
> create mode 100644 fs/xfs/xfs_notify_failure.c
>
> diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
> index 04611a1068b4..09f5560e29f2 100644
> --- a/fs/xfs/Makefile
> +++ b/fs/xfs/Makefile
> @@ -128,6 +128,11 @@ xfs-$(CONFIG_SYSCTL) += xfs_sysctl.o
> xfs-$(CONFIG_COMPAT) += xfs_ioctl32.o
> xfs-$(CONFIG_EXPORTFS_BLOCK_OPS) += xfs_pnfs.o
>
> +# notify failure
> +ifeq ($(CONFIG_MEMORY_FAILURE),y)
> +xfs-$(CONFIG_FS_DAX) += xfs_notify_failure.o
> +endif
> +
> # online scrub/repair
> ifeq ($(CONFIG_XFS_ONLINE_SCRUB),y)
>
> diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
> index f9ca08398d32..9064b8dfbc66 100644
> --- a/fs/xfs/xfs_buf.c
> +++ b/fs/xfs/xfs_buf.c
> @@ -5,6 +5,7 @@
> */
> #include "xfs.h"
> #include <linux/backing-dev.h>
> +#include <linux/dax.h>
>
> #include "xfs_shared.h"
> #include "xfs_format.h"
> @@ -1911,7 +1912,7 @@ xfs_free_buftarg(
> list_lru_destroy(&btp->bt_lru);
>
> blkdev_issue_flush(btp->bt_bdev);
> - fs_put_dax(btp->bt_daxdev, NULL);
> + fs_put_dax(btp->bt_daxdev, btp->bt_mount);
>
> kmem_free(btp);
> }
> @@ -1964,8 +1965,8 @@ xfs_alloc_buftarg(
> btp->bt_mount = mp;
> btp->bt_dev = bdev->bd_dev;
> btp->bt_bdev = bdev;
> - btp->bt_daxdev = fs_dax_get_by_bdev(bdev, &btp->bt_dax_part_off, NULL,
> - NULL);
> + btp->bt_daxdev = fs_dax_get_by_bdev(bdev, &btp->bt_dax_part_off, mp,
> + &xfs_dax_holder_operations);

I see a problem with this: we are setting up notify callbacks before
we've even read in the superblock during mount. i.e. we don't even
kow yet if we've got an XFS filesystem on this block device.

Hence if we get a notification immediately after registering this
notification callback....

[...]

> +
> +static int
> +xfs_dax_notify_ddev_failure(
> + struct xfs_mount *mp,
> + xfs_daddr_t daddr,
> + xfs_daddr_t bblen,
> + int mf_flags)
> +{
> + struct xfs_trans *tp = NULL;
> + struct xfs_btree_cur *cur = NULL;
> + struct xfs_buf *agf_bp = NULL;
> + int error = 0;
> + xfs_fsblock_t fsbno = XFS_DADDR_TO_FSB(mp, daddr);
> + xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, fsbno);
> + xfs_fsblock_t end_fsbno = XFS_DADDR_TO_FSB(mp, daddr + bblen);
> + xfs_agnumber_t end_agno = XFS_FSB_TO_AGNO(mp, end_fsbno);

.... none of this code is going to function correctly because it
is dependent on the superblock having been read, validated and
copied to the in-memory superblock.

> + error = xfs_trans_alloc_empty(mp, &tp);
> + if (error)
> + return error;

... and it's not valid to use transactions (even empty ones) before
log recovery has completed and set the log up correctly.

> +
> + for (; agno <= end_agno; agno++) {
> + struct xfs_rmap_irec ri_low = { };
> + struct xfs_rmap_irec ri_high;
> + struct failure_info notify;
> + struct xfs_agf *agf;
> + xfs_agblock_t agend;
> +
> + error = xfs_alloc_read_agf(mp, tp, agno, 0, &agf_bp);
> + if (error)
> + break;
> +
> + cur = xfs_rmapbt_init_cursor(mp, tp, agf_bp, agf_bp->b_pag);

... and none of the structures this rmapbt walk is dependent on
(e.g. perag structures) have been initialised yet so there's null
pointer dereferences going to happen here.

Perhaps even worse is that the rmapbt is not guaranteed to be in
consistent state until after log recovery has completed, so this
walk could get stuck forever in a stale on-disk cycle that
recovery would have corrected....

Hence these notifications need to be delayed until after the
filesystem is mounted, all the internal structures have been set up
and log recovery has completed.

Cheers,

Dave.
--
Dave Chinner
[email protected]

2022-04-13 05:19:41

by Dan Williams

[permalink] [raw]
Subject: Re: [PATCH v12 6/7] xfs: Implement ->notify_failure() for XFS

On Tue, Apr 12, 2022 at 5:04 PM Dave Chinner <[email protected]> wrote:
>
> On Mon, Apr 11, 2022 at 12:09:03AM +0800, Shiyang Ruan wrote:
> > Introduce xfs_notify_failure.c to handle failure related works, such as
> > implement ->notify_failure(), register/unregister dax holder in xfs, and
> > so on.
> >
> > If the rmap feature of XFS enabled, we can query it to find files and
> > metadata which are associated with the corrupt data. For now all we do
> > is kill processes with that file mapped into their address spaces, but
> > future patches could actually do something about corrupt metadata.
> >
> > After that, the memory failure needs to notify the processes who are
> > using those files.
> >
> > Signed-off-by: Shiyang Ruan <[email protected]>
> > ---
> > fs/xfs/Makefile | 5 +
> > fs/xfs/xfs_buf.c | 7 +-
> > fs/xfs/xfs_fsops.c | 3 +
> > fs/xfs/xfs_mount.h | 1 +
> > fs/xfs/xfs_notify_failure.c | 219 ++++++++++++++++++++++++++++++++++++
> > fs/xfs/xfs_super.h | 1 +
> > 6 files changed, 233 insertions(+), 3 deletions(-)
> > create mode 100644 fs/xfs/xfs_notify_failure.c
> >
> > diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
> > index 04611a1068b4..09f5560e29f2 100644
> > --- a/fs/xfs/Makefile
> > +++ b/fs/xfs/Makefile
> > @@ -128,6 +128,11 @@ xfs-$(CONFIG_SYSCTL) += xfs_sysctl.o
> > xfs-$(CONFIG_COMPAT) += xfs_ioctl32.o
> > xfs-$(CONFIG_EXPORTFS_BLOCK_OPS) += xfs_pnfs.o
> >
> > +# notify failure
> > +ifeq ($(CONFIG_MEMORY_FAILURE),y)
> > +xfs-$(CONFIG_FS_DAX) += xfs_notify_failure.o
> > +endif
> > +
> > # online scrub/repair
> > ifeq ($(CONFIG_XFS_ONLINE_SCRUB),y)
> >
> > diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
> > index f9ca08398d32..9064b8dfbc66 100644
> > --- a/fs/xfs/xfs_buf.c
> > +++ b/fs/xfs/xfs_buf.c
> > @@ -5,6 +5,7 @@
> > */
> > #include "xfs.h"
> > #include <linux/backing-dev.h>
> > +#include <linux/dax.h>
> >
> > #include "xfs_shared.h"
> > #include "xfs_format.h"
> > @@ -1911,7 +1912,7 @@ xfs_free_buftarg(
> > list_lru_destroy(&btp->bt_lru);
> >
> > blkdev_issue_flush(btp->bt_bdev);
> > - fs_put_dax(btp->bt_daxdev, NULL);
> > + fs_put_dax(btp->bt_daxdev, btp->bt_mount);
> >
> > kmem_free(btp);
> > }
> > @@ -1964,8 +1965,8 @@ xfs_alloc_buftarg(
> > btp->bt_mount = mp;
> > btp->bt_dev = bdev->bd_dev;
> > btp->bt_bdev = bdev;
> > - btp->bt_daxdev = fs_dax_get_by_bdev(bdev, &btp->bt_dax_part_off, NULL,
> > - NULL);
> > + btp->bt_daxdev = fs_dax_get_by_bdev(bdev, &btp->bt_dax_part_off, mp,
> > + &xfs_dax_holder_operations);
>
> I see a problem with this: we are setting up notify callbacks before
> we've even read in the superblock during mount. i.e. we don't even
> kow yet if we've got an XFS filesystem on this block device.
>
> Hence if we get a notification immediately after registering this
> notification callback....
>
> [...]
>
> > +
> > +static int
> > +xfs_dax_notify_ddev_failure(
> > + struct xfs_mount *mp,
> > + xfs_daddr_t daddr,
> > + xfs_daddr_t bblen,
> > + int mf_flags)
> > +{
> > + struct xfs_trans *tp = NULL;
> > + struct xfs_btree_cur *cur = NULL;
> > + struct xfs_buf *agf_bp = NULL;
> > + int error = 0;
> > + xfs_fsblock_t fsbno = XFS_DADDR_TO_FSB(mp, daddr);
> > + xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, fsbno);
> > + xfs_fsblock_t end_fsbno = XFS_DADDR_TO_FSB(mp, daddr + bblen);
> > + xfs_agnumber_t end_agno = XFS_FSB_TO_AGNO(mp, end_fsbno);
>
> .... none of this code is going to function correctly because it
> is dependent on the superblock having been read, validated and
> copied to the in-memory superblock.
>
> > + error = xfs_trans_alloc_empty(mp, &tp);
> > + if (error)
> > + return error;
>
> ... and it's not valid to use transactions (even empty ones) before
> log recovery has completed and set the log up correctly.
>
> > +
> > + for (; agno <= end_agno; agno++) {
> > + struct xfs_rmap_irec ri_low = { };
> > + struct xfs_rmap_irec ri_high;
> > + struct failure_info notify;
> > + struct xfs_agf *agf;
> > + xfs_agblock_t agend;
> > +
> > + error = xfs_alloc_read_agf(mp, tp, agno, 0, &agf_bp);
> > + if (error)
> > + break;
> > +
> > + cur = xfs_rmapbt_init_cursor(mp, tp, agf_bp, agf_bp->b_pag);
>
> ... and none of the structures this rmapbt walk is dependent on
> (e.g. perag structures) have been initialised yet so there's null
> pointer dereferences going to happen here.
>
> Perhaps even worse is that the rmapbt is not guaranteed to be in
> consistent state until after log recovery has completed, so this
> walk could get stuck forever in a stale on-disk cycle that
> recovery would have corrected....
>
> Hence these notifications need to be delayed until after the
> filesystem is mounted, all the internal structures have been set up
> and log recovery has completed.

So I think this gets back to the fact that there will eventually be 2
paths into this notifier. One will be the currently proposed
synchronous / CPU-consumes-poison while accessing the filesystem
(potentially even while recovery is running), and another will be in
response to some asynchronous background scanning. I am thinking that
the latter would be driven from a userspace daemon reconciling
background scan events and notifying the filesystem and any other
interested party.

All that to say, I think it is ok / expected for the filesystem to
drop notifications on the floor when it is not ready to handle them.
For example there are no processes to send SIGBUS to if the filesystem
has not even finished mount. It is then up to userspace to replay any
relevant error notifications that may be pending after mount completes
to sync the filesystem with the current state of the hardware.

2022-04-13 14:33:17

by Dave Chinner

[permalink] [raw]
Subject: Re: [PATCH v12 6/7] xfs: Implement ->notify_failure() for XFS

On Tue, Apr 12, 2022 at 07:06:40PM -0700, Dan Williams wrote:
> On Tue, Apr 12, 2022 at 5:04 PM Dave Chinner <[email protected]> wrote:
> > On Mon, Apr 11, 2022 at 12:09:03AM +0800, Shiyang Ruan wrote:
> > > Introduce xfs_notify_failure.c to handle failure related works, such as
> > > implement ->notify_failure(), register/unregister dax holder in xfs, and
> > > so on.
> > >
> > > If the rmap feature of XFS enabled, we can query it to find files and
> > > metadata which are associated with the corrupt data. For now all we do
> > > is kill processes with that file mapped into their address spaces, but
> > > future patches could actually do something about corrupt metadata.
> > >
> > > After that, the memory failure needs to notify the processes who are
> > > using those files.
...
> > > @@ -1964,8 +1965,8 @@ xfs_alloc_buftarg(
> > > btp->bt_mount = mp;
> > > btp->bt_dev = bdev->bd_dev;
> > > btp->bt_bdev = bdev;
> > > - btp->bt_daxdev = fs_dax_get_by_bdev(bdev, &btp->bt_dax_part_off, NULL,
> > > - NULL);
> > > + btp->bt_daxdev = fs_dax_get_by_bdev(bdev, &btp->bt_dax_part_off, mp,
> > > + &xfs_dax_holder_operations);
> >
> > I see a problem with this: we are setting up notify callbacks before
> > we've even read in the superblock during mount. i.e. we don't even
> > kow yet if we've got an XFS filesystem on this block device.
> > Hence these notifications need to be delayed until after the
> > filesystem is mounted, all the internal structures have been set up
> > and log recovery has completed.
>
> So I think this gets back to the fact that there will eventually be 2
> paths into this notifier.

I'm not really concerned by how the notifications are generated;
my concern is purely that notifications can be handled safely.

> All that to say, I think it is ok / expected for the filesystem to
> drop notifications on the floor when it is not ready to handle them.

Well, yes. The whole point of notifications is the consumer makes
the decision on what to do with the notification it receives - the
producer of the notification does not (and can not) dictate what
policy the consumer(s) implement...

> For example there are no processes to send SIGBUS to if the filesystem
> has not even finished mount.

There may be not processes to send SIGBUS to even if the filesystem
has finished mount. But we still want the notifications to be
delivered and we still need to handle them safely.

IOWs, while we might start by avoiding notifications during mount,
this doesn't mean we will never have reason to process events during
mount. What we do with this notification is going to evolve over
time as we add new and adapt existing functionality....

Cheers,

Dave.
--
Dave Chinner
[email protected]

2022-04-13 19:58:34

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH v12 6/7] xfs: Implement ->notify_failure() for XFS

On Wed, Apr 13, 2022 at 10:09:40AM -0700, Dan Williams wrote:
> Yes, sounds like we're on the same page. I had mistakenly interpreted
> "Hence these notifications need to be delayed until after the
> filesystem is mounted" as something the producer would need to handle,
> but yes, consumer is free to drop if the notification arrives at an
> inopportune time.

A SB_BORN check might be all that we need.

2022-04-14 12:38:51

by Dan Williams

[permalink] [raw]
Subject: Re: [PATCH v12 6/7] xfs: Implement ->notify_failure() for XFS

On Tue, Apr 12, 2022 at 11:10 PM Dave Chinner <[email protected]> wrote:
>
> On Tue, Apr 12, 2022 at 07:06:40PM -0700, Dan Williams wrote:
> > On Tue, Apr 12, 2022 at 5:04 PM Dave Chinner <[email protected]> wrote:
> > > On Mon, Apr 11, 2022 at 12:09:03AM +0800, Shiyang Ruan wrote:
> > > > Introduce xfs_notify_failure.c to handle failure related works, such as
> > > > implement ->notify_failure(), register/unregister dax holder in xfs, and
> > > > so on.
> > > >
> > > > If the rmap feature of XFS enabled, we can query it to find files and
> > > > metadata which are associated with the corrupt data. For now all we do
> > > > is kill processes with that file mapped into their address spaces, but
> > > > future patches could actually do something about corrupt metadata.
> > > >
> > > > After that, the memory failure needs to notify the processes who are
> > > > using those files.
> ...
> > > > @@ -1964,8 +1965,8 @@ xfs_alloc_buftarg(
> > > > btp->bt_mount = mp;
> > > > btp->bt_dev = bdev->bd_dev;
> > > > btp->bt_bdev = bdev;
> > > > - btp->bt_daxdev = fs_dax_get_by_bdev(bdev, &btp->bt_dax_part_off, NULL,
> > > > - NULL);
> > > > + btp->bt_daxdev = fs_dax_get_by_bdev(bdev, &btp->bt_dax_part_off, mp,
> > > > + &xfs_dax_holder_operations);
> > >
> > > I see a problem with this: we are setting up notify callbacks before
> > > we've even read in the superblock during mount. i.e. we don't even
> > > kow yet if we've got an XFS filesystem on this block device.
> > > Hence these notifications need to be delayed until after the
> > > filesystem is mounted, all the internal structures have been set up
> > > and log recovery has completed.
> >
> > So I think this gets back to the fact that there will eventually be 2
> > paths into this notifier.
>
> I'm not really concerned by how the notifications are generated;
> my concern is purely that notifications can be handled safely.
>
> > All that to say, I think it is ok / expected for the filesystem to
> > drop notifications on the floor when it is not ready to handle them.
>
> Well, yes. The whole point of notifications is the consumer makes
> the decision on what to do with the notification it receives - the
> producer of the notification does not (and can not) dictate what
> policy the consumer(s) implement...
>
> > For example there are no processes to send SIGBUS to if the filesystem
> > has not even finished mount.
>
> There may be not processes to send SIGBUS to even if the filesystem
> has finished mount. But we still want the notifications to be
> delivered and we still need to handle them safely.
>
> IOWs, while we might start by avoiding notifications during mount,
> this doesn't mean we will never have reason to process events during
> mount. What we do with this notification is going to evolve over
> time as we add new and adapt existing functionality....

Yes, sounds like we're on the same page. I had mistakenly interpreted
"Hence these notifications need to be delayed until after the
filesystem is mounted" as something the producer would need to handle,
but yes, consumer is free to drop if the notification arrives at an
inopportune time.

2022-04-16 00:18:23

by kernel test robot

[permalink] [raw]
Subject: [xfs] bf68be0c39: BUG:KASAN:null-ptr-deref_in_fs_put_dax



Greeting,

FYI, we noticed the following commit (built with gcc-11):

commit: bf68be0c39b8ecc4223b948a9ee126af167d74f0 ("[PATCH v12 6/7] xfs: Implement ->notify_failure() for XFS")
url: https://github.com/intel-lab-lkp/linux/commits/Shiyang-Ruan/fsdax-introduce-fs-query-to-support-reflink/20220411-001048
base: https://github.com/hnaz/linux-mm master
patch link: https://lore.kernel.org/lkml/[email protected]

in testcase: xfstests
version: xfstests-x86_64-1de1db8-1_20220217
with following parameters:

disk: 4HDD
fs: xfs
test: xfs-group-05
ucode: 0x21

test-description: xfstests is a regression test suite for xfs and other files ystems.
test-url: git://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git


on test machine: 4 threads 1 sockets Intel(R) Core(TM) i3-3220 CPU @ 3.30GHz with 8G memory

caused below changes (please refer to attached dmesg/kmsg for entire log/backtrace):



If you fix the issue, kindly add following tag
Reported-by: kernel test robot <[email protected]>


[ 62.111233][ T1606] BUG: KASAN: null-ptr-deref in fs_put_dax (drivers/dax/super.c:116 (discriminator 1))
[ 62.117884][ T1606] Write of size 8 at addr 00000000000002f0 by task umount/1606
[ 62.125379][ T1606]
[ 62.127616][ T1606] CPU: 2 PID: 1606 Comm: umount Not tainted 5.18.0-rc1-mm1-00194-gbf68be0c39b8 #1
[ 62.136760][ T1606] Hardware name: Hewlett-Packard HP Pro 3340 MT/17A1, BIOS 8.07 01/24/2013
[ 62.145339][ T1606] Call Trace:
[ 62.148554][ T1606] <TASK>
[ 62.151404][ T1606] ? fs_put_dax (drivers/dax/super.c:116 (discriminator 1))
[ 62.155651][ T1606] dump_stack_lvl (lib/dump_stack.c:107 (discriminator 1))
[ 62.160110][ T1606] kasan_report (mm/kasan/report.c:162 mm/kasan/report.c:493)
[ 62.164447][ T1606] ? fs_put_dax (drivers/dax/super.c:116 (discriminator 1))
[ 62.168677][ T1606] kasan_check_range (mm/kasan/generic.c:190)
[ 62.173427][ T1606] fs_put_dax (drivers/dax/super.c:116 (discriminator 1))
[ 62.177519][ T1606] xfs_free_buftarg (fs/xfs/kmem.h:62 fs/xfs/xfs_buf.c:1917) xfs
[ 62.182900][ T1606] xfs_fs_put_super (fs/xfs/xfs_super.c:1101) xfs
[ 62.188326][ T1606] generic_shutdown_super (fs/super.c:464)
[ 62.193636][ T1606] kill_block_super (fs/super.c:1395)
[ 62.198325][ T1606] deactivate_locked_super (fs/super.c:339)
[ 62.203656][ T1606] cleanup_mnt (fs/namespace.c:138 fs/namespace.c:1187)
[ 62.208023][ T1606] ? path_umount (fs/namespace.c:1808)
[ 62.212530][ T1606] task_work_run (kernel/task_work.c:166 (discriminator 1))
[ 62.216932][ T1606] exit_to_user_mode_loop (include/linux/resume_user_mode.h:49 kernel/entry/common.c:169)
[ 62.222253][ T1606] exit_to_user_mode_prepare (kernel/entry/common.c:201)
[ 62.227749][ T1606] syscall_exit_to_user_mode (arch/x86/include/asm/jump_label.h:27 include/linux/context_tracking_state.h:31 include/linux/context_tracking.h:40 kernel/entry/common.c:132 kernel/entry/common.c:296)
[ 62.233149][ T1606] do_syscall_64 (arch/x86/entry/common.c:87)
[ 62.237447][ T1606] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:115)
[ 62.243288][ T1606] RIP: 0033:0x7fa858fee507
[ 62.247649][ T1606] Code: 19 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 0f 1f 44 00 00 31 f6 e9 09 00 00 00 66 0f 1f 84 00 00 00 00 00 b8 a6 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 59 19 0c 00 f7 d8 64 89 01 48
All code
========
0: 19 0c 00 sbb %ecx,(%rax,%rax,1)
3: f7 d8 neg %eax
5: 64 89 01 mov %eax,%fs:(%rcx)
8: 48 83 c8 ff or $0xffffffffffffffff,%rax
c: c3 retq
d: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
13: 31 f6 xor %esi,%esi
15: e9 09 00 00 00 jmpq 0x23
1a: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
21: 00 00
23: b8 a6 00 00 00 mov $0xa6,%eax
28: 0f 05 syscall
2a:* 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax <-- trapping instruction
30: 73 01 jae 0x33
32: c3 retq
33: 48 8b 0d 59 19 0c 00 mov 0xc1959(%rip),%rcx # 0xc1993
3a: f7 d8 neg %eax
3c: 64 89 01 mov %eax,%fs:(%rcx)
3f: 48 rex.W

Code starting with the faulting instruction
===========================================
0: 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax
6: 73 01 jae 0x9
8: c3 retq
9: 48 8b 0d 59 19 0c 00 mov 0xc1959(%rip),%rcx # 0xc1969
10: f7 d8 neg %eax
12: 64 89 01 mov %eax,%fs:(%rcx)
15: 48 rex.W
[ 62.267385][ T1606] RSP: 002b:00007ffe344b8b68 EFLAGS: 00000246 ORIG_RAX: 00000000000000a6
[ 62.275814][ T1606] RAX: 0000000000000000 RBX: 00005639c92b5970 RCX: 00007fa858fee507
[ 62.283744][ T1606] RDX: 0000000000000001 RSI: 0000000000000000 RDI: 00005639c92b5b80
[ 62.291682][ T1606] RBP: 0000000000000000 R08: 00005639c92b5ba0 R09: 00007fa85906fe80
[ 62.299622][ T1606] R10: 0000000000000000 R11: 0000000000000246 R12: 00005639c92b5b80
[ 62.307568][ T1606] R13: 00007fa8591141c4 R14: 00005639c92b5a68 R15: 0000000000000000
[ 62.315510][ T1606] </TASK>
[ 62.318445][ T1606] ==================================================================
[ 62.326514][ T1606] Disabling lock debugging due to kernel taint
[ 62.332634][ T1606] BUG: kernel NULL pointer dereference, address: 00000000000002f0
[ 62.340410][ T1606] #PF: supervisor write access in kernel mode
[ 62.346422][ T1606] #PF: error_code(0x0002) - not-present page
[ 62.352357][ T1606] PGD 0 P4D 0
[ 62.355658][ T1606] Oops: 0002 [#1] SMP KASAN PTI
[ 62.360475][ T1606] CPU: 2 PID: 1606 Comm: umount Tainted: G B 5.18.0-rc1-mm1-00194-gbf68be0c39b8 #1
[ 62.371045][ T1606] Hardware name: Hewlett-Packard HP Pro 3340 MT/17A1, BIOS 8.07 01/24/2013
[ 62.379598][ T1606] RIP: 0010:fs_put_dax (drivers/dax/super.c:116 (discriminator 1))
[ 62.384466][ T1606] Code: 40 00 0f 1f 44 00 00 55 48 89 fd 53 48 85 f6 74 27 48 89 f3 48 8d bf f0 02 00 00 be 08 00 00 00 e8 9d a8 29 ff 48 89 d8 31 d2 <f0> 48 0f b1 95 f0 02 00 00 48 39 c3 74 12 48 85 ed 74 0a 48 89 ef
All code
========
0: 40 00 0f add %cl,(%rdi)
3: 1f (bad)
4: 44 00 00 add %r8b,(%rax)
7: 55 push %rbp
8: 48 89 fd mov %rdi,%rbp
b: 53 push %rbx
c: 48 85 f6 test %rsi,%rsi
f: 74 27 je 0x38
11: 48 89 f3 mov %rsi,%rbx
14: 48 8d bf f0 02 00 00 lea 0x2f0(%rdi),%rdi
1b: be 08 00 00 00 mov $0x8,%esi
20: e8 9d a8 29 ff callq 0xffffffffff29a8c2
25: 48 89 d8 mov %rbx,%rax
28: 31 d2 xor %edx,%edx
2a:* f0 48 0f b1 95 f0 02 lock cmpxchg %rdx,0x2f0(%rbp) <-- trapping instruction
31: 00 00
33: 48 39 c3 cmp %rax,%rbx
36: 74 12 je 0x4a
38: 48 85 ed test %rbp,%rbp
3b: 74 0a je 0x47
3d: 48 89 ef mov %rbp,%rdi

Code starting with the faulting instruction
===========================================
0: f0 48 0f b1 95 f0 02 lock cmpxchg %rdx,0x2f0(%rbp)
7: 00 00
9: 48 39 c3 cmp %rax,%rbx
c: 74 12 je 0x20
e: 48 85 ed test %rbp,%rbp
11: 74 0a je 0x1d
13: 48 89 ef mov %rbp,%rdi
[ 62.404142][ T1606] RSP: 0018:ffffc90000f5fd90 EFLAGS: 00010246
[ 62.410137][ T1606] RAX: ffff888140f34000 RBX: ffff888140f34000 RCX: ffffffff811992e6
[ 62.418085][ T1606] RDX: 0000000000000000 RSI: 0000000000000008 RDI: ffffffff85c0b600
[ 62.426032][ T1606] RBP: 0000000000000000 R08: 0000000000000001 R09: ffffffff85c0b607
[ 62.433997][ T1606] R10: fffffbfff0b816c0 R11: 0000000000000000 R12: ffff8882189e80b8
[ 62.441943][ T1606] R13: ffff888140f34180 R14: ffff888140f34188 R15: ffff8881312f4180
[ 62.449876][ T1606] FS: 00007fa858bc8080(0000) GS:ffff8881aad00000(0000) knlGS:0000000000000000
[ 62.458774][ T1606] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 62.465317][ T1606] CR2: 00000000000002f0 CR3: 0000000134b6a002 CR4: 00000000001706e0
[ 62.473283][ T1606] Call Trace:
[ 62.476463][ T1606] <TASK>
[ 62.479331][ T1606] xfs_free_buftarg (fs/xfs/kmem.h:62 fs/xfs/xfs_buf.c:1917) xfs
[ 62.484688][ T1606] xfs_fs_put_super (fs/xfs/xfs_super.c:1101) xfs
[ 62.490091][ T1606] generic_shutdown_super (fs/super.c:464)
[ 62.495390][ T1606] kill_block_super (fs/super.c:1395)
[ 62.500072][ T1606] deactivate_locked_super (fs/super.c:339)
[ 62.505394][ T1606] cleanup_mnt (fs/namespace.c:138 fs/namespace.c:1187)
[ 62.509717][ T1606] ? path_umount (fs/namespace.c:1808)
[ 62.514233][ T1606] task_work_run (kernel/task_work.c:166 (discriminator 1))
[ 62.518679][ T1606] exit_to_user_mode_loop (include/linux/resume_user_mode.h:49 kernel/entry/common.c:169)
[ 62.524009][ T1606] exit_to_user_mode_prepare (kernel/entry/common.c:201)
[ 62.529493][ T1606] syscall_exit_to_user_mode (arch/x86/include/asm/jump_label.h:27 include/linux/context_tracking_state.h:31 include/linux/context_tracking.h:40 kernel/entry/common.c:132 kernel/entry/common.c:296)
[ 62.534902][ T1606] do_syscall_64 (arch/x86/entry/common.c:87)
[ 62.539220][ T1606] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:115)
[ 62.545042][ T1606] RIP: 0033:0x7fa858fee507
[ 62.549388][ T1606] Code: 19 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 0f 1f 44 00 00 31 f6 e9 09 00 00 00 66 0f 1f 84 00 00 00 00 00 b8 a6 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 59 19 0c 00 f7 d8 64 89 01 48
All code
========
0: 19 0c 00 sbb %ecx,(%rax,%rax,1)
3: f7 d8 neg %eax
5: 64 89 01 mov %eax,%fs:(%rcx)
8: 48 83 c8 ff or $0xffffffffffffffff,%rax
c: c3 retq
d: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
13: 31 f6 xor %esi,%esi
15: e9 09 00 00 00 jmpq 0x23
1a: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
21: 00 00
23: b8 a6 00 00 00 mov $0xa6,%eax
28: 0f 05 syscall
2a:* 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax <-- trapping instruction
30: 73 01 jae 0x33
32: c3 retq
33: 48 8b 0d 59 19 0c 00 mov 0xc1959(%rip),%rcx # 0xc1993
3a: f7 d8 neg %eax
3c: 64 89 01 mov %eax,%fs:(%rcx)
3f: 48 rex.W

Code starting with the faulting instruction
===========================================
0: 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax
6: 73 01 jae 0x9
8: c3 retq
9: 48 8b 0d 59 19 0c 00 mov 0xc1959(%rip),%rcx # 0xc1969
10: f7 d8 neg %eax
12: 64 89 01 mov %eax,%fs:(%rcx)
15: 48 rex.W
[ 62.569097][ T1606] RSP: 002b:00007ffe344b8b68 EFLAGS: 00000246 ORIG_RAX: 00000000000000a6
[ 62.577467][ T1606] RAX: 0000000000000000 RBX: 00005639c92b5970 RCX: 00007fa858fee507
[ 62.585386][ T1606] RDX: 0000000000000001 RSI: 0000000000000000 RDI: 00005639c92b5b80
[ 62.593265][ T1606] RBP: 0000000000000000 R08: 00005639c92b5ba0 R09: 00007fa85906fe80
[ 62.601248][ T1606] R10: 0000000000000000 R11: 0000000000000246 R12: 00005639c92b5b80
[ 62.609151][ T1606] R13: 00007fa8591141c4 R14: 00005639c92b5a68 R15: 0000000000000000
[ 62.617075][ T1606] </TASK>
[ 62.619995][ T1606] Modules linked in: xfs dm_mod netconsole btrfs blake2b_generic xor raid6_pq zstd_compress libcrc32c sd_mod t10_pi crc64_rocksoft_generic intel_rapl_msr crc64_rocksoft intel_rapl_common crc64 sg x86_pkg_temp_thermal intel_powerclamp coretemp ipmi_devintf i915 ipmi_msghandler kvm_intel kvm intel_gtt drm_buddy drm_dp_helper ttm irqbypass crct10dif_pclmul crc32_pclmul drm_kms_helper wmi_bmof crc32c_intel syscopyarea ghash_clmulni_intel rapl intel_cstate sysfillrect sysimgblt ahci fb_sys_fops libahci intel_uncore mei_me drm libata mei video wmi ip_tables
[ 62.670932][ T1606] CR2: 00000000000002f0
[ 62.675025][ T1606] ---[ end trace 0000000000000000 ]---
[ 62.680557][ T1606] RIP: 0010:fs_put_dax (drivers/dax/super.c:116 (discriminator 1))
[ 62.685457][ T1606] Code: 40 00 0f 1f 44 00 00 55 48 89 fd 53 48 85 f6 74 27 48 89 f3 48 8d bf f0 02 00 00 be 08 00 00 00 e8 9d a8 29 ff 48 89 d8 31 d2 <f0> 48 0f b1 95 f0 02 00 00 48 39 c3 74 12 48 85 ed 74 0a 48 89 ef
All code
========
0: 40 00 0f add %cl,(%rdi)
3: 1f (bad)
4: 44 00 00 add %r8b,(%rax)
7: 55 push %rbp
8: 48 89 fd mov %rdi,%rbp
b: 53 push %rbx
c: 48 85 f6 test %rsi,%rsi
f: 74 27 je 0x38
11: 48 89 f3 mov %rsi,%rbx
14: 48 8d bf f0 02 00 00 lea 0x2f0(%rdi),%rdi
1b: be 08 00 00 00 mov $0x8,%esi
20: e8 9d a8 29 ff callq 0xffffffffff29a8c2
25: 48 89 d8 mov %rbx,%rax
28: 31 d2 xor %edx,%edx
2a:* f0 48 0f b1 95 f0 02 lock cmpxchg %rdx,0x2f0(%rbp) <-- trapping instruction
31: 00 00
33: 48 39 c3 cmp %rax,%rbx
36: 74 12 je 0x4a
38: 48 85 ed test %rbp,%rbp
3b: 74 0a je 0x47
3d: 48 89 ef mov %rbp,%rdi

Code starting with the faulting instruction
===========================================
0: f0 48 0f b1 95 f0 02 lock cmpxchg %rdx,0x2f0(%rbp)
7: 00 00
9: 48 39 c3 cmp %rax,%rbx
c: 74 12 je 0x20
e: 48 85 ed test %rbp,%rbp
11: 74 0a je 0x1d
13: 48 89 ef mov %rbp,%rdi


To reproduce:

git clone https://github.com/intel/lkp-tests.git
cd lkp-tests
sudo bin/lkp install job.yaml # job file is attached in this email
bin/lkp split-job --compatible job.yaml # generate the yaml file for lkp run
sudo bin/lkp run generated-yaml-file

# if come across any failure that blocks the test,
# please remove ~/.lkp and /lkp dir to run from a clean state.



--
0-DAY CI Kernel Test Service
https://01.org/lkp



Attachments:
(No filename) (14.39 kB)
config-5.18.0-rc1-mm1-00194-gbf68be0c39b8 (169.52 kB)
job-script (5.99 kB)
dmesg.xz (4.20 kB)
xfstests (15.25 kB)
job.yaml (4.87 kB)
Download all attachments