diff options
author | Yosry Ahmed <yosryahmed@google.com> | 2024-03-11 20:43:46 +0100 |
---|---|---|
committer | Andrew Morton <akpm@linux-foundation.org> | 2024-04-26 05:55:49 +0200 |
commit | 2ccd48ce35e87f09472b42dda96fbf7b5165f3c3 (patch) | |
tree | 1ccc98877cb2fa3645f95c17faa1610f6bd9ba14 /mm/percpu-vm.c | |
parent | mm/numa_balancing: allow migrate on protnone reference with MPOL_PREFERRED_MA... (diff) | |
download | linux-2ccd48ce35e87f09472b42dda96fbf7b5165f3c3.tar.xz linux-2ccd48ce35e87f09472b42dda96fbf7b5165f3c3.zip |
percpu: clean up all mappings when pcpu_map_pages() fails
In pcpu_map_pages(), if __pcpu_map_pages() fails on a CPU, we call
__pcpu_unmap_pages() to clean up mappings on all CPUs where mappings were
created, but not on the CPU where __pcpu_map_pages() fails.
__pcpu_map_pages() and __pcpu_unmap_pages() are wrappers around
vmap_pages_range_noflush() and vunmap_range_noflush(). All other callers
of vmap_pages_range_noflush() call vunmap_range_noflush() when mapping
fails, except pcpu_map_pages(). The reason could be that partial mappings
may be left behind from a failed mapping attempt.
Call __pcpu_unmap_pages() for the failed CPU as well in pcpu_map_pages().
This was found by code inspection, no failures or bugs were observed.
Link: https://lkml.kernel.org/r/20240311194346.2291333-1-yosryahmed@google.com
Signed-off-by: Yosry Ahmed <yosryahmed@google.com>
Acked-by: Dennis Zhou <dennis@kernel.org>
Cc: Christoph Lameter (Ampere) <cl@linux.com>
Cc: Tejun Heo <tj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'mm/percpu-vm.c')
-rw-r--r-- | mm/percpu-vm.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/mm/percpu-vm.c b/mm/percpu-vm.c index 2054c9213c43..cd69caf6aa8d 100644 --- a/mm/percpu-vm.c +++ b/mm/percpu-vm.c @@ -231,10 +231,10 @@ static int pcpu_map_pages(struct pcpu_chunk *chunk, return 0; err: for_each_possible_cpu(tcpu) { - if (tcpu == cpu) - break; __pcpu_unmap_pages(pcpu_chunk_addr(chunk, tcpu, page_start), page_end - page_start); + if (tcpu == cpu) + break; } pcpu_post_unmap_tlb_flush(chunk, page_start, page_end); return err; |