[syzbot] [netfs?] kernel BUG in iov_iter_revert (2)

23 views
Skip to first unread message

syzbot

unread,
Oct 31, 2024, 9:07:30 AM10/31/24
to dhow...@redhat.com, jla...@kernel.org, linux-...@vger.kernel.org, linux-...@vger.kernel.org, ne...@lists.linux.dev, syzkall...@googlegroups.com
Hello,

syzbot found the following issue on:

HEAD commit: 850925a8133c Merge tag '9p-for-6.12-rc5' of https://github..
git tree: upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=17192940580000
kernel config: https://syzkaller.appspot.com/x/.config?x=309bb816d40abc28
dashboard link: https://syzkaller.appspot.com/bug?extid=404b4b745080b6210c6c
compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=10992940580000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=1503cca7980000

Downloadable assets:
disk image (non-bootable): https://storage.googleapis.com/syzbot-assets/7feb34a89c2a/non_bootable_disk-850925a8.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/c831c931f29c/vmlinux-850925a8.xz
kernel image: https://storage.googleapis.com/syzbot-assets/85f584e52a7f/bzImage-850925a8.xz

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+404b4b...@syzkaller.appspotmail.com

R10: 0000000000000002 R11: 0000000000000246 R12: 00007f40bfa2741c
R13: 00007ffe565206f0 R14: 00007f40bfa2a5a1 R15: 0000000000000001
</TASK>
------------[ cut here ]------------
kernel BUG at lib/iov_iter.c:624!
Oops: invalid opcode: 0000 [#1] PREEMPT SMP KASAN NOPTI
CPU: 0 UID: 0 PID: 5311 Comm: syz-executor145 Not tainted 6.12.0-rc4-syzkaller-00261-g850925a8133c #0
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014
RIP: 0010:iov_iter_revert+0x420/0x590 lib/iov_iter.c:624
Code: 42 80 3c 20 00 48 8b 1c 24 74 08 48 89 df e8 17 07 43 fd 4c 89 2b e9 04 01 00 00 45 85 ed 48 8b 3c 24 75 16 e8 41 48 d9 fc 90 <0f> 0b 41 83 fd 05 48 8b 3c 24 0f 84 58 01 00 00 48 89 f8 48 c1 e8
RSP: 0018:ffffc9000d09f740 EFLAGS: 00010293
RAX: ffffffff84bba22f RBX: 000000000001e098 RCX: ffff88801f03a440
RDX: 0000000000000000 RSI: ffffffff8f098180 RDI: ffff888048077cf0
RBP: 0000000000000000 R08: 0000000000000001 R09: ffffffff84bb9f14
R10: 0000000000000004 R11: ffff88801f03a440 R12: dffffc0000000000
R13: 0000000000000000 R14: ffff888048077ce0 R15: fffffffffffe1f68
FS: 000055556a75b380(0000) GS:ffff88801fc00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000555bd33aafa0 CR3: 0000000041784000 CR4: 0000000000352ef0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
<TASK>
netfs_reset_iter+0xce/0x130 fs/netfs/misc.c:133
netfs_clear_unread fs/netfs/read_collect.c:22 [inline]
netfs_read_subreq_terminated+0x1fe/0xad0 fs/netfs/read_collect.c:491
netfs_read_to_pagecache+0x628/0x900 fs/netfs/buffered_read.c:306
netfs_readahead+0x7e9/0x9d0 fs/netfs/buffered_read.c:421
read_pages+0x17e/0x840 mm/readahead.c:160
page_cache_ra_unbounded+0x774/0x8a0 mm/readahead.c:290
do_page_cache_ra mm/readahead.c:320 [inline]
force_page_cache_ra+0x280/0x2f0 mm/readahead.c:349
force_page_cache_readahead mm/internal.h:357 [inline]
generic_fadvise+0x522/0x830 mm/fadvise.c:106
ksys_readahead mm/readahead.c:695 [inline]
__do_sys_readahead mm/readahead.c:703 [inline]
__se_sys_readahead mm/readahead.c:701 [inline]
__x64_sys_readahead+0x1ac/0x230 mm/readahead.c:701
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f40bf9e5689
Code: 48 83 c4 28 c3 e8 17 1a 00 00 0f 1f 80 00 00 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007ffe565206c8 EFLAGS: 00000246 ORIG_RAX: 00000000000000bb
RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007f40bf9e5689
RDX: 000800000000000d RSI: 0000000000000005 RDI: 0000000000000006
RBP: 00007f40bfa273ee R08: 00007ffe56520466 R09: 0000550032313335
R10: 0000000000000002 R11: 0000000000000246 R12: 00007f40bfa2741c
R13: 00007ffe565206f0 R14: 00007f40bfa2a5a1 R15: 0000000000000001
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:iov_iter_revert+0x420/0x590 lib/iov_iter.c:624
Code: 42 80 3c 20 00 48 8b 1c 24 74 08 48 89 df e8 17 07 43 fd 4c 89 2b e9 04 01 00 00 45 85 ed 48 8b 3c 24 75 16 e8 41 48 d9 fc 90 <0f> 0b 41 83 fd 05 48 8b 3c 24 0f 84 58 01 00 00 48 89 f8 48 c1 e8
RSP: 0018:ffffc9000d09f740 EFLAGS: 00010293
RAX: ffffffff84bba22f RBX: 000000000001e098 RCX: ffff88801f03a440
RDX: 0000000000000000 RSI: ffffffff8f098180 RDI: ffff888048077cf0
RBP: 0000000000000000 R08: 0000000000000001 R09: ffffffff84bb9f14
R10: 0000000000000004 R11: ffff88801f03a440 R12: dffffc0000000000
R13: 0000000000000000 R14: ffff888048077ce0 R15: fffffffffffe1f68
FS: 000055556a75b380(0000) GS:ffff88801fc00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000555bd33aafa0 CR3: 0000000041784000 CR4: 0000000000352ef0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400


---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzk...@googlegroups.com.

syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.

If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title

If you want syzbot to run the reproducer, reply with:
#syz test: git://repo/address.git branch-or-commit-hash
If you attach or paste a git patch, syzbot will apply it before testing.

If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)

