From 35989e5c267c2b176d23217257e953c879ce5b47 Mon Sep 17 00:00:00 2001 From: Donald Buczek Date: Thu, 25 Apr 2024 11:50:56 +0200 Subject: [PATCH] Revert "mm/sparsemem: fix race in accessing memory_section->usage" This reverts commit b448de2459b6d62a53892487ab18b7d823ff0529. With this patch, the Nvidia kernel drives doesn't compile, so revert it. linux-5.15.155 , nvidia 535.104.05 : make -j $(nproc) CC=gcc SYSSRC=/scratch/local/linux clean && make -j $(nproc) CC=gcc SYSSRC=/scratch/local/linux V=2 modules [...] MODPOST /scratch/local/bee-buczek/nvidia/test_535-104-05/kernel/Module.symvers - due to target missing ERROR: modpost: GPL-incompatible module nvidia.ko uses GPL-only symbol 'rcu_read_unlock_strict' make[2]: *** [scripts/Makefile.modpost:133: /scratch/local/bee-buczek/nvidia/test_535-104-05/kernel/Module.symvers] Error 1 make[2]: *** Deleting file '/scratch/local/bee-buczek/nvidia/test_535-104-05/kernel/Module.symvers' make[1]: *** [Makefile:1826: modules] Error 2 make[1]: Leaving directory '/scratch/local/linux' make: *** [Makefile:82: modules] Error 2 Although the reverted patch ist included in the 6.5 series, the Nvidia driver compiles okay with 6.5. --- include/linux/mmzone.h | 14 +++----------- mm/sparse.c | 17 ++++++++--------- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 8b8349ffa1cd9..9e1485083398a 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -1287,7 +1287,6 @@ static inline unsigned long section_nr_to_pfn(unsigned long sec) #define SUBSECTION_ALIGN_DOWN(pfn) ((pfn) & PAGE_SUBSECTION_MASK) struct mem_section_usage { - struct rcu_head rcu; #ifdef CONFIG_SPARSEMEM_VMEMMAP DECLARE_BITMAP(subsection_map, SUBSECTIONS_PER_SECTION); #endif @@ -1458,7 +1457,7 @@ static inline int pfn_section_valid(struct mem_section *ms, unsigned long pfn) { int idx = subsection_map_index(pfn); - return test_bit(idx, READ_ONCE(ms->usage)->subsection_map); + return test_bit(idx, ms->usage->subsection_map); } #else static inline int pfn_section_valid(struct mem_section *ms, unsigned long pfn) @@ -1482,7 +1481,6 @@ static inline int pfn_section_valid(struct mem_section *ms, unsigned long pfn) static inline int pfn_valid(unsigned long pfn) { struct mem_section *ms; - int ret; /* * Ensure the upper PAGE_SHIFT bits are clear in the @@ -1496,19 +1494,13 @@ static inline int pfn_valid(unsigned long pfn) if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS) return 0; ms = __pfn_to_section(pfn); - rcu_read_lock(); - if (!valid_section(ms)) { - rcu_read_unlock(); + if (!valid_section(ms)) return 0; - } /* * Traditionally early sections always returned pfn_valid() for * the entire section-sized span. */ - ret = early_section(ms) || pfn_section_valid(ms, pfn); - rcu_read_unlock(); - - return ret; + return early_section(ms) || pfn_section_valid(ms, pfn); } #endif diff --git a/mm/sparse.c b/mm/sparse.c index 27092badd15bd..120bc8ea5293e 100644 --- a/mm/sparse.c +++ b/mm/sparse.c @@ -789,13 +789,6 @@ static void section_deactivate(unsigned long pfn, unsigned long nr_pages, if (empty) { unsigned long section_nr = pfn_to_section_nr(pfn); - /* - * Mark the section invalid so that valid_section() - * return false. This prevents code from dereferencing - * ms->usage array. - */ - ms->section_mem_map &= ~SECTION_HAS_MEM_MAP; - /* * When removing an early section, the usage map is kept (as the * usage maps of other sections fall into the same page). It @@ -804,10 +797,16 @@ static void section_deactivate(unsigned long pfn, unsigned long nr_pages, * was allocated during boot. */ if (!PageReserved(virt_to_page(ms->usage))) { - kfree_rcu(ms->usage, rcu); - WRITE_ONCE(ms->usage, NULL); + kfree(ms->usage); + ms->usage = NULL; } memmap = sparse_decode_mem_map(ms->section_mem_map, section_nr); + /* + * Mark the section invalid so that valid_section() + * return false. This prevents code from dereferencing + * ms->usage array. + */ + ms->section_mem_map &= ~SECTION_HAS_MEM_MAP; } /*