Skip to content

Commit dae5cd8

Browse files
Dave Chinnerdjwong
authored andcommitted
xfs: add mount delay debug option
Similar to log_recovery_delay, this delay occurs between the VFS superblock being initialised and the xfs_mount being fully initialised. It also poisons the per-ag radix tree node so that it can be used for triggering shrinker races during mount such as the following: <run memory pressure workload in background> $ cat dirty-mount.sh #! /bin/bash umount -f /dev/pmem0 mkfs.xfs -f /dev/pmem0 mount /dev/pmem0 /mnt/test rm -f /mnt/test/foo xfs_io -fxc "pwrite 0 4k" -c fsync -c "shutdown" /mnt/test/foo umount /dev/pmem0 # let's crash it now! echo 30 > /sys/fs/xfs/debug/mount_delay mount /dev/pmem0 /mnt/test echo 0 > /sys/fs/xfs/debug/mount_delay umount /dev/pmem0 $ sudo ./dirty-mount.sh ..... [ 60.378118] CPU: 3 PID: 3577 Comm: fs_mark Tainted: G D W 4.16.0-rc5-dgc torvalds#440 [ 60.378120] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014 [ 60.378124] RIP: 0010:radix_tree_next_chunk+0x76/0x320 [ 60.378127] RSP: 0018:ffffc9000276f4f8 EFLAGS: 00010282 [ 60.383670] RAX: a5a5a5a5a5a5a5a4 RBX: 0000000000000010 RCX: 000000000000001a [ 60.385277] RDX: 0000000000000000 RSI: ffffc9000276f540 RDI: 0000000000000000 [ 60.386554] RBP: 0000000000000000 R08: 0000000000000000 R09: a5a5a5a5a5a5a5a5 [ 60.388194] R10: 0000000000000006 R11: 0000000000000001 R12: ffffc9000276f598 [ 60.389288] R13: 0000000000000040 R14: 0000000000000228 R15: ffff880816cd6458 [ 60.390827] FS: 00007f5c124b9740(0000) GS:ffff88083fc00000(0000) knlGS:0000000000000000 [ 60.392253] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 60.393423] CR2: 00007f5c11bba0b8 CR3: 000000035580e001 CR4: 00000000000606e0 [ 60.394519] Call Trace: [ 60.395252] radix_tree_gang_lookup_tag+0xc4/0x130 [ 60.395948] xfs_perag_get_tag+0x37/0xf0 [ 60.396522] xfs_reclaim_inodes_count+0x32/0x40 [ 60.397178] xfs_fs_nr_cached_objects+0x11/0x20 [ 60.397837] super_cache_count+0x35/0xc0 [ 60.399159] shrink_slab.part.66+0xb1/0x370 [ 60.400194] shrink_node+0x7e/0x1a0 [ 60.401058] try_to_free_pages+0x199/0x470 [ 60.402081] __alloc_pages_slowpath+0x3a1/0xd20 [ 60.403729] __alloc_pages_nodemask+0x1c3/0x200 [ 60.404941] cache_grow_begin+0x20b/0x2e0 [ 60.406164] fallback_alloc+0x160/0x200 [ 60.407088] kmem_cache_alloc+0x111/0x4e0 [ 60.408038] ? xfs_buf_rele+0x61/0x430 [ 60.408925] kmem_zone_alloc+0x61/0xe0 [ 60.409965] xfs_inode_alloc+0x24/0x1d0 ..... Signed-Off-By: Dave Chinner <[email protected]> Reviewed-by: Brian Foster <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Signed-off-by: Darrick J. Wong <[email protected]>
1 parent 4e52933 commit dae5cd8

File tree

4 files changed

+44
-0
lines changed

4 files changed

+44
-0
lines changed

fs/xfs/xfs_globals.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ xfs_param_t xfs_params = {
4747

4848
struct xfs_globals xfs_globals = {
4949
.log_recovery_delay = 0, /* no delay by default */
50+
.mount_delay = 0, /* no delay by default */
5051
#ifdef XFS_ASSERT_FATAL
5152
.bug_on_assert = true, /* assert failures BUG() */
5253
#else

fs/xfs/xfs_super.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1635,6 +1635,17 @@ xfs_fs_fill_super(
16351635
#endif
16361636
sb->s_op = &xfs_super_operations;
16371637

1638+
/*
1639+
* Delay mount work if the debug hook is set. This is debug
1640+
* instrumention to coordinate simulation of xfs mount failures with
1641+
* VFS superblock operations
1642+
*/
1643+
if (xfs_globals.mount_delay) {
1644+
xfs_notice(mp, "Delaying mount for %d seconds.",
1645+
xfs_globals.mount_delay);
1646+
msleep(xfs_globals.mount_delay * 1000);
1647+
}
1648+
16381649
if (silent)
16391650
flags |= XFS_MFSI_QUIET;
16401651

fs/xfs/xfs_sysctl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ extern xfs_param_t xfs_params;
9595

9696
struct xfs_globals {
9797
int log_recovery_delay; /* log recovery delay (secs) */
98+
int mount_delay; /* mount setup delay (secs) */
9899
bool bug_on_assert; /* BUG() the kernel on assert failure */
99100
};
100101
extern struct xfs_globals xfs_globals;

fs/xfs/xfs_sysfs.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,40 @@ log_recovery_delay_show(
165165
}
166166
XFS_SYSFS_ATTR_RW(log_recovery_delay);
167167

168+
STATIC ssize_t
169+
mount_delay_store(
170+
struct kobject *kobject,
171+
const char *buf,
172+
size_t count)
173+
{
174+
int ret;
175+
int val;
176+
177+
ret = kstrtoint(buf, 0, &val);
178+
if (ret)
179+
return ret;
180+
181+
if (val < 0 || val > 60)
182+
return -EINVAL;
183+
184+
xfs_globals.mount_delay = val;
185+
186+
return count;
187+
}
188+
189+
STATIC ssize_t
190+
mount_delay_show(
191+
struct kobject *kobject,
192+
char *buf)
193+
{
194+
return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.mount_delay);
195+
}
196+
XFS_SYSFS_ATTR_RW(mount_delay);
197+
168198
static struct attribute *xfs_dbg_attrs[] = {
169199
ATTR_LIST(bug_on_assert),
170200
ATTR_LIST(log_recovery_delay),
201+
ATTR_LIST(mount_delay),
171202
NULL,
172203
};
173204

0 commit comments

Comments
 (0)