mm/sparse: fix check_usemap_section_nr warnings
I see a "virt_to_phys used for non-linear address" warning from check_usemap_section_nr() on arm64 platforms. In current implementation of NODE_DATA, if CONFIG_NEED_MULTIPLE_NODES=y, pglist_data is dynamically allocated and assigned to node_data[]. For example, in arch/arm64/include/asm/mmzone.h: extern struct pglist_data *node_data[]; #define NODE_DATA(nid) (node_data[(nid)]) If CONFIG_NEED_MULTIPLE_NODES=n, pglist_data is defined as a global variable named "contig_page_data". For example, in include/linux/mmzone.h: extern struct pglist_data contig_page_data; #define NODE_DATA(nid) (&contig_page_data) If CONFIG_DEBUG_VIRTUAL is not enabled, __pa() can handle both dynamically allocated linear addresses and symbol addresses. However, if (CONFIG_DEBUG_VIRTUAL=y && CONFIG_NEED_MULTIPLE_NODES=n) we can see the "virt_to_phys used for non-linear address" warning because that &contig_page_data is not a linear address on arm64. Warning message: virt_to_phys used for non-linear address: (contig_page_data+0x0/0x1c00) WARNING: CPU: 0 PID: 0 at arch/arm64/mm/physaddr.c:15 __virt_to_phys+0x58/0x68 Modules linked in: CPU: 0 PID: 0 Comm: swapper Tainted: G W 5.13.0-rc1-00074-g1140ab592e2e #3 Hardware name: linux,dummy-virt (DT) pstate: 600000c5 (nZCv daIF -PAN -UAO -TCO BTYPE=--) Call trace: __virt_to_phys+0x58/0x68 check_usemap_section_nr+0x50/0xfc sparse_init_nid+0x1ac/0x28c sparse_init+0x1c4/0x1e0 bootmem_init+0x60/0x90 setup_arch+0x184/0x1f0 start_kernel+0x78/0x488 To fix it, create a small function to handle both translation. Link: https://lkml.kernel.org/r/1623058729-27264-1-git-send-email-miles.chen@mediatek.com Signed-off-by: Miles Chen <miles.chen@mediatek.com> Cc: Mike Rapoport <rppt@kernel.org> Cc: Baoquan He <bhe@redhat.com> Cc: Kazu <k-hagio-ab@nec.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
504e070dc0
commit
ccbd6283a9
13
mm/sparse.c
13
mm/sparse.c
|
@ -344,6 +344,15 @@ size_t mem_section_usage_size(void)
|
|||
return sizeof(struct mem_section_usage) + usemap_size();
|
||||
}
|
||||
|
||||
static inline phys_addr_t pgdat_to_phys(struct pglist_data *pgdat)
|
||||
{
|
||||
#ifndef CONFIG_NEED_MULTIPLE_NODES
|
||||
return __pa_symbol(pgdat);
|
||||
#else
|
||||
return __pa(pgdat);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MEMORY_HOTREMOVE
|
||||
static struct mem_section_usage * __init
|
||||
sparse_early_usemaps_alloc_pgdat_section(struct pglist_data *pgdat,
|
||||
|
@ -362,7 +371,7 @@ sparse_early_usemaps_alloc_pgdat_section(struct pglist_data *pgdat,
|
|||
* from the same section as the pgdat where possible to avoid
|
||||
* this problem.
|
||||
*/
|
||||
goal = __pa(pgdat) & (PAGE_SECTION_MASK << PAGE_SHIFT);
|
||||
goal = pgdat_to_phys(pgdat) & (PAGE_SECTION_MASK << PAGE_SHIFT);
|
||||
limit = goal + (1UL << PA_SECTION_SHIFT);
|
||||
nid = early_pfn_to_nid(goal >> PAGE_SHIFT);
|
||||
again:
|
||||
|
@ -390,7 +399,7 @@ static void __init check_usemap_section_nr(int nid,
|
|||
}
|
||||
|
||||
usemap_snr = pfn_to_section_nr(__pa(usage) >> PAGE_SHIFT);
|
||||
pgdat_snr = pfn_to_section_nr(__pa(pgdat) >> PAGE_SHIFT);
|
||||
pgdat_snr = pfn_to_section_nr(pgdat_to_phys(pgdat) >> PAGE_SHIFT);
|
||||
if (usemap_snr == pgdat_snr)
|
||||
return;
|
||||
|
||||
|
|
Loading…
Reference in New Issue