| From c572e4888ad1be123c1516ec577ad30a700bbec4 Mon Sep 17 00:00:00 2001 |
| From: Mel Gorman <mgorman@techsingularity.net> |
| Date: Thu, 26 May 2022 10:12:10 +0100 |
| Subject: mm/page_alloc: always attempt to allocate at least one page during bulk allocation |
| |
| From: Mel Gorman <mgorman@techsingularity.net> |
| |
| commit c572e4888ad1be123c1516ec577ad30a700bbec4 upstream. |
| |
| Peter Pavlisko reported the following problem on kernel bugzilla 216007. |
| |
| When I try to extract an uncompressed tar archive (2.6 milion |
| files, 760.3 GiB in size) on newly created (empty) XFS file system, |
| after first low tens of gigabytes extracted the process hangs in |
| iowait indefinitely. One CPU core is 100% occupied with iowait, |
| the other CPU core is idle (on 2-core Intel Celeron G1610T). |
| |
| It was bisected to c9fa563072e1 ("xfs: use alloc_pages_bulk_array() for |
| buffers") but XFS is only the messenger. The problem is that nothing is |
| waking kswapd to reclaim some pages at a time the PCP lists cannot be |
| refilled until some reclaim happens. The bulk allocator checks that there |
| are some pages in the array and the original intent was that a bulk |
| allocator did not necessarily need all the requested pages and it was best |
| to return as quickly as possible. |
| |
| This was fine for the first user of the API but both NFS and XFS require |
| the requested number of pages be available before making progress. Both |
| could be adjusted to call the page allocator directly if a bulk allocation |
| fails but it puts a burden on users of the API. Adjust the semantics to |
| attempt at least one allocation via __alloc_pages() before returning so |
| kswapd is woken if necessary. |
| |
| It was reported via bugzilla that the patch addressed the problem and that |
| the tar extraction completed successfully. This may also address bug |
| 215975 but has yet to be confirmed. |
| |
| BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=216007 |
| BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=215975 |
| Link: https://lkml.kernel.org/r/20220526091210.GC3441@techsingularity.net |
| Fixes: 387ba26fb1cb ("mm/page_alloc: add a bulk page allocator") |
| Signed-off-by: Mel Gorman <mgorman@techsingularity.net> |
| Cc: "Darrick J. Wong" <djwong@kernel.org> |
| Cc: Dave Chinner <dchinner@redhat.com> |
| Cc: Jan Kara <jack@suse.cz> |
| Cc: Vlastimil Babka <vbabka@suse.cz> |
| Cc: Jesper Dangaard Brouer <brouer@redhat.com> |
| Cc: Chuck Lever <chuck.lever@oracle.com> |
| Cc: <stable@vger.kernel.org> [5.13+] |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| mm/page_alloc.c | 4 ++-- |
| 1 file changed, 2 insertions(+), 2 deletions(-) |
| |
| --- a/mm/page_alloc.c |
| +++ b/mm/page_alloc.c |
| @@ -5324,8 +5324,8 @@ unsigned long __alloc_pages_bulk(gfp_t g |
| page = __rmqueue_pcplist(zone, 0, ac.migratetype, alloc_flags, |
| pcp, pcp_list); |
| if (unlikely(!page)) { |
| - /* Try and get at least one page */ |
| - if (!nr_populated) |
| + /* Try and allocate at least one page */ |
| + if (!nr_account) |
| goto failed_irq; |
| break; |
| } |