If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report

If you want to undo deduplication, reply with:
#syz undup

syzbot

unread,
Nov 1, 2024, 10:37:06 AM11/1/24
to linux-...@vger.kernel.org, syzkall...@googlegroups.com
For archival purposes, forwarding an incoming command email to
linux-...@vger.kernel.org, syzkall...@googlegroups.com.

***

Subject: Re: kernel BUG in iov_iter_revert (2)
Author: dman...@yandex.ru

#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 6c52d4da1c742cd01a797a4d0a2d3c5a60dc9bfe

diff --git a/fs/netfs/buffered_read.c b/fs/netfs/buffered_read.c
index af46a598f4d7..706862094c49 100644
--- a/fs/netfs/buffered_read.c
+++ b/fs/netfs/buffered_read.c
@@ -174,6 +174,21 @@ static ssize_t netfs_prepare_read_iterator(struct netfs_io_subrequest *subreq)
return subreq->len;
}

+/* Wrap the above by handling possible -ENOMEM and
+ * marking the corresponding subrequest as cancelled.
+ */
+static inline ssize_t netfs_wrap_read_iterator(struct netfs_io_subrequest *subreq)
+{
+ struct netfs_io_request *rreq = subreq->rreq;
+ ssize_t slice = netfs_prepare_read_iterator(subreq);
+
+ if (unlikely(slice < 0)) {
+ atomic_dec(&rreq->nr_outstanding);
+ netfs_put_subrequest(subreq, false, netfs_sreq_trace_put_cancel);
+ }
+ return slice;
+}
+
static enum netfs_io_source netfs_cache_prepare_read(struct netfs_io_request *rreq,
struct netfs_io_subrequest *subreq,
loff_t i_size)
@@ -284,10 +299,8 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
trace_netfs_sreq(subreq, netfs_sreq_trace_prepare);
}

- slice = netfs_prepare_read_iterator(subreq);
- if (slice < 0) {
- atomic_dec(&rreq->nr_outstanding);
- netfs_put_subrequest(subreq, false, netfs_sreq_trace_put_cancel);
+ slice = netfs_wrap_read_iterator(subreq);
+ if (unlikely(slice < 0)) {
ret = slice;
break;
}
@@ -301,7 +314,11 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
subreq->source = NETFS_FILL_WITH_ZEROES;
trace_netfs_sreq(subreq, netfs_sreq_trace_submit);
netfs_stat(&netfs_n_rh_zero);
- slice = netfs_prepare_read_iterator(subreq);
+ slice = netfs_wrap_read_iterator(subreq);
+ if (unlikely(slice < 0)) {
+ ret = slice;
+ break;
+ }
__set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags);
netfs_read_subreq_terminated(subreq, 0, false);
goto done;
@@ -309,7 +326,11 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)

