Skip to content

Commit

Permalink
Revert "mm/sparsemem: fix race in accessing memory_section->usage"
Browse files Browse the repository at this point in the history
This reverts commit b448de2.

For some reasons we don't understand, b448de2 ("mm/sparsemem: fix
race in accessing memory_section->usage") prevents us from compiling the
proprietary Nvidia Unix driver with versions 510.108.03 and 535.104.05
in the 5.15 series.  No problems with the 6.5 series, although the patch
is included there as well

    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
donald committed Jun 5, 2024
1 parent bdaba54 commit 789cc62
Showing 2 changed files with 11 additions and 20 deletions.
14 changes: 3 additions & 11 deletions include/linux/mmzone.h
Original file line number Diff line number Diff line change
@@ -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

17 changes: 8 additions & 9 deletions mm/sparse.c
Original file line number Diff line number Diff line change
@@ -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;
}

/*

0 comments on commit 789cc62

Please sign in to comment.