Re: BUG: unable to handle kernel paging request in isolate_freepages_block

From: Dmitry Vyukov
Date: Thu May 09 2019 - 06:13:20 EST


> On Tue, May 07, 2019 at 02:50:05AM -0700, syzbot wrote:
> > Hello,
> >
> > syzbot found the following crash on:
> >
> > HEAD commit: baf76f0c slip: make slhc_free() silently accept an error p..
> > git tree: upstream
> > console output: https://syzkaller.appspot.com/x/log.txt?x=16dbe6cca00000
> > kernel config: https://syzkaller.appspot.com/x/.config?x=a42d110b47dd6b36
> > dashboard link: https://syzkaller.appspot.com/bug?extid=d84c80f9fe26a0f7a734
> > compiler: gcc (GCC) 9.0.0 20181231 (experimental)
> >
> > Unfortunately, I don't have any reproducer for this crash yet.
> >
>
> How reproducible is it and can the following (compile tested only) patch
> be tested please? I'm thinking it's a similar class of bug to 6b0868c820ff
> ("mm/compaction.c: correct zone boundary handling when resetting pageblock
> skip hints")

Hi Mel,

The info about reproducibility is always available on the dashboard:

> > dashboard link: https://syzkaller.appspot.com/bug?extid=d84c80f9fe26a0f7a734

So far it happened only 3 times which is not very frequent, 1 crash
every few days. syzbot did not come up with a reproducer so far.
If you think this should fix the bug, commit the patch, syzbot will
close the bug and then notify us again if the crash will happen again
after the patch reaches all tested trees.



> diff --git a/mm/compaction.c b/mm/compaction.c
> index 3319e0872d01..ae4d99d31b61 100644
> --- a/mm/compaction.c
> +++ b/mm/compaction.c
> @@ -1228,7 +1228,7 @@ fast_isolate_around(struct compact_control *cc, unsigned long pfn, unsigned long
>
> /* Pageblock boundaries */
> start_pfn = pageblock_start_pfn(pfn);
> - end_pfn = min(start_pfn + pageblock_nr_pages, zone_end_pfn(cc->zone));
> + end_pfn = min(start_pfn + pageblock_nr_pages, zone_end_pfn(cc->zone) - 1);
>
> /* Scan before */
> if (start_pfn != pfn) {
> @@ -1239,7 +1239,7 @@ fast_isolate_around(struct compact_control *cc, unsigned long pfn, unsigned long
>
> /* Scan after */
> start_pfn = pfn + nr_isolated;
> - if (start_pfn != end_pfn)
> + if (start_pfn < end_pfn)
> isolate_freepages_block(cc, &start_pfn, end_pfn, &cc->freepages, 1, false);
>
> /* Skip this pageblock in the future as it's full or nearly full */