[PATCH 2/2] sparsemem extreme: hotplug preparation

From: Dave Hansen (haveblue_at_us.ibm.com)
Date: 08/12/05

  • Next message: Horst von Brand: "Re: Problem with usb-storage and /dev/sd?"
    To: akpm@osdl.org
    Date:	Thu, 11 Aug 2005 15:48:09 -0700
    
    

    This splits up sparse_index_alloc() into two pieces. This is needed
    because we'll allocate the memory for the second level in a different
    place from where we actually consume it to keep the allocation from
    happening underneath a lock

    Signed-off-by: Dave Hansen <haveblue@us.ibm.com>

    ---
     memhotplug-dave/include/linux/mmzone.h |    1 
     memhotplug-dave/mm/sparse.c            |   52 ++++++++++++++++++++++++---------
     2 files changed, 40 insertions(+), 13 deletions(-)
    diff -puN mm/sparse.c~A6-extreme-hotplug-prepare mm/sparse.c
    --- memhotplug/mm/sparse.c~A6-extreme-hotplug-prepare	2005-08-11 15:46:18.000000000 -0700
    +++ memhotplug-dave/mm/sparse.c	2005-08-11 15:46:18.000000000 -0700
    @@ -6,6 +6,7 @@
     #include <linux/mmzone.h>
     #include <linux/bootmem.h>
     #include <linux/module.h>
    +#include <linux/spinlock.h>
     #include <asm/dma.h>
     
     /*
    @@ -22,27 +23,52 @@ struct mem_section mem_section[NR_SECTIO
     #endif
     EXPORT_SYMBOL(mem_section);
     
    -static void sparse_alloc_root(unsigned long root, int nid)
    -{
     #ifdef CONFIG_SPARSEMEM_EXTREME
    -	mem_section[root] = alloc_bootmem_node(NODE_DATA(nid), PAGE_SIZE);
    -#endif
    +static struct mem_section *sparse_index_alloc(int nid)
    +{
    +	struct mem_section *section = NULL;
    +	unsigned long array_size = SECTIONS_PER_ROOT *
    +				   sizeof(struct mem_section);
    +
    +	section = alloc_bootmem_node(NODE_DATA(nid), array_size);
    +
    +	if (section)
    +		memset(section, 0, array_size);
    +
    +	return section;
     }
     
    -static void sparse_index_init(unsigned long section, int nid)
    +static int sparse_index_init(unsigned long section_nr, int nid)
     {
    -	unsigned long root = SECTION_NR_TO_ROOT(section);
    +	static spinlock_t index_init_lock = SPIN_LOCK_UNLOCKED;
    +	unsigned long root = SECTION_NR_TO_ROOT(section_nr);
    +	struct mem_section *section;
    +	int ret = 0;
     
    -	if (mem_section[root])
    -		return;
    +	section = sparse_index_alloc(nid);
    +	/*
    +	 * This lock keeps two different sections from
    +	 * reallocating for the same index
    +	 */
    +	spin_lock(&index_init_lock);
     
    -	sparse_alloc_root(root, nid);
    +	if (mem_section[root]) {
    +		ret = -EEXIST;
    +		goto out;
    +	}
     
    -	if (mem_section[root])
    -		memset(mem_section[root], 0, PAGE_SIZE);
    -	else
    -		panic("memory_present: NO MEMORY\n");
    +	mem_section[root] = section;
    +out:
    +	spin_unlock(&index_init_lock);
    +	return ret;
    +}
    +#else /* !SPARSEMEM_EXTREME */
    +static inline int sparse_index_init(unsigned long section_nr, int nid)
    +{
    +	return 0;
     }
    +#endif
    +
     /* Record a memory area against a node. */
     void memory_present(int nid, unsigned long start, unsigned long end)
     {
    diff -puN include/linux/mmzone.h~A6-extreme-hotplug-prepare include/linux/mmzone.h
    --- memhotplug/include/linux/mmzone.h~A6-extreme-hotplug-prepare	2005-08-11 15:46:18.000000000 -0700
    +++ memhotplug-dave/include/linux/mmzone.h	2005-08-11 15:46:18.000000000 -0700
    @@ -588,6 +588,7 @@ static inline int pfn_valid(unsigned lon
     void sparse_init(void);
     #else
     #define sparse_init()	do {} while (0)
    +#define sparse_index_init(_sec, _nid)  do {} while (0)
     #endif /* CONFIG_SPARSEMEM */
     
     #ifdef CONFIG_NODES_SPAN_OTHER_NODES
    _
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at  http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at  http://www.tux.org/lkml/
    

  • Next message: Horst von Brand: "Re: Problem with usb-storage and /dev/sd?"

    Relevant Pages

    • Re: printf
      ... > int mainas sombody said *very* correctly. ... What's wrong with int main (void)? ... > portion of memory. ... > You still have to allocate p. ...
      (comp.lang.c)
    • Re: HeapAlloc heap fragmentation.
      ... This is contrary to evidence and implementation (see code and debugger ... > It appears that if an application allocate a large portion of the ... > void TestSmallBlocks ... > // now free the memory ...
      (microsoft.public.win32.programmer.kernel)
    • Re: redefining operator new and STL classes
      ... >> Containers don't use new to allocate objects, ... The standard allocator gets memory and then ... which is to say, first memory is allocated using an operator new, ... form with a void* argument does), and finally the pObj is created ...
      (alt.comp.lang.learn.c-cpp)
    • Re: Filling data in function...
      ... What is the best way to do pointer arithmetic, ... a chunk of memory for an array of data. ... > But how did you allocate the space for the character strings? ...
      (alt.comp.lang.learn.c-cpp)
    • [RFC/PATCH]Allow agp memory allocations to use node information
      ... int nodeid; ... +void *agp_generic_alloc_page ... +static void *i460_alloc_page (int nid) ...
      (Linux-Kernel)