[akpm-mm:mm-new 163/164] mm/sparse-vmemmap.c:766:35: sparse: sparse: cast removes address space '__rcu' of expression

kernel test robot
2026-04-17T10:02:35Z

tree: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-new
head: ee03ca7d1cb1223d0e14dfd3b48478545af75253
commit: 8568f268a5183e0fd5fbd33569b6513038b62f27 [163/164] mm/sparse: fix race on mem_section->usage in pfn walkers
config: arm64-randconfig-r122-20260417 (https://download.01.org/0day-ci/archive/20260417/202604171755.GRWIpPjV-lkp@intel.com/config)
compiler: clang version 23.0.0git (https://github.com/llvm/llvm-project 5bac06718f502014fade905512f1d26d578a18f3)
sparse: v0.6.5-rc1
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260417/202604171755.GRWIpPjV-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202604171755.GRWIpPjV-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
mm/sparse-vmemmap.c:616:39: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long *map @@ got unsigned long [noderef] __rcu * @@
mm/sparse-vmemmap.c:616:39: sparse: expected unsigned long *map
mm/sparse-vmemmap.c:616:39: sparse: got unsigned long [noderef] __rcu *
mm/sparse-vmemmap.c:684:17: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned long *subsection_map @@ got unsigned long [noderef] __rcu * @@
mm/sparse-vmemmap.c:684:17: sparse: expected unsigned long *subsection_map
mm/sparse-vmemmap.c:684:17: sparse: got unsigned long [noderef] __rcu *
mm/sparse-vmemmap.c:701:55: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected unsigned long const *src @@ got unsigned long [noderef] __rcu * @@
mm/sparse-vmemmap.c:701:55: sparse: expected unsigned long const *src
mm/sparse-vmemmap.c:701:55: sparse: got unsigned long [noderef] __rcu *
mm/sparse-vmemmap.c:714:24: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected unsigned long *subsection_map @@ got unsigned long [noderef] __rcu * @@
mm/sparse-vmemmap.c:714:24: sparse: expected unsigned long *subsection_map
mm/sparse-vmemmap.c:714:24: sparse: got unsigned long [noderef] __rcu *
>> mm/sparse-vmemmap.c:766:35: sparse: sparse: cast removes address space '__rcu' of expression
mm/sparse-vmemmap.c:805:27: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct mem_section_usage [noderef] __rcu *usage @@ got struct mem_section_usage *[assigned] usage @@
mm/sparse-vmemmap.c:805:27: sparse: expected struct mem_section_usage [noderef] __rcu *usage
mm/sparse-vmemmap.c:805:27: sparse: got struct mem_section_usage *[assigned] usage
mm/sparse-vmemmap.c:884:59: sparse: sparse: incorrect type in argument 4 (different address spaces) @@ expected struct mem_section_usage *usage @@ got struct mem_section_usage [noderef] __rcu *usage @@
mm/sparse-vmemmap.c:884:59: sparse: expected struct mem_section_usage *usage
mm/sparse-vmemmap.c:884:59: sparse: got struct mem_section_usage [noderef] __rcu *usage
mm/sparse-vmemmap.c: note: in included file:
mm/internal.h:987:19: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct mem_section_usage [noderef] __rcu *usage @@ got struct mem_section_usage *usage @@
mm/internal.h:987:19: sparse: expected struct mem_section_usage [noderef] __rcu *usage
mm/internal.h:987:19: sparse: got struct mem_section_usage *usage

vim +/__rcu +766 mm/sparse-vmemmap.c

738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 726)
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 727) /*
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 728) * To deactivate a memory region, there are 3 cases to handle:
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 729) *
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 730) * 1. deactivation of a partial hot-added section:
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 731) * a) section was present at memory init.
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 732) * b) section was hot-added post memory init.
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 733) * 2. deactivation of a complete hot-added section.
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 734) * 3. deactivation of a complete section from memory init.
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 735) *
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 736) * For 1, when subsection_map does not empty we will not be freeing the
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 737) * usage map, but still need to free the vmemmap range.
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 738) */
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 739) static void section_deactivate(unsigned long pfn, unsigned long nr_pages,
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 740) struct vmem_altmap *altmap)
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 741) {
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 742) struct mem_section *ms = __pfn_to_section(pfn);
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 743) bool section_is_early = early_section(ms);
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 744) struct page *memmap = NULL;
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 745) bool empty;
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 746)
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 747) if (clear_subsection_map(pfn, nr_pages))
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 748) return;
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 749)
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 750) empty = is_subsection_map_empty(ms);
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 751) if (empty) {
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 752) /*
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 753) * Mark the section invalid so that valid_section()
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 754) * return false. This prevents code from dereferencing
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 755) * ms->usage array.
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 756) */
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 757) ms->section_mem_map &= ~SECTION_HAS_MEM_MAP;
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 758)
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 759) /*
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 760) * When removing an early section, the usage map is kept (as the
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 761) * usage maps of other sections fall into the same page). It
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 762) * will be re-used when re-adding the section - which is then no
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 763) * longer an early section. If the usage map is PageReserved, it
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 764) * was allocated during boot.
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 765) */
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 @766) if (!PageReserved(virt_to_page(ms->usage))) {
8568f268a5183e Muchun Song 2026-04-15 767 struct mem_section_usage *usage;
8568f268a5183e Muchun Song 2026-04-15 768
8568f268a5183e Muchun Song 2026-04-15 769 usage = rcu_replace_pointer(ms->usage, NULL, true);
8568f268a5183e Muchun Song 2026-04-15 770 kfree_rcu(usage, rcu);
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 771) }
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 772) memmap = pfn_to_page(SECTION_ALIGN_DOWN(pfn));
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 773) }
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 774)
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 775) /*
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 776) * The memmap of early sections is always fully populated. See
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 777) * section_activate() and pfn_valid() .
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 778) */
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 779) if (!section_is_early) {
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 780) memmap_pages_add(-1L * (DIV_ROUND_UP(nr_pages * sizeof(struct page), PAGE_SIZE)));
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 781) depopulate_section_memmap(pfn, nr_pages, altmap);
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 782) } else if (memmap) {
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 783) memmap_boot_pages_add(-1L * (DIV_ROUND_UP(nr_pages * sizeof(struct page),
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 784) PAGE_SIZE)));
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 785) free_map_bootmem(memmap);
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 786) }
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 787)
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 788) if (empty)
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 789) ms->section_mem_map = (unsigned long)NULL;
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 790) }
738de20c4fafe6 David Hildenbrand (Arm 2026-03-20 791)

:::::: The code at line 766 was first introduced by commit
:::::: 738de20c4fafe64290c5086d683254f60e837db6 mm/sparse: move memory hotplug bits to sparse-vmemmap.c

:::::: TO: David Hildenbrand (Arm) <david@kernel.org>
:::::: CC: Andrew Morton <akpm@linux-foundation.org>

--
0-DAY CI Kernel Test Service