* [PATCH] xfs: clear PF_MEMALLOC before exiting xfsaild thread
[not found] <0000000000000e7156059f751d7b@google.com>
@ 2020-03-08 4:35 ` Eric Biggers
2020-03-08 23:03 ` Dave Chinner
0 siblings, 1 reply; 12+ messages in thread
From: Eric Biggers @ 2020-03-08 4:35 UTC (permalink / raw)
To: linux-xfs; +Cc: linux-ext4, syzkaller-bugs, linux-kernel
From: Eric Biggers <ebiggers@google.com>
Leaving PF_MEMALLOC set when exiting a kthread causes it to remain set
during do_exit(). That can confuse things. For example, if BSD process
accounting is enabled, then it's possible for do_exit() to end up
calling ext4_write_inode(). That triggers the
WARN_ON_ONCE(current->flags & PF_MEMALLOC) there, as it assumes
(appropriately) that inodes aren't written when allocating memory.
This case was reported by syzbot at
https://lkml.kernel.org/r/0000000000000e7156059f751d7b@google.com.
Fix this in xfsaild() by using the helper functions to save and restore
PF_MEMALLOC.
Reported-by: syzbot+1f9dc49e8de2582d90c2@syzkaller.appspotmail.com
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
fs/xfs/xfs_trans_ail.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index 00cc5b8734be..3bc570c90ad9 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -529,8 +529,9 @@ xfsaild(
{
struct xfs_ail *ailp = data;
long tout = 0; /* milliseconds */
+ unsigned int noreclaim_flag;
- current->flags |= PF_MEMALLOC;
+ noreclaim_flag = memalloc_noreclaim_save();
set_freezable();
while (1) {
@@ -601,6 +602,7 @@ xfsaild(
tout = xfsaild_push(ailp);
}
+ memalloc_noreclaim_restore(noreclaim_flag);
return 0;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] xfs: clear PF_MEMALLOC before exiting xfsaild thread
2020-03-08 4:35 ` [PATCH] xfs: clear PF_MEMALLOC before exiting xfsaild thread Eric Biggers
@ 2020-03-08 23:03 ` Dave Chinner
2020-03-09 1:04 ` Eric Biggers
0 siblings, 1 reply; 12+ messages in thread
From: Dave Chinner @ 2020-03-08 23:03 UTC (permalink / raw)
To: Eric Biggers; +Cc: linux-xfs, linux-ext4, syzkaller-bugs, linux-kernel
On Sat, Mar 07, 2020 at 08:35:40PM -0800, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
>
> Leaving PF_MEMALLOC set when exiting a kthread causes it to remain set
> during do_exit(). That can confuse things. For example, if BSD process
> accounting is enabled, then it's possible for do_exit() to end up
> calling ext4_write_inode(). That triggers the
> WARN_ON_ONCE(current->flags & PF_MEMALLOC) there, as it assumes
> (appropriately) that inodes aren't written when allocating memory.
And just how the hell does and XFS kernel thread end up calling
ext4_write_inode()? That's kinda a key factor in all this, and
it's not explained here.
> This case was reported by syzbot at
> https://lkml.kernel.org/r/0000000000000e7156059f751d7b@google.com.
Which doesn't really explain it, either.
What is the configuration conditions under which this triggers? It
looks like some weird combination of a no-journal ext4 root
filesystem and the audit subsystem being configured with O_SYNC
files?
People trying to decide if this is something that needs to be
backported to stable kernels need to be able to unerstand how this
bug is actually triggered so they can make sane decisions about
it...
/me tracks the PF_MEMALLOC flag back to commit 43ff2122e649 ("xfs:
on-stack delayed write buffer lists") where is was inherited here
from the buffer flush daemon that xfsaild took over from. Which also
never cleared the PF_MEMALLOC flag. That goes back to 2002:
commit d676c94914eb97d72061aff69c99406df4f395e9
Author: Steve Lord <lord@sgi.com>
Date: Fri Jan 11 23:31:51 2002 +0000
Merge pagebuf module into XFS
So this issue of calling do_exit() with PF_MEMALLOC set has been
around for 18+ years without anyone noticing it.
I also note that cifs_demultiplex_thread() has the same problem -
can you please do a complete audit of all the users of PF_MEMALLOC
and fix all of them?
> Fix this in xfsaild() by using the helper functions to save and restore
> PF_MEMALLOC.
>
> Reported-by: syzbot+1f9dc49e8de2582d90c2@syzkaller.appspotmail.com
> Signed-off-by: Eric Biggers <ebiggers@google.com>
> ---
> fs/xfs/xfs_trans_ail.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
> index 00cc5b8734be..3bc570c90ad9 100644
> --- a/fs/xfs/xfs_trans_ail.c
> +++ b/fs/xfs/xfs_trans_ail.c
> @@ -529,8 +529,9 @@ xfsaild(
> {
> struct xfs_ail *ailp = data;
> long tout = 0; /* milliseconds */
> + unsigned int noreclaim_flag;
>
> - current->flags |= PF_MEMALLOC;
> + noreclaim_flag = memalloc_noreclaim_save();
> set_freezable();
>
> while (1) {
> @@ -601,6 +602,7 @@ xfsaild(
> tout = xfsaild_push(ailp);
> }
>
> + memalloc_noreclaim_restore(noreclaim_flag);
> return 0;
> }
The code looks fine - I considered doing this a couple of weeks ago
just for cleaniness reasons - but the commit message needs work to
explain the context of the bug...
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] xfs: clear PF_MEMALLOC before exiting xfsaild thread
2020-03-08 23:03 ` Dave Chinner
@ 2020-03-09 1:04 ` Eric Biggers
2020-03-09 4:34 ` [PATCH v2] " Eric Biggers
0 siblings, 1 reply; 12+ messages in thread
From: Eric Biggers @ 2020-03-09 1:04 UTC (permalink / raw)
To: Dave Chinner; +Cc: linux-xfs, linux-ext4, syzkaller-bugs, linux-kernel
On Mon, Mar 09, 2020 at 10:03:07AM +1100, Dave Chinner wrote:
> On Sat, Mar 07, 2020 at 08:35:40PM -0800, Eric Biggers wrote:
> > From: Eric Biggers <ebiggers@google.com>
> >
> > Leaving PF_MEMALLOC set when exiting a kthread causes it to remain set
> > during do_exit(). That can confuse things. For example, if BSD process
> > accounting is enabled, then it's possible for do_exit() to end up
> > calling ext4_write_inode(). That triggers the
> > WARN_ON_ONCE(current->flags & PF_MEMALLOC) there, as it assumes
> > (appropriately) that inodes aren't written when allocating memory.
>
> And just how the hell does and XFS kernel thread end up calling
> ext4_write_inode()? That's kinda a key factor in all this, and
> it's not explained here.
>
> > This case was reported by syzbot at
> > https://lkml.kernel.org/r/0000000000000e7156059f751d7b@google.com.
>
> Which doesn't really explain it, either.
>
> What is the configuration conditions under which this triggers? It
> looks like some weird combination of a no-journal ext4 root
> filesystem and the audit subsystem being configured with O_SYNC
> files?
>
> People trying to decide if this is something that needs to be
> backported to stable kernels need to be able to unerstand how this
> bug is actually triggered so they can make sane decisions about
> it...
My guess is that syzbot enabled BSD process accounting to a file with FS_SYNC_FL
on an ext4 nojournal fs. It didn't provide a reproducer itself. Sure, I'll try
to write a reproducer and include it in the commit message. I felt it wasn't
quite as important for this one compared to most of the other syzbot bugs, since
BSD process accounting can only be enabled by root, and once we're talking about
do_exit() being able to write an arbitrary file, it's not hard to see why
*something* could get tripped up by PF_MEMALLOC. There are probably other ways
it could cause problems besides this specific one. But sure, I'll try.
>
> I also note that cifs_demultiplex_thread() has the same problem -
> can you please do a complete audit of all the users of PF_MEMALLOC
> and fix all of them?
I already did, that's why at the same time I sent out this patch, I also sent
out one to fix cifs_demultiplex_thread()
(https://lkml.kernel.org/linux-cifs/20200308043645.1034870-1-ebiggers@kernel.org/T/#t).
These were the only two; I didn't find any others that needed to be fixed.
- Eric
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2] xfs: clear PF_MEMALLOC before exiting xfsaild thread
2020-03-09 1:04 ` Eric Biggers
@ 2020-03-09 4:34 ` Eric Biggers
2020-03-09 10:57 ` Brian Foster
2020-03-09 16:24 ` Darrick J. Wong
0 siblings, 2 replies; 12+ messages in thread
From: Eric Biggers @ 2020-03-09 4:34 UTC (permalink / raw)
To: linux-xfs; +Cc: linux-ext4, syzkaller-bugs, linux-kernel
From: Eric Biggers <ebiggers@google.com>
Leaving PF_MEMALLOC set when exiting a kthread causes it to remain set
during do_exit(). That can confuse things. For example, if BSD process
accounting is enabled and the accounting file has FS_SYNC_FL set and is
located on an ext4 filesystem without a journal, then do_exit() ends up
calling ext4_write_inode(). That triggers the
WARN_ON_ONCE(current->flags & PF_MEMALLOC) there, as it assumes
(appropriately) that inodes aren't written when allocating memory.
Fix this in xfsaild() by using the helper functions to save and restore
PF_MEMALLOC.
This can be reproduced as follows in the kvm-xfstests test appliance
modified to add the 'acct' Debian package, and with kvm-xfstests's
recommended kconfig modified to add CONFIG_BSD_PROCESS_ACCT=y:
mkfs.ext2 -F /dev/vdb
mount /vdb -t ext4
touch /vdb/file
chattr +S /vdb/file
accton /vdb/file
mkfs.xfs -f /dev/vdc
mount /vdc
umount /vdc
It causes:
WARNING: CPU: 0 PID: 332 at fs/ext4/inode.c:5097 ext4_write_inode+0x140/0x1a0
CPU: 0 PID: 332 Comm: xfsaild/vdc Not tainted 5.6.0-rc5 #5
[...]
RIP: 0010:ext4_write_inode+0x140/0x1a0 fs/ext4/inode.c:5097
[...]
Call Trace:
write_inode fs/fs-writeback.c:1312 [inline]
__writeback_single_inode+0x465/0x5f0 fs/fs-writeback.c:1511
writeback_single_inode+0xad/0x120 fs/fs-writeback.c:1565
sync_inode fs/fs-writeback.c:2602 [inline]
sync_inode_metadata+0x3d/0x57 fs/fs-writeback.c:2622
ext4_fsync_nojournal fs/ext4/fsync.c:94 [inline]
ext4_sync_file+0x243/0x4b0 fs/ext4/fsync.c:172
generic_write_sync include/linux/fs.h:2867 [inline]
ext4_buffered_write_iter+0xe1/0x130 fs/ext4/file.c:277
call_write_iter include/linux/fs.h:1901 [inline]
new_sync_write+0x130/0x1d0 fs/read_write.c:483
__kernel_write+0x54/0xe0 fs/read_write.c:515
do_acct_process+0x122/0x170 kernel/acct.c:522
slow_acct_process kernel/acct.c:581 [inline]
acct_process+0x1d4/0x27c kernel/acct.c:607
do_exit+0x83d/0xbc0 kernel/exit.c:791
kthread+0xf1/0x140 kernel/kthread.c:257
ret_from_fork+0x27/0x50 arch/x86/entry/entry_64.S:352
This case was originally reported by syzbot at
https://lore.kernel.org/r/0000000000000e7156059f751d7b@google.com.
Reported-by: syzbot+1f9dc49e8de2582d90c2@syzkaller.appspotmail.com
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
v2: include more details in the commit message.
fs/xfs/xfs_trans_ail.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index 00cc5b8734be8..3bc570c90ad97 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -529,8 +529,9 @@ xfsaild(
{
struct xfs_ail *ailp = data;
long tout = 0; /* milliseconds */
+ unsigned int noreclaim_flag;
- current->flags |= PF_MEMALLOC;
+ noreclaim_flag = memalloc_noreclaim_save();
set_freezable();
while (1) {
@@ -601,6 +602,7 @@ xfsaild(
tout = xfsaild_push(ailp);
}
+ memalloc_noreclaim_restore(noreclaim_flag);
return 0;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2] xfs: clear PF_MEMALLOC before exiting xfsaild thread
2020-03-09 4:34 ` [PATCH v2] " Eric Biggers
@ 2020-03-09 10:57 ` Brian Foster
2020-03-09 16:24 ` Darrick J. Wong
1 sibling, 0 replies; 12+ messages in thread
From: Brian Foster @ 2020-03-09 10:57 UTC (permalink / raw)
To: Eric Biggers; +Cc: linux-xfs, linux-ext4, syzkaller-bugs, linux-kernel
On Sun, Mar 08, 2020 at 09:34:30PM -0700, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
>
> Leaving PF_MEMALLOC set when exiting a kthread causes it to remain set
> during do_exit(). That can confuse things. For example, if BSD process
> accounting is enabled and the accounting file has FS_SYNC_FL set and is
> located on an ext4 filesystem without a journal, then do_exit() ends up
> calling ext4_write_inode(). That triggers the
> WARN_ON_ONCE(current->flags & PF_MEMALLOC) there, as it assumes
> (appropriately) that inodes aren't written when allocating memory.
>
> Fix this in xfsaild() by using the helper functions to save and restore
> PF_MEMALLOC.
>
> This can be reproduced as follows in the kvm-xfstests test appliance
> modified to add the 'acct' Debian package, and with kvm-xfstests's
> recommended kconfig modified to add CONFIG_BSD_PROCESS_ACCT=y:
>
> mkfs.ext2 -F /dev/vdb
> mount /vdb -t ext4
> touch /vdb/file
> chattr +S /vdb/file
> accton /vdb/file
> mkfs.xfs -f /dev/vdc
> mount /vdc
> umount /vdc
>
> It causes:
> WARNING: CPU: 0 PID: 332 at fs/ext4/inode.c:5097 ext4_write_inode+0x140/0x1a0
> CPU: 0 PID: 332 Comm: xfsaild/vdc Not tainted 5.6.0-rc5 #5
> [...]
> RIP: 0010:ext4_write_inode+0x140/0x1a0 fs/ext4/inode.c:5097
> [...]
> Call Trace:
> write_inode fs/fs-writeback.c:1312 [inline]
> __writeback_single_inode+0x465/0x5f0 fs/fs-writeback.c:1511
> writeback_single_inode+0xad/0x120 fs/fs-writeback.c:1565
> sync_inode fs/fs-writeback.c:2602 [inline]
> sync_inode_metadata+0x3d/0x57 fs/fs-writeback.c:2622
> ext4_fsync_nojournal fs/ext4/fsync.c:94 [inline]
> ext4_sync_file+0x243/0x4b0 fs/ext4/fsync.c:172
> generic_write_sync include/linux/fs.h:2867 [inline]
> ext4_buffered_write_iter+0xe1/0x130 fs/ext4/file.c:277
> call_write_iter include/linux/fs.h:1901 [inline]
> new_sync_write+0x130/0x1d0 fs/read_write.c:483
> __kernel_write+0x54/0xe0 fs/read_write.c:515
> do_acct_process+0x122/0x170 kernel/acct.c:522
> slow_acct_process kernel/acct.c:581 [inline]
> acct_process+0x1d4/0x27c kernel/acct.c:607
> do_exit+0x83d/0xbc0 kernel/exit.c:791
> kthread+0xf1/0x140 kernel/kthread.c:257
> ret_from_fork+0x27/0x50 arch/x86/entry/entry_64.S:352
>
> This case was originally reported by syzbot at
> https://lore.kernel.org/r/0000000000000e7156059f751d7b@google.com.
>
> Reported-by: syzbot+1f9dc49e8de2582d90c2@syzkaller.appspotmail.com
> Signed-off-by: Eric Biggers <ebiggers@google.com>
> ---
Reviewed-by: Brian Foster <bfoster@redhat.com>
>
> v2: include more details in the commit message.
>
> fs/xfs/xfs_trans_ail.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
> index 00cc5b8734be8..3bc570c90ad97 100644
> --- a/fs/xfs/xfs_trans_ail.c
> +++ b/fs/xfs/xfs_trans_ail.c
> @@ -529,8 +529,9 @@ xfsaild(
> {
> struct xfs_ail *ailp = data;
> long tout = 0; /* milliseconds */
> + unsigned int noreclaim_flag;
>
> - current->flags |= PF_MEMALLOC;
> + noreclaim_flag = memalloc_noreclaim_save();
> set_freezable();
>
> while (1) {
> @@ -601,6 +602,7 @@ xfsaild(
> tout = xfsaild_push(ailp);
> }
>
> + memalloc_noreclaim_restore(noreclaim_flag);
> return 0;
> }
>
> --
> 2.25.1
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2] xfs: clear PF_MEMALLOC before exiting xfsaild thread
2020-03-09 4:34 ` [PATCH v2] " Eric Biggers
2020-03-09 10:57 ` Brian Foster
@ 2020-03-09 16:24 ` Darrick J. Wong
2020-03-09 18:04 ` Eric Biggers
2020-03-12 22:20 ` [PATCH v2] " Eric Biggers
1 sibling, 2 replies; 12+ messages in thread
From: Darrick J. Wong @ 2020-03-09 16:24 UTC (permalink / raw)
To: Eric Biggers; +Cc: linux-xfs, linux-ext4, syzkaller-bugs, linux-kernel
On Sun, Mar 08, 2020 at 09:34:30PM -0700, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
>
> Leaving PF_MEMALLOC set when exiting a kthread causes it to remain set
> during do_exit(). That can confuse things. For example, if BSD process
> accounting is enabled and the accounting file has FS_SYNC_FL set and is
> located on an ext4 filesystem without a journal, then do_exit() ends up
> calling ext4_write_inode(). That triggers the
> WARN_ON_ONCE(current->flags & PF_MEMALLOC) there, as it assumes
> (appropriately) that inodes aren't written when allocating memory.
>
> Fix this in xfsaild() by using the helper functions to save and restore
> PF_MEMALLOC.
>
> This can be reproduced as follows in the kvm-xfstests test appliance
> modified to add the 'acct' Debian package, and with kvm-xfstests's
> recommended kconfig modified to add CONFIG_BSD_PROCESS_ACCT=y:
>
> mkfs.ext2 -F /dev/vdb
> mount /vdb -t ext4
> touch /vdb/file
> chattr +S /vdb/file
Does this trip if the process accounting file is also on an xfs
filesystem?
> accton /vdb/file
> mkfs.xfs -f /dev/vdc
> mount /vdc
> umount /vdc
...and if so, can this be turned into an fstests case, please?
>
> It causes:
> WARNING: CPU: 0 PID: 332 at fs/ext4/inode.c:5097 ext4_write_inode+0x140/0x1a0
> CPU: 0 PID: 332 Comm: xfsaild/vdc Not tainted 5.6.0-rc5 #5
> [...]
> RIP: 0010:ext4_write_inode+0x140/0x1a0 fs/ext4/inode.c:5097
> [...]
> Call Trace:
> write_inode fs/fs-writeback.c:1312 [inline]
> __writeback_single_inode+0x465/0x5f0 fs/fs-writeback.c:1511
> writeback_single_inode+0xad/0x120 fs/fs-writeback.c:1565
> sync_inode fs/fs-writeback.c:2602 [inline]
> sync_inode_metadata+0x3d/0x57 fs/fs-writeback.c:2622
> ext4_fsync_nojournal fs/ext4/fsync.c:94 [inline]
> ext4_sync_file+0x243/0x4b0 fs/ext4/fsync.c:172
> generic_write_sync include/linux/fs.h:2867 [inline]
> ext4_buffered_write_iter+0xe1/0x130 fs/ext4/file.c:277
> call_write_iter include/linux/fs.h:1901 [inline]
> new_sync_write+0x130/0x1d0 fs/read_write.c:483
> __kernel_write+0x54/0xe0 fs/read_write.c:515
> do_acct_process+0x122/0x170 kernel/acct.c:522
> slow_acct_process kernel/acct.c:581 [inline]
> acct_process+0x1d4/0x27c kernel/acct.c:607
> do_exit+0x83d/0xbc0 kernel/exit.c:791
> kthread+0xf1/0x140 kernel/kthread.c:257
> ret_from_fork+0x27/0x50 arch/x86/entry/entry_64.S:352
>
> This case was originally reported by syzbot at
> https://lore.kernel.org/r/0000000000000e7156059f751d7b@google.com.
>
> Reported-by: syzbot+1f9dc49e8de2582d90c2@syzkaller.appspotmail.com
> Signed-off-by: Eric Biggers <ebiggers@google.com>
Looks ok,
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
--D
> ---
>
> v2: include more details in the commit message.
>
> fs/xfs/xfs_trans_ail.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
> index 00cc5b8734be8..3bc570c90ad97 100644
> --- a/fs/xfs/xfs_trans_ail.c
> +++ b/fs/xfs/xfs_trans_ail.c
> @@ -529,8 +529,9 @@ xfsaild(
> {
> struct xfs_ail *ailp = data;
> long tout = 0; /* milliseconds */
> + unsigned int noreclaim_flag;
>
> - current->flags |= PF_MEMALLOC;
> + noreclaim_flag = memalloc_noreclaim_save();
> set_freezable();
>
> while (1) {
> @@ -601,6 +602,7 @@ xfsaild(
> tout = xfsaild_push(ailp);
> }
>
> + memalloc_noreclaim_restore(noreclaim_flag);
> return 0;
> }
>
> --
> 2.25.1
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2] xfs: clear PF_MEMALLOC before exiting xfsaild thread
2020-03-09 16:24 ` Darrick J. Wong
@ 2020-03-09 18:04 ` Eric Biggers
2020-03-09 18:13 ` Darrick J. Wong
2020-03-12 22:20 ` [PATCH v2] " Eric Biggers
1 sibling, 1 reply; 12+ messages in thread
From: Eric Biggers @ 2020-03-09 18:04 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: linux-xfs, linux-ext4, syzkaller-bugs, linux-kernel
On Mon, Mar 09, 2020 at 09:24:39AM -0700, Darrick J. Wong wrote:
> On Sun, Mar 08, 2020 at 09:34:30PM -0700, Eric Biggers wrote:
> > From: Eric Biggers <ebiggers@google.com>
> >
> > Leaving PF_MEMALLOC set when exiting a kthread causes it to remain set
> > during do_exit(). That can confuse things. For example, if BSD process
> > accounting is enabled and the accounting file has FS_SYNC_FL set and is
> > located on an ext4 filesystem without a journal, then do_exit() ends up
> > calling ext4_write_inode(). That triggers the
> > WARN_ON_ONCE(current->flags & PF_MEMALLOC) there, as it assumes
> > (appropriately) that inodes aren't written when allocating memory.
> >
> > Fix this in xfsaild() by using the helper functions to save and restore
> > PF_MEMALLOC.
> >
> > This can be reproduced as follows in the kvm-xfstests test appliance
> > modified to add the 'acct' Debian package, and with kvm-xfstests's
> > recommended kconfig modified to add CONFIG_BSD_PROCESS_ACCT=y:
> >
> > mkfs.ext2 -F /dev/vdb
> > mount /vdb -t ext4
> > touch /vdb/file
> > chattr +S /vdb/file
>
> Does this trip if the process accounting file is also on an xfs
> filesystem?
>
> > accton /vdb/file
> > mkfs.xfs -f /dev/vdc
> > mount /vdc
> > umount /vdc
>
> ...and if so, can this be turned into an fstests case, please?
I wasn't expecting it, but it turns out it does actually trip a similar warning
in iomap_do_writepage():
mkfs.xfs -f /dev/vdb
mount /vdb
touch /vdb/file
chattr +S /vdb/file
accton /vdb/file
mkfs.xfs -f /dev/vdc
mount /vdc
umount /vdc
causes...
WARNING: CPU: 1 PID: 336 at fs/iomap/buffered-io.c:1534
CPU: 1 PID: 336 Comm: xfsaild/vdc Not tainted 5.6.0-rc5 #3
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20191223_100556-anatol 04/01/2014
RIP: 0010:iomap_do_writepage+0x16b/0x1f0 fs/iomap/buffered-io.c:1534
[...]
Call Trace:
write_cache_pages+0x189/0x4d0 mm/page-writeback.c:2238
iomap_writepages+0x1c/0x33 fs/iomap/buffered-io.c:1642
xfs_vm_writepages+0x65/0x90 fs/xfs/xfs_aops.c:578
do_writepages+0x41/0xe0 mm/page-writeback.c:2344
__filemap_fdatawrite_range+0xd2/0x120 mm/filemap.c:421
file_write_and_wait_range+0x71/0xc0 mm/filemap.c:760
xfs_file_fsync+0x7a/0x2b0 fs/xfs/xfs_file.c:114
generic_write_sync include/linux/fs.h:2867 [inline]
xfs_file_buffered_aio_write+0x379/0x3b0 fs/xfs/xfs_file.c:691
call_write_iter include/linux/fs.h:1901 [inline]
new_sync_write+0x130/0x1d0 fs/read_write.c:483
__kernel_write+0x54/0xe0 fs/read_write.c:515
do_acct_process+0x122/0x170 kernel/acct.c:522
slow_acct_process kernel/acct.c:581 [inline]
acct_process+0x1d4/0x27c kernel/acct.c:607
do_exit+0x83d/0xbc0 kernel/exit.c:791
kthread+0xf1/0x140 kernel/kthread.c:257
ret_from_fork+0x27/0x50 arch/x86/entry/entry_64.S:352
So sure, since it's not necessarily a multi-filesystem thing, I can try to turn
it into an xfstest. There's currently no way to enable BSD process accounting
in xfstests though, so we'll either need to make the test depend on the 'acct'
program or add a helper test program.
Also, do you want me to update the commit message again, to mention the above
case?
- Eric
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2] xfs: clear PF_MEMALLOC before exiting xfsaild thread
2020-03-09 18:04 ` Eric Biggers
@ 2020-03-09 18:13 ` Darrick J. Wong
2020-03-09 18:57 ` [PATCH v3] " Eric Biggers
0 siblings, 1 reply; 12+ messages in thread
From: Darrick J. Wong @ 2020-03-09 18:13 UTC (permalink / raw)
To: Eric Biggers; +Cc: linux-xfs, linux-ext4, syzkaller-bugs, linux-kernel
On Mon, Mar 09, 2020 at 11:04:52AM -0700, Eric Biggers wrote:
> On Mon, Mar 09, 2020 at 09:24:39AM -0700, Darrick J. Wong wrote:
> > On Sun, Mar 08, 2020 at 09:34:30PM -0700, Eric Biggers wrote:
> > > From: Eric Biggers <ebiggers@google.com>
> > >
> > > Leaving PF_MEMALLOC set when exiting a kthread causes it to remain set
> > > during do_exit(). That can confuse things. For example, if BSD process
> > > accounting is enabled and the accounting file has FS_SYNC_FL set and is
> > > located on an ext4 filesystem without a journal, then do_exit() ends up
> > > calling ext4_write_inode(). That triggers the
> > > WARN_ON_ONCE(current->flags & PF_MEMALLOC) there, as it assumes
> > > (appropriately) that inodes aren't written when allocating memory.
> > >
> > > Fix this in xfsaild() by using the helper functions to save and restore
> > > PF_MEMALLOC.
> > >
> > > This can be reproduced as follows in the kvm-xfstests test appliance
> > > modified to add the 'acct' Debian package, and with kvm-xfstests's
> > > recommended kconfig modified to add CONFIG_BSD_PROCESS_ACCT=y:
> > >
> > > mkfs.ext2 -F /dev/vdb
> > > mount /vdb -t ext4
> > > touch /vdb/file
> > > chattr +S /vdb/file
> >
> > Does this trip if the process accounting file is also on an xfs
> > filesystem?
> >
> > > accton /vdb/file
> > > mkfs.xfs -f /dev/vdc
> > > mount /vdc
> > > umount /vdc
> >
> > ...and if so, can this be turned into an fstests case, please?
>
> I wasn't expecting it, but it turns out it does actually trip a similar warning
> in iomap_do_writepage():
>
> mkfs.xfs -f /dev/vdb
> mount /vdb
> touch /vdb/file
> chattr +S /vdb/file
> accton /vdb/file
> mkfs.xfs -f /dev/vdc
> mount /vdc
> umount /vdc
>
> causes...
>
> WARNING: CPU: 1 PID: 336 at fs/iomap/buffered-io.c:1534
> CPU: 1 PID: 336 Comm: xfsaild/vdc Not tainted 5.6.0-rc5 #3
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20191223_100556-anatol 04/01/2014
> RIP: 0010:iomap_do_writepage+0x16b/0x1f0 fs/iomap/buffered-io.c:1534
> [...]
> Call Trace:
> write_cache_pages+0x189/0x4d0 mm/page-writeback.c:2238
> iomap_writepages+0x1c/0x33 fs/iomap/buffered-io.c:1642
> xfs_vm_writepages+0x65/0x90 fs/xfs/xfs_aops.c:578
> do_writepages+0x41/0xe0 mm/page-writeback.c:2344
> __filemap_fdatawrite_range+0xd2/0x120 mm/filemap.c:421
> file_write_and_wait_range+0x71/0xc0 mm/filemap.c:760
> xfs_file_fsync+0x7a/0x2b0 fs/xfs/xfs_file.c:114
> generic_write_sync include/linux/fs.h:2867 [inline]
> xfs_file_buffered_aio_write+0x379/0x3b0 fs/xfs/xfs_file.c:691
> call_write_iter include/linux/fs.h:1901 [inline]
> new_sync_write+0x130/0x1d0 fs/read_write.c:483
> __kernel_write+0x54/0xe0 fs/read_write.c:515
> do_acct_process+0x122/0x170 kernel/acct.c:522
> slow_acct_process kernel/acct.c:581 [inline]
> acct_process+0x1d4/0x27c kernel/acct.c:607
> do_exit+0x83d/0xbc0 kernel/exit.c:791
> kthread+0xf1/0x140 kernel/kthread.c:257
> ret_from_fork+0x27/0x50 arch/x86/entry/entry_64.S:352
>
> So sure, since it's not necessarily a multi-filesystem thing, I can try to turn
> it into an xfstest. There's currently no way to enable BSD process accounting
> in xfstests though, so we'll either need to make the test depend on the 'acct'
> program or add a helper test program.
>
> Also, do you want me to update the commit message again, to mention the above
> case?
I think it's worth mentioning that this is a general problem that
applies any time the process accounting file has that sync flag set,
since this problem isn't specific to ext4 + xfs.
(and now I wonder how many other places in the kernel suffer from these
kinds of file write surprises...)
--D
> - Eric
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3] xfs: clear PF_MEMALLOC before exiting xfsaild thread
2020-03-09 18:13 ` Darrick J. Wong
@ 2020-03-09 18:57 ` Eric Biggers
2020-03-10 15:47 ` Darrick J. Wong
2020-03-11 6:34 ` Christoph Hellwig
0 siblings, 2 replies; 12+ messages in thread
From: Eric Biggers @ 2020-03-09 18:57 UTC (permalink / raw)
To: linux-xfs; +Cc: linux-ext4, syzkaller-bugs, linux-kernel
From: Eric Biggers <ebiggers@google.com>
Leaving PF_MEMALLOC set when exiting a kthread causes it to remain set
during do_exit(). That can confuse things. In particular, if BSD
process accounting is enabled, then do_exit() writes data to an
accounting file. If that file has FS_SYNC_FL set, then this write
occurs synchronously and can misbehave if PF_MEMALLOC is set.
For example, if the accounting file is located on an XFS filesystem,
then a WARN_ON_ONCE() in iomap_do_writepage() is triggered and the data
doesn't get written when it should. Or if the accounting file is
located on an ext4 filesystem without a journal, then a WARN_ON_ONCE()
in ext4_write_inode() is triggered and the inode doesn't get written.
Fix this in xfsaild() by using the helper functions to save and restore
PF_MEMALLOC.
This can be reproduced as follows in the kvm-xfstests test appliance
modified to add the 'acct' Debian package, and with kvm-xfstests's
recommended kconfig modified to add CONFIG_BSD_PROCESS_ACCT=y:
mkfs.xfs -f /dev/vdb
mount /vdb
touch /vdb/file
chattr +S /vdb/file
accton /vdb/file
mkfs.xfs -f /dev/vdc
mount /vdc
umount /vdc
It causes:
WARNING: CPU: 1 PID: 336 at fs/iomap/buffered-io.c:1534
CPU: 1 PID: 336 Comm: xfsaild/vdc Not tainted 5.6.0-rc5 #3
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20191223_100556-anatol 04/01/2014
RIP: 0010:iomap_do_writepage+0x16b/0x1f0 fs/iomap/buffered-io.c:1534
[...]
Call Trace:
write_cache_pages+0x189/0x4d0 mm/page-writeback.c:2238
iomap_writepages+0x1c/0x33 fs/iomap/buffered-io.c:1642
xfs_vm_writepages+0x65/0x90 fs/xfs/xfs_aops.c:578
do_writepages+0x41/0xe0 mm/page-writeback.c:2344
__filemap_fdatawrite_range+0xd2/0x120 mm/filemap.c:421
file_write_and_wait_range+0x71/0xc0 mm/filemap.c:760
xfs_file_fsync+0x7a/0x2b0 fs/xfs/xfs_file.c:114
generic_write_sync include/linux/fs.h:2867 [inline]
xfs_file_buffered_aio_write+0x379/0x3b0 fs/xfs/xfs_file.c:691
call_write_iter include/linux/fs.h:1901 [inline]
new_sync_write+0x130/0x1d0 fs/read_write.c:483
__kernel_write+0x54/0xe0 fs/read_write.c:515
do_acct_process+0x122/0x170 kernel/acct.c:522
slow_acct_process kernel/acct.c:581 [inline]
acct_process+0x1d4/0x27c kernel/acct.c:607
do_exit+0x83d/0xbc0 kernel/exit.c:791
kthread+0xf1/0x140 kernel/kthread.c:257
ret_from_fork+0x27/0x50 arch/x86/entry/entry_64.S:352
This bug was originally reported by syzbot at
https://lore.kernel.org/r/0000000000000e7156059f751d7b@google.com.
Reported-by: syzbot+1f9dc49e8de2582d90c2@syzkaller.appspotmail.com
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
v3: updated commit message again, this time to take into account the bug
also being reproducible when the accounting file is located on XFS.
v2: include more details in the commit message.
fs/xfs/xfs_trans_ail.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index 00cc5b8734be8..3bc570c90ad97 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -529,8 +529,9 @@ xfsaild(
{
struct xfs_ail *ailp = data;
long tout = 0; /* milliseconds */
+ unsigned int noreclaim_flag;
- current->flags |= PF_MEMALLOC;
+ noreclaim_flag = memalloc_noreclaim_save();
set_freezable();
while (1) {
@@ -601,6 +602,7 @@ xfsaild(
tout = xfsaild_push(ailp);
}
+ memalloc_noreclaim_restore(noreclaim_flag);
return 0;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v3] xfs: clear PF_MEMALLOC before exiting xfsaild thread
2020-03-09 18:57 ` [PATCH v3] " Eric Biggers
@ 2020-03-10 15:47 ` Darrick J. Wong
2020-03-11 6:34 ` Christoph Hellwig
1 sibling, 0 replies; 12+ messages in thread
From: Darrick J. Wong @ 2020-03-10 15:47 UTC (permalink / raw)
To: Eric Biggers; +Cc: linux-xfs, linux-ext4, syzkaller-bugs, linux-kernel
On Mon, Mar 09, 2020 at 11:57:14AM -0700, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
>
> Leaving PF_MEMALLOC set when exiting a kthread causes it to remain set
> during do_exit(). That can confuse things. In particular, if BSD
> process accounting is enabled, then do_exit() writes data to an
> accounting file. If that file has FS_SYNC_FL set, then this write
> occurs synchronously and can misbehave if PF_MEMALLOC is set.
>
> For example, if the accounting file is located on an XFS filesystem,
> then a WARN_ON_ONCE() in iomap_do_writepage() is triggered and the data
> doesn't get written when it should. Or if the accounting file is
> located on an ext4 filesystem without a journal, then a WARN_ON_ONCE()
> in ext4_write_inode() is triggered and the inode doesn't get written.
>
> Fix this in xfsaild() by using the helper functions to save and restore
> PF_MEMALLOC.
>
> This can be reproduced as follows in the kvm-xfstests test appliance
> modified to add the 'acct' Debian package, and with kvm-xfstests's
> recommended kconfig modified to add CONFIG_BSD_PROCESS_ACCT=y:
>
> mkfs.xfs -f /dev/vdb
> mount /vdb
> touch /vdb/file
> chattr +S /vdb/file
> accton /vdb/file
> mkfs.xfs -f /dev/vdc
> mount /vdc
> umount /vdc
>
> It causes:
> WARNING: CPU: 1 PID: 336 at fs/iomap/buffered-io.c:1534
> CPU: 1 PID: 336 Comm: xfsaild/vdc Not tainted 5.6.0-rc5 #3
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20191223_100556-anatol 04/01/2014
> RIP: 0010:iomap_do_writepage+0x16b/0x1f0 fs/iomap/buffered-io.c:1534
> [...]
> Call Trace:
> write_cache_pages+0x189/0x4d0 mm/page-writeback.c:2238
> iomap_writepages+0x1c/0x33 fs/iomap/buffered-io.c:1642
> xfs_vm_writepages+0x65/0x90 fs/xfs/xfs_aops.c:578
> do_writepages+0x41/0xe0 mm/page-writeback.c:2344
> __filemap_fdatawrite_range+0xd2/0x120 mm/filemap.c:421
> file_write_and_wait_range+0x71/0xc0 mm/filemap.c:760
> xfs_file_fsync+0x7a/0x2b0 fs/xfs/xfs_file.c:114
> generic_write_sync include/linux/fs.h:2867 [inline]
> xfs_file_buffered_aio_write+0x379/0x3b0 fs/xfs/xfs_file.c:691
> call_write_iter include/linux/fs.h:1901 [inline]
> new_sync_write+0x130/0x1d0 fs/read_write.c:483
> __kernel_write+0x54/0xe0 fs/read_write.c:515
> do_acct_process+0x122/0x170 kernel/acct.c:522
> slow_acct_process kernel/acct.c:581 [inline]
> acct_process+0x1d4/0x27c kernel/acct.c:607
> do_exit+0x83d/0xbc0 kernel/exit.c:791
> kthread+0xf1/0x140 kernel/kthread.c:257
> ret_from_fork+0x27/0x50 arch/x86/entry/entry_64.S:352
>
> This bug was originally reported by syzbot at
> https://lore.kernel.org/r/0000000000000e7156059f751d7b@google.com.
>
> Reported-by: syzbot+1f9dc49e8de2582d90c2@syzkaller.appspotmail.com
> Signed-off-by: Eric Biggers <ebiggers@google.com>
Seems reasonable to me, will give it a spin...
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
--D
> ---
>
> v3: updated commit message again, this time to take into account the bug
> also being reproducible when the accounting file is located on XFS.
>
> v2: include more details in the commit message.
>
> fs/xfs/xfs_trans_ail.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
> index 00cc5b8734be8..3bc570c90ad97 100644
> --- a/fs/xfs/xfs_trans_ail.c
> +++ b/fs/xfs/xfs_trans_ail.c
> @@ -529,8 +529,9 @@ xfsaild(
> {
> struct xfs_ail *ailp = data;
> long tout = 0; /* milliseconds */
> + unsigned int noreclaim_flag;
>
> - current->flags |= PF_MEMALLOC;
> + noreclaim_flag = memalloc_noreclaim_save();
> set_freezable();
>
> while (1) {
> @@ -601,6 +602,7 @@ xfsaild(
> tout = xfsaild_push(ailp);
> }
>
> + memalloc_noreclaim_restore(noreclaim_flag);
> return 0;
> }
>
> --
> 2.25.1
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3] xfs: clear PF_MEMALLOC before exiting xfsaild thread
2020-03-09 18:57 ` [PATCH v3] " Eric Biggers
2020-03-10 15:47 ` Darrick J. Wong
@ 2020-03-11 6:34 ` Christoph Hellwig
1 sibling, 0 replies; 12+ messages in thread
From: Christoph Hellwig @ 2020-03-11 6:34 UTC (permalink / raw)
To: Eric Biggers; +Cc: linux-xfs, linux-ext4, syzkaller-bugs, linux-kernel
Looks good,
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2] xfs: clear PF_MEMALLOC before exiting xfsaild thread
2020-03-09 16:24 ` Darrick J. Wong
2020-03-09 18:04 ` Eric Biggers
@ 2020-03-12 22:20 ` Eric Biggers
1 sibling, 0 replies; 12+ messages in thread
From: Eric Biggers @ 2020-03-12 22:20 UTC (permalink / raw)
To: Darrick J. Wong; +Cc: linux-xfs, linux-ext4, syzkaller-bugs, linux-kernel
On Mon, Mar 09, 2020 at 09:24:39AM -0700, Darrick J. Wong wrote:
> >
> > mkfs.ext2 -F /dev/vdb
> > mount /vdb -t ext4
> > touch /vdb/file
> > chattr +S /vdb/file
>
> Does this trip if the process accounting file is also on an xfs
> filesystem?
>
> > accton /vdb/file
> > mkfs.xfs -f /dev/vdc
> > mount /vdc
> > umount /vdc
>
> ...and if so, can this be turned into an fstests case, please?
>
Test sent out at
https://lkml.kernel.org/fstests/20200312221437.141484-1-ebiggers@kernel.org/
- Eric
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2020-03-12 22:20 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <0000000000000e7156059f751d7b@google.com>
2020-03-08 4:35 ` [PATCH] xfs: clear PF_MEMALLOC before exiting xfsaild thread Eric Biggers
2020-03-08 23:03 ` Dave Chinner
2020-03-09 1:04 ` Eric Biggers
2020-03-09 4:34 ` [PATCH v2] " Eric Biggers
2020-03-09 10:57 ` Brian Foster
2020-03-09 16:24 ` Darrick J. Wong
2020-03-09 18:04 ` Eric Biggers
2020-03-09 18:13 ` Darrick J. Wong
2020-03-09 18:57 ` [PATCH v3] " Eric Biggers
2020-03-10 15:47 ` Darrick J. Wong
2020-03-11 6:34 ` Christoph Hellwig
2020-03-12 22:20 ` [PATCH v2] " Eric Biggers
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox