]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
mm/sparsemem: fix race in accessing memory_section->usage
authorCharan Teja Kalla <quic_charante@quicinc.com>
Fri, 27 Oct 2023 10:49:38 +0000 (16:19 +0530)
committerAndrew Morton <akpm@linux-foundation.org>
Mon, 20 Nov 2023 21:16:02 +0000 (13:16 -0800)
use kfree_rcu() in place of synchronize_rcu(), per David

Link: https://lkml.kernel.org/r/1698403778-20938-1-git-send-email-quic_charante@quicinc.com
Fixes: f46edbd1b151 ("mm/sparsemem: add helpers track active portions of a section at boot")
Signed-off-by: Charan Teja Kalla <quic_charante@quicinc.com>
Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Mel Gorman <mgorman@techsingularity.net>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
include/linux/mmzone.h
mm/sparse.c

index 12f31633be0572b35becb4d923bb41cc2965196e..091c18cb779b82eddf303676a80006fb24c69707 100644 (file)
@@ -1789,6 +1789,7 @@ 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
@@ -1982,7 +1983,7 @@ static inline int pfn_section_valid(struct mem_section *ms, unsigned long pfn)
 {
        int idx = subsection_map_index(pfn);
 
-       return test_bit(idx, ms->usage->subsection_map);
+       return test_bit(idx, READ_ONCE(ms->usage)->subsection_map);
 }
 #else
 static inline int pfn_section_valid(struct mem_section *ms, unsigned long pfn)
index ca7dbe110875ad0218fd6ab382954ca8d2a2ac14..338cf946dee8de3a9cc1ea4f335805138b76bfbe 100644 (file)
@@ -806,9 +806,8 @@ static void section_deactivate(unsigned long pfn, unsigned long nr_pages,
                 * was allocated during boot.
                 */
                if (!PageReserved(virt_to_page(ms->usage))) {
-                       synchronize_rcu();
-                       kfree(ms->usage);
-                       ms->usage = NULL;
+                       kfree_rcu(ms->usage, rcu);
+                       WRITE_ONCE(ms->usage, NULL);
                }
                memmap = sparse_decode_mem_map(ms->section_mem_map, section_nr);
        }