if (source == NETFS_READ_FROM_CACHE) {
trace_netfs_sreq(subreq, netfs_sreq_trace_submit);
- slice = netfs_prepare_read_iterator(subreq);
+ slice = netfs_wrap_read_iterator(subreq);
+ if (unlikely(slice < 0)) {
+ ret = slice;
+ break;
+ }
netfs_read_cache_to_pagecache(rreq, subreq);
goto done;
}

syzbot

unread,
Nov 1, 2024, 10:57:05 AM11/1/24
to dman...@yandex.ru, linux-...@vger.kernel.org, syzkall...@googlegroups.com
Hello,

syzbot has tested the proposed patch and the reproducer did not trigger any issue:

Reported-by: syzbot+404b4b...@syzkaller.appspotmail.com
Tested-by: syzbot+404b4b...@syzkaller.appspotmail.com

Tested on:

commit: 6c52d4da Merge tag 'for-linus' of git://git.kernel.org..
git tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
console output: https://syzkaller.appspot.com/x/log.txt?x=150fb2a7980000
kernel config: https://syzkaller.appspot.com/x/.config?x=4aec7739e14231a7
dashboard link: https://syzkaller.appspot.com/bug?extid=404b4b745080b6210c6c
compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40
patch: https://syzkaller.appspot.com/x/patch.diff?x=14cbe630580000

Note: testing is done by a robot and is best-effort only.

syzbot

unread,
Nov 30, 2024, 9:44:05 AM11/30/24
to dhow...@redhat.com, dman...@yandex.ru, jla...@kernel.org, joanne...@gmail.com, jo...@toxicpanda.com, linux-...@vger.kernel.org, linux-...@vger.kernel.org, lvc-p...@linuxtesting.org, mik...@szeredi.hu, msze...@redhat.com, ne...@lists.linux.dev, syzkall...@googlegroups.com
syzbot has bisected this issue to:

commit 3b97c3652d9128ab7f8c9b8adec6108611fdb153
Author: Joanne Koong <joanne...@gmail.com>
Date: Thu Oct 24 17:18:08 2024 +0000

fuse: convert direct io to use folios

bisection log: https://syzkaller.appspot.com/x/bisect.txt?x=13e29f78580000
start commit: f486c8aa16b8 Add linux-next specific files for 20241128
git tree: linux-next
final oops: https://syzkaller.appspot.com/x/report.txt?x=10129f78580000
console output: https://syzkaller.appspot.com/x/log.txt?x=17e29f78580000
kernel config: https://syzkaller.appspot.com/x/.config?x=e348a4873516af92
dashboard link: https://syzkaller.appspot.com/bug?extid=404b4b745080b6210c6c
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=131f71e8580000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=12bc200f980000

Reported-by: syzbot+404b4b...@syzkaller.appspotmail.com
Fixes: 3b97c3652d91 ("fuse: convert direct io to use folios")

For information about bisection process see: https://goo.gl/tpsmEJ#bisection

syzbot

unread,
Dec 2, 2024, 4:01:04 AM12/2/24
to linux-...@vger.kernel.org, syzkall...@googlegroups.com
For archival purposes, forwarding an incoming command email to
linux-...@vger.kernel.org, syzkall...@googlegroups.com.

***

Subject: Re: kernel BUG in iov_iter_revert()
Author: dman...@yandex.ru

#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git e70140ba0d2b1a30467d4af6bcfe761327b9ec95

diff --git a/fs/netfs/buffered_read.c b/fs/netfs/buffered_read.c
index 7ac34550c403..4404f3c6ec3e 100644
--- a/fs/netfs/buffered_read.c
+++ b/fs/netfs/buffered_read.c
@@ -95,7 +95,7 @@ static size_t netfs_load_buffer_from_ra(struct netfs_io_request *rreq,
}

