lkml.org 
[lkml]   [2017]   [Sep]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCHv7 01/19] mm/sparsemem: Allocate mem_section at runtime for SPARSEMEM_EXTREME
    Date
    Size of mem_section array depends on size of physical address space.

    In preparation for boot-time switching between paging modes on x86-64
    we need to make allocation of mem_section dynamic.

    The patch allocates the array on the first call to
    sparse_memory_present_with_active_regions().

    Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
    ---
    include/linux/mmzone.h | 6 +++++-
    mm/page_alloc.c | 10 ++++++++++
    mm/sparse.c | 17 +++++++++++------
    3 files changed, 26 insertions(+), 7 deletions(-)

    diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
    index 356a814e7c8e..a48b55fbb502 100644
    --- a/include/linux/mmzone.h
    +++ b/include/linux/mmzone.h
    @@ -1144,13 +1144,17 @@ struct mem_section {
    #define SECTION_ROOT_MASK (SECTIONS_PER_ROOT - 1)

    #ifdef CONFIG_SPARSEMEM_EXTREME
    -extern struct mem_section *mem_section[NR_SECTION_ROOTS];
    +extern struct mem_section **mem_section;
    #else
    extern struct mem_section mem_section[NR_SECTION_ROOTS][SECTIONS_PER_ROOT];
    #endif

    static inline struct mem_section *__nr_to_section(unsigned long nr)
    {
    +#ifdef CONFIG_SPARSEMEM_EXTREME
    + if (!mem_section)
    + return NULL;
    +#endif
    if (!mem_section[SECTION_NR_TO_ROOT(nr)])
    return NULL;
    return &mem_section[SECTION_NR_TO_ROOT(nr)][nr & SECTION_ROOT_MASK];
    diff --git a/mm/page_alloc.c b/mm/page_alloc.c
    index c841af88836a..8034651b916e 100644
    --- a/mm/page_alloc.c
    +++ b/mm/page_alloc.c
    @@ -5645,6 +5645,16 @@ void __init sparse_memory_present_with_active_regions(int nid)
    unsigned long start_pfn, end_pfn;
    int i, this_nid;

    +#ifdef CONFIG_SPARSEMEM_EXTREME
    + if (!mem_section) {
    + unsigned long size, align;
    +
    + size = sizeof(struct mem_section) * NR_SECTION_ROOTS;
    + align = 1 << (INTERNODE_CACHE_SHIFT);
    + mem_section = memblock_virt_alloc(size, align);
    + }
    +#endif
    +
    for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, &this_nid)
    memory_present(this_nid, start_pfn, end_pfn);
    }
    diff --git a/mm/sparse.c b/mm/sparse.c
    index 83b3bf6461af..b00a97398795 100644
    --- a/mm/sparse.c
    +++ b/mm/sparse.c
    @@ -22,8 +22,7 @@
    * 1) mem_section - memory sections, mem_map's for valid memory
    */
    #ifdef CONFIG_SPARSEMEM_EXTREME
    -struct mem_section *mem_section[NR_SECTION_ROOTS]
    - ____cacheline_internodealigned_in_smp;
    +struct mem_section **mem_section;
    #else
    struct mem_section mem_section[NR_SECTION_ROOTS][SECTIONS_PER_ROOT]
    ____cacheline_internodealigned_in_smp;
    @@ -100,7 +99,7 @@ static inline int sparse_index_init(unsigned long section_nr, int nid)
    int __section_nr(struct mem_section* ms)
    {
    unsigned long root_nr;
    - struct mem_section* root;
    + struct mem_section *root = NULL;

    for (root_nr = 0; root_nr < NR_SECTION_ROOTS; root_nr++) {
    root = __nr_to_section(root_nr * SECTIONS_PER_ROOT);
    @@ -111,7 +110,7 @@ int __section_nr(struct mem_section* ms)
    break;
    }

    - VM_BUG_ON(root_nr == NR_SECTION_ROOTS);
    + VM_BUG_ON(!root);

    return (root_nr * SECTIONS_PER_ROOT) + (ms - root);
    }
    @@ -329,11 +328,17 @@ sparse_early_usemaps_alloc_pgdat_section(struct pglist_data *pgdat,
    static void __init check_usemap_section_nr(int nid, unsigned long *usemap)
    {
    unsigned long usemap_snr, pgdat_snr;
    - static unsigned long old_usemap_snr = NR_MEM_SECTIONS;
    - static unsigned long old_pgdat_snr = NR_MEM_SECTIONS;
    + static unsigned long old_usemap_snr;
    + static unsigned long old_pgdat_snr;
    struct pglist_data *pgdat = NODE_DATA(nid);
    int usemap_nid;

    + /* First call */
    + if (!old_usemap_snr) {
    + old_usemap_snr = NR_MEM_SECTIONS;
    + old_pgdat_snr = NR_MEM_SECTIONS;
    + }
    +
    usemap_snr = pfn_to_section_nr(__pa(usemap) >> PAGE_SHIFT);
    pgdat_snr = pfn_to_section_nr(__pa(pgdat) >> PAGE_SHIFT);
    if (usemap_snr == pgdat_snr)
    --
    2.14.1
    \
     
     \ /
      Last update: 2017-09-18 12:56    [W:4.536 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site