Skip to content

Commit ccbd628

Browse files
milesdotchentorvalds
authored andcommitted
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>
1 parent 504e070 commit ccbd628

1 file changed

Lines changed: 11 additions & 2 deletions

File tree

mm/sparse.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,15 @@ size_t mem_section_usage_size(void)
344344
return sizeof(struct mem_section_usage) + usemap_size();
345345
}
346346

347+
static inline phys_addr_t pgdat_to_phys(struct pglist_data *pgdat)
348+
{
349+
#ifndef CONFIG_NEED_MULTIPLE_NODES
350+
return __pa_symbol(pgdat);
351+
#else
352+
return __pa(pgdat);
353+
#endif
354+
}
355+
347356
#ifdef CONFIG_MEMORY_HOTREMOVE
348357
static struct mem_section_usage * __init
349358
sparse_early_usemaps_alloc_pgdat_section(struct pglist_data *pgdat,
@@ -362,7 +371,7 @@ sparse_early_usemaps_alloc_pgdat_section(struct pglist_data *pgdat,
362371
* from the same section as the pgdat where possible to avoid
363372
* this problem.
364373
*/
365-
goal = __pa(pgdat) & (PAGE_SECTION_MASK << PAGE_SHIFT);
374+
goal = pgdat_to_phys(pgdat) & (PAGE_SECTION_MASK << PAGE_SHIFT);
366375
limit = goal + (1UL << PA_SECTION_SHIFT);
367376
nid = early_pfn_to_nid(goal >> PAGE_SHIFT);
368377
again:
@@ -390,7 +399,7 @@ static void __init check_usemap_section_nr(int nid,
390399
}
391400

392401
usemap_snr = pfn_to_section_nr(__pa(usage) >> PAGE_SHIFT);
393-
pgdat_snr = pfn_to_section_nr(__pa(pgdat) >> PAGE_SHIFT);
402+
pgdat_snr = pfn_to_section_nr(pgdat_to_phys(pgdat) >> PAGE_SHIFT);
394403
if (usemap_snr == pgdat_snr)
395404
return;
396405

0 commit comments

Comments
 (0)