/*
- * netfs_prepare_read_iterator - Prepare the subreq iterator for I/O
+ * __netfs_prepare_read_iterator - Prepare the subreq iterator for I/O
* @subreq: The subrequest to be set up
*
* Prepare the I/O iterator representing the read buffer on a subrequest for
@@ -109,7 +109,7 @@ static size_t netfs_load_buffer_from_ra(struct netfs_io_request *rreq,
* [!] NOTE: This must be run in the same thread as ->issue_read() was called
* in as we access the readahead_control struct.
*/
-static ssize_t netfs_prepare_read_iterator(struct netfs_io_subrequest *subreq)
+static ssize_t __netfs_prepare_read_iterator(struct netfs_io_subrequest *subreq)
{
struct netfs_io_request *rreq = subreq->rreq;
size_t rsize = subreq->len;
@@ -174,6 +174,21 @@ static ssize_t netfs_prepare_read_iterator(struct netfs_io_subrequest *subreq)
return subreq->len;
}

+/* Wrap the above by handling possible -ENOMEM and
+ * marking the corresponding subrequest as cancelled.
+ */
+static inline ssize_t netfs_prepare_read_iterator(struct netfs_io_subrequest *subreq)
+{
+ struct netfs_io_request *rreq = subreq->rreq;
+ ssize_t slice = __netfs_prepare_read_iterator(subreq);
+
+ if (unlikely(slice < 0)) {
+ atomic_dec(&rreq->nr_outstanding);
+ netfs_put_subrequest(subreq, false, netfs_sreq_trace_put_cancel);
+ }
+ return slice;
+}
+
static enum netfs_io_source netfs_cache_prepare_read(struct netfs_io_request *rreq,
struct netfs_io_subrequest *subreq,
loff_t i_size)
@@ -285,9 +300,7 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
}

slice = netfs_prepare_read_iterator(subreq);
- if (slice < 0) {
- atomic_dec(&rreq->nr_outstanding);
- netfs_put_subrequest(subreq, false, netfs_sreq_trace_put_cancel);
+ if (unlikely(slice < 0)) {
ret = slice;
break;
}
@@ -302,6 +315,10 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
trace_netfs_sreq(subreq, netfs_sreq_trace_submit);
netfs_stat(&netfs_n_rh_zero);
slice = netfs_prepare_read_iterator(subreq);
+ if (unlikely(slice < 0)) {
+ ret = slice;
+ break;
+ }
__set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags);
netfs_read_subreq_terminated(subreq, 0, false);
goto done;
@@ -310,6 +327,10 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
if (source == NETFS_READ_FROM_CACHE) {
trace_netfs_sreq(subreq, netfs_sreq_trace_submit);
slice = netfs_prepare_read_iterator(subreq);
+ if (unlikely(slice < 0)) {
+ ret = slice;
+ break;
+ }
netfs_read_cache_to_pagecache(rreq, subreq);
goto done;
}
--
2.47.1

syzbot

unread,
Dec 2, 2024, 4:21:03 AM12/2/24
to dman...@yandex.ru, linux-...@vger.kernel.org, syzkall...@googlegroups.com
Hello,

syzbot has tested the proposed patch and the reproducer did not trigger any issue:

Reported-by: syzbot+404b4b...@syzkaller.appspotmail.com
Tested-by: syzbot+404b4b...@syzkaller.appspotmail.com

Tested on:

commit: e70140ba Get rid of 'remove_new' relic from platform d..
git tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
console output: https://syzkaller.appspot.com/x/log.txt?x=16fe50df980000
kernel config: https://syzkaller.appspot.com/x/.config?x=58639d2215ba9a07
dashboard link: https://syzkaller.appspot.com/bug?extid=404b4b745080b6210c6c
compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40
patch: https://syzkaller.appspot.com/x/patch.diff?x=105217c0580000

David Howells

unread,
Dec 4, 2024, 9:00:00 AM12/4/24
to syzbot, dhow...@redhat.com, jla...@kernel.org, linux-...@vger.kernel.org, linux-...@vger.kernel.org, ne...@lists.linux.dev, syzkall...@googlegroups.com
#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git v6.13-rc1

netfs: Fix enomem handling in buffered reads

If netfs_read_to_pagecache() gets an error from either ->prepare_read() or
from netfs_prepare_read_iterator(), it needs to decrement ->nr_outstanding,
cancel the subrequest and break out of the issuing loop. Currently, it
only does this for two of the cases, but there are two more that aren't
handled.

Fix this by moving the handling to a common place and jumping to it from
all four places. This is in preference to inserting a wrapper around
netfs_prepare_read_iterator() as proposed by Dmitry Antipov[1].

Fixes: ee4cdf7ba857 ("netfs: Speed up buffered reading")
Reported-by: syzbot+404b4b...@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=404b4b745080b6210c6c
Signed-off-by: David Howells <dhow...@redhat.com>
cc: Dmitry Antipov <dman...@yandex.ru>
cc: Jeff Layton <jla...@kernel.org>
cc: ne...@lists.linux.dev
cc: linux-...@vger.kernel.org
Link: https://lore.kernel.org/r/20241202093943.2...@yandex.ru/ [1]
---
fs/netfs/buffered_read.c | 27 +++++++++++++++------------
1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/fs/netfs/buffered_read.c b/fs/netfs/buffered_read.c
index 7ac34550c403..e5c7dd5a4c90 100644
--- a/fs/netfs/buffered_read.c
+++ b/fs/netfs/buffered_read.c
@@ -275,22 +275,14 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
netfs_stat(&netfs_n_rh_download);
if (rreq->netfs_ops->prepare_read) {
ret = rreq->netfs_ops->prepare_read(subreq);
- if (ret < 0) {
- atomic_dec(&rreq->nr_outstanding);
- netfs_put_subrequest(subreq, false,
- netfs_sreq_trace_put_cancel);
- break;
- }
+ if (ret < 0)
+ goto prep_failed;
trace_netfs_sreq(subreq, netfs_sreq_trace_prepare);
}

slice = netfs_prepare_read_iterator(subreq);
- if (slice < 0) {
- atomic_dec(&rreq->nr_outstanding);
- netfs_put_subrequest(subreq, false, netfs_sreq_trace_put_cancel);
- ret = slice;
- break;
- }
+ if (slice < 0)
+ goto prep_failed;

rreq->netfs_ops->issue_read(subreq);
goto done;
@@ -302,6 +294,8 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
trace_netfs_sreq(subreq, netfs_sreq_trace_submit);
netfs_stat(&netfs_n_rh_zero);
slice = netfs_prepare_read_iterator(subreq);
+ if (slice < 0)
+ goto prep_failed;
__set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags);
netfs_read_subreq_terminated(subreq, 0, false);
goto done;
@@ -310,6 +304,8 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
if (source == NETFS_READ_FROM_CACHE) {
trace_netfs_sreq(subreq, netfs_sreq_trace_submit);
slice = netfs_prepare_read_iterator(subreq);
+ if (slice < 0)
+ goto prep_failed;
netfs_read_cache_to_pagecache(rreq, subreq);
goto done;
}
@@ -318,6 +314,13 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
WARN_ON_ONCE(1);
break;

+ prep_failed:
+ ret = slice;
+ subreq->error = ret;
+ atomic_dec(&rreq->nr_outstanding);
+ netfs_put_subrequest(subreq, false, netfs_sreq_trace_put_cancel);
+ break;
+
done:
size -= slice;
start += slice;

David Howells

unread,
Dec 4, 2024, 9:11:37 AM12/4/24
to syzbot, dhow...@redhat.com, jla...@kernel.org, linux-...@vger.kernel.org, linux-...@vger.kernel.org, ne...@lists.linux.dev, syzkall...@googlegroups.com
#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git v6.13-rc1

netfs: Fix enomem handling in buffered reads

If netfs_read_to_pagecache() gets an error from either ->prepare_read() or
from netfs_prepare_read_iterator(), it needs to decrement ->nr_outstanding,
cancel the subrequest and break out of the issuing loop. Currently, it
only does this for two of the cases, but there are two more that aren't
handled.

Fix this by moving the handling to a common place and jumping to it from
all four places. This is in preference to inserting a wrapper around
netfs_prepare_read_iterator() as proposed by Dmitry Antipov[1].

Fixes: ee4cdf7ba857 ("netfs: Speed up buffered reading")
Reported-by: syzbot+404b4b...@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=404b4b745080b6210c6c
Signed-off-by: David Howells <dhow...@redhat.com>
cc: Dmitry Antipov <dman...@yandex.ru>
cc: Jeff Layton <jla...@kernel.org>
cc: ne...@lists.linux.dev
cc: linux-...@vger.kernel.org
Link: https://lore.kernel.org/r/20241202093943.2...@yandex.ru/ [1]
---
fs/netfs/buffered_read.c | 28 ++++++++++++++++------------
1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/fs/netfs/buffered_read.c b/fs/netfs/buffered_read.c
index 7ac34550c403..4dc9b8286355 100644
--- a/fs/netfs/buffered_read.c
+++ b/fs/netfs/buffered_read.c
@@ -275,22 +275,14 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
netfs_stat(&netfs_n_rh_download);
if (rreq->netfs_ops->prepare_read) {
ret = rreq->netfs_ops->prepare_read(subreq);
- if (ret < 0) {
- atomic_dec(&rreq->nr_outstanding);
- netfs_put_subrequest(subreq, false,
- netfs_sreq_trace_put_cancel);
- break;
- }
+ if (ret < 0)
+ goto prep_failed;
trace_netfs_sreq(subreq, netfs_sreq_trace_prepare);
}

slice = netfs_prepare_read_iterator(subreq);
- if (slice < 0) {
- atomic_dec(&rreq->nr_outstanding);
- netfs_put_subrequest(subreq, false, netfs_sreq_trace_put_cancel);
- ret = slice;
- break;
- }
+ if (slice < 0)
+ goto prep_iter_failed;

rreq->netfs_ops->issue_read(subreq);
goto done;
@@ -302,6 +294,8 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
trace_netfs_sreq(subreq, netfs_sreq_trace_submit);
netfs_stat(&netfs_n_rh_zero);
slice = netfs_prepare_read_iterator(subreq);
+ if (slice < 0)
+ goto prep_iter_failed;
__set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags);
netfs_read_subreq_terminated(subreq, 0, false);
goto done;
@@ -310,6 +304,8 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
if (source == NETFS_READ_FROM_CACHE) {
trace_netfs_sreq(subreq, netfs_sreq_trace_submit);
slice = netfs_prepare_read_iterator(subreq);
+ if (slice < 0)
+ goto prep_iter_failed;
netfs_read_cache_to_pagecache(rreq, subreq);
goto done;
}
@@ -318,6 +314,14 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
WARN_ON_ONCE(1);
break;

+ prep_iter_failed:
+ ret = slice;
+ prep_failed:

syzbot

unread,
Dec 4, 2024, 9:20:05 AM12/4/24
to dhow...@redhat.com, jla...@kernel.org, linux-...@vger.kernel.org, linux-...@vger.kernel.org, ne...@lists.linux.dev, syzkall...@googlegroups.com
Hello,

syzbot has tested the proposed patch and the reproducer did not trigger any issue:

Reported-by: syzbot+404b4b...@syzkaller.appspotmail.com
Tested-by: syzbot+404b4b...@syzkaller.appspotmail.com

Tested on:

commit: 40384c84 Linux 6.13-rc1
git tree: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git v6.13-rc1
console output: https://syzkaller.appspot.com/x/log.txt?x=11f960f8580000
kernel config: https://syzkaller.appspot.com/x/.config?x=58639d2215ba9a07
dashboard link: https://syzkaller.appspot.com/bug?extid=404b4b745080b6210c6c
compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40
patch: https://syzkaller.appspot.com/x/patch.diff?x=1249a330580000

syzbot

unread,
Dec 4, 2024, 9:39:05 AM12/4/24
to dhow...@redhat.com, jla...@kernel.org, linux-...@vger.kernel.org, linux-...@vger.kernel.org, ne...@lists.linux.dev, syzkall...@googlegroups.com
Hello,

syzbot has tested the proposed patch but the reproducer is still triggering an issue:
possible deadlock in __submit_bio

======================================================
WARNING: possible circular locking dependency detected
6.13.0-rc1-syzkaller-dirty #0 Not tainted
------------------------------------------------------
kswapd0/75 is trying to acquire lock:
ffff888034c41438 (&q->q_usage_counter(io)#37){++++}-{0:0}, at: __submit_bio+0x2c6/0x560 block/blk-core.c:629

but task is already holding lock:
ffffffff8ea35b00 (fs_reclaim){+.+.}-{0:0}, at: balance_pgdat mm/vmscan.c:6864 [inline]
ffffffff8ea35b00 (fs_reclaim){+.+.}-{0:0}, at: kswapd+0xbf1/0x36f0 mm/vmscan.c:7246

which lock already depends on the new lock.


the existing dependency chain (in reverse order) is:

-> #1 (fs_reclaim){+.+.}-{0:0}:
lock_acquire+0x1ed/0x550 kernel/locking/lockdep.c:5849
__fs_reclaim_acquire mm/page_alloc.c:3851 [inline]
fs_reclaim_acquire+0x88/0x130 mm/page_alloc.c:3865
might_alloc include/linux/sched/mm.h:318 [inline]
slab_pre_alloc_hook mm/slub.c:4055 [inline]
slab_alloc_node mm/slub.c:4133 [inline]
__do_kmalloc_node mm/slub.c:4282 [inline]
__kmalloc_node_noprof+0xb2/0x4d0 mm/slub.c:4289
__kvmalloc_node_noprof+0x72/0x190 mm/util.c:650
sbitmap_init_node+0x2d4/0x670 lib/sbitmap.c:132
scsi_realloc_sdev_budget_map+0x2a7/0x460 drivers/scsi/scsi_scan.c:246
scsi_add_lun drivers/scsi/scsi_scan.c:1106 [inline]
scsi_probe_and_add_lun+0x3173/0x4bd0 drivers/scsi/scsi_scan.c:1287
__scsi_add_device+0x228/0x2f0 drivers/scsi/scsi_scan.c:1622
ata_scsi_scan_host+0x236/0x740 drivers/ata/libata-scsi.c:4575
async_run_entry_fn+0xa8/0x420 kernel/async.c:129
process_one_work kernel/workqueue.c:3229 [inline]
process_scheduled_works+0xa66/0x1840 kernel/workqueue.c:3310
worker_thread+0x870/0xd30 kernel/workqueue.c:3391
kthread+0x2f0/0x390 kernel/kthread.c:389
ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244

-> #0 (&q->q_usage_counter(io)#37){++++}-{0:0}:
check_prev_add kernel/locking/lockdep.c:3161 [inline]
check_prevs_add kernel/locking/lockdep.c:3280 [inline]
validate_chain+0x18ef/0x5920 kernel/locking/lockdep.c:3904
__lock_acquire+0x1397/0x2100 kernel/locking/lockdep.c:5226
lock_acquire+0x1ed/0x550 kernel/locking/lockdep.c:5849
bio_queue_enter block/blk.h:75 [inline]
blk_mq_submit_bio+0x1536/0x2390 block/blk-mq.c:3091
__submit_bio+0x2c6/0x560 block/blk-core.c:629
__submit_bio_noacct_mq block/blk-core.c:710 [inline]
submit_bio_noacct_nocheck+0x4d3/0xe30 block/blk-core.c:739
swap_writepage_bdev_async mm/page_io.c:451 [inline]
__swap_writepage+0x5fc/0x1400 mm/page_io.c:474
swap_writepage+0x8f4/0x1170 mm/page_io.c:289
pageout mm/vmscan.c:689 [inline]
shrink_folio_list+0x3c0e/0x8cb0 mm/vmscan.c:1367
evict_folios+0x5568/0x7be0 mm/vmscan.c:4593
try_to_shrink_lruvec+0x9a6/0xc70 mm/vmscan.c:4789
shrink_one+0x3b9/0x850 mm/vmscan.c:4834
shrink_many mm/vmscan.c:4897 [inline]
lru_gen_shrink_node mm/vmscan.c:4975 [inline]
shrink_node+0x37c5/0x3e50 mm/vmscan.c:5956
kswapd_shrink_node mm/vmscan.c:6785 [inline]
balance_pgdat mm/vmscan.c:6977 [inline]
kswapd+0x1ca9/0x36f0 mm/vmscan.c:7246
kthread+0x2f0/0x390 kernel/kthread.c:389
ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244

other info that might help us debug this:

Possible unsafe locking scenario:

CPU0 CPU1
---- ----
lock(fs_reclaim);
lock(&q->q_usage_counter(io)#37);
lock(fs_reclaim);
rlock(&q->q_usage_counter(io)#37);

*** DEADLOCK ***

1 lock held by kswapd0/75:
#0: ffffffff8ea35b00 (fs_reclaim){+.+.}-{0:0}, at: balance_pgdat mm/vmscan.c:6864 [inline]
#0: ffffffff8ea35b00 (fs_reclaim){+.+.}-{0:0}, at: kswapd+0xbf1/0x36f0 mm/vmscan.c:7246

stack backtrace:
CPU: 0 UID: 0 PID: 75 Comm: kswapd0 Not tainted 6.13.0-rc1-syzkaller-dirty #0
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:94 [inline]
dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120
print_circular_bug+0x13a/0x1b0 kernel/locking/lockdep.c:2074
check_noncircular+0x36a/0x4a0 kernel/locking/lockdep.c:2206
check_prev_add kernel/locking/lockdep.c:3161 [inline]
check_prevs_add kernel/locking/lockdep.c:3280 [inline]
validate_chain+0x18ef/0x5920 kernel/locking/lockdep.c:3904
__lock_acquire+0x1397/0x2100 kernel/locking/lockdep.c:5226
lock_acquire+0x1ed/0x550 kernel/locking/lockdep.c:5849
bio_queue_enter block/blk.h:75 [inline]
blk_mq_submit_bio+0x1536/0x2390 block/blk-mq.c:3091
__submit_bio+0x2c6/0x560 block/blk-core.c:629
__submit_bio_noacct_mq block/blk-core.c:710 [inline]
submit_bio_noacct_nocheck+0x4d3/0xe30 block/blk-core.c:739
swap_writepage_bdev_async mm/page_io.c:451 [inline]
__swap_writepage+0x5fc/0x1400 mm/page_io.c:474
swap_writepage+0x8f4/0x1170 mm/page_io.c:289
pageout mm/vmscan.c:689 [inline]
shrink_folio_list+0x3c0e/0x8cb0 mm/vmscan.c:1367
evict_folios+0x5568/0x7be0 mm/vmscan.c:4593
try_to_shrink_lruvec+0x9a6/0xc70 mm/vmscan.c:4789
shrink_one+0x3b9/0x850 mm/vmscan.c:4834
shrink_many mm/vmscan.c:4897 [inline]
lru_gen_shrink_node mm/vmscan.c:4975 [inline]
shrink_node+0x37c5/0x3e50 mm/vmscan.c:5956
kswapd_shrink_node mm/vmscan.c:6785 [inline]
balance_pgdat mm/vmscan.c:6977 [inline]
kswapd+0x1ca9/0x36f0 mm/vmscan.c:7246
kthread+0x2f0/0x390 kernel/kthread.c:389
ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
</TASK>


Tested on:

commit: 40384c84 Linux 6.13-rc1
git tree: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git v6.13-rc1
console output: https://syzkaller.appspot.com/x/log.txt?x=101560f8580000
kernel config: https://syzkaller.appspot.com/x/.config?x=58639d2215ba9a07
dashboard link: https://syzkaller.appspot.com/bug?extid=404b4b745080b6210c6c
compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40
patch: https://syzkaller.appspot.com/x/patch.diff?x=138c4de8580000

David Howells

unread,
Dec 4, 2024, 9:43:27 AM12/4/24
to syzbot, dhow...@redhat.com, jla...@kernel.org, linux-...@vger.kernel.org, linux-...@vger.kernel.org, ne...@lists.linux.dev, syzkall...@googlegroups.com
This looks like it's probably a separate bug.

David

David Howells

unread,
Dec 5, 2024, 4:39:18 AM12/5/24
to syzbot, dhow...@redhat.com, jla...@kernel.org, Ming Lei, Jens Axboe, ne...@lists.linux.dev, linux...@vger.kernel.org, linux-...@vger.kernel.org, linux-...@vger.kernel.org, syzkall...@googlegroups.com

syzbot

unread,
Dec 5, 2024, 4:59:05 AM12/5/24
to ax...@kernel.dk, dhow...@redhat.com, jla...@kernel.org, linux...@vger.kernel.org, linux-...@vger.kernel.org, linux-...@vger.kernel.org, ming...@redhat.com, ne...@lists.linux.dev, syzkall...@googlegroups.com
Hello,

syzbot has tested the proposed patch and the reproducer did not trigger any issue:

Reported-by: syzbot+404b4b...@syzkaller.appspotmail.com
Tested-by: syzbot+404b4b...@syzkaller.appspotmail.com

Tested on:

commit: c018ec9d block: rnull: Initialize the module in place
git tree: https://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git for-6.14/block
console output: https://syzkaller.appspot.com/x/log.txt?x=159ca8df980000
kernel config: https://syzkaller.appspot.com/x/.config?x=58639d2215ba9a07
dashboard link: https://syzkaller.appspot.com/bug?extid=404b4b745080b6210c6c
compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40
patch: https://syzkaller.appspot.com/x/patch.diff?x=14b910f8580000
Reply all
Reply to author
Forward
0 new messages