From: Jianguo Wu <wujianguo@huawei.com>
To: Tang Chen <tangchen@cn.fujitsu.com>
Cc: akpm@linux-foundation.org, rientjes@google.com, liuj97@gmail.com,
len.brown@intel.com, benh@kernel.crashing.org, paulus@samba.org,
cl@linux.com, minchan.kim@gmail.com,
kosaki.motohiro@jp.fujitsu.com, isimatu.yasuaki@jp.fujitsu.com,
wency@cn.fujitsu.com, hpa@zytor.com, linfeng@cn.fujitsu.com,
laijs@cn.fujitsu.com, mgorman@suse.de, yinghai@kernel.org,
x86@kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org, linux-acpi@vger.kernel.org,
linux-s390@vger.kernel.org, linux-sh@vger.kernel.org,
linux-ia64@vger.kernel.org, cmetcalf@tilera.com,
sparclinux@vger.kernel.org
Subject: Re: [PATCH v5 06/14] memory-hotplug: implement register_page_bootmem_info_section of sparse-vmemmap
Date: Tue, 25 Dec 2012 16:09:53 +0800 [thread overview]
Message-ID: <50D95F51.9090007@huawei.com> (raw)
In-Reply-To: <1356350964-13437-7-git-send-email-tangchen@cn.fujitsu.com>
On 2012/12/24 20:09, Tang Chen wrote:
> From: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
>
> For removing memmap region of sparse-vmemmap which is allocated bootmem,
> memmap region of sparse-vmemmap needs to be registered by get_page_bootmem().
> So the patch searches pages of virtual mapping and registers the pages by
> get_page_bootmem().
>
> Note: register_page_bootmem_memmap() is not implemented for ia64, ppc, s390,
> and sparc.
>
> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
> Signed-off-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
> ---
> arch/ia64/mm/discontig.c | 6 ++++
> arch/powerpc/mm/init_64.c | 6 ++++
> arch/s390/mm/vmem.c | 6 ++++
> arch/sparc/mm/init_64.c | 6 ++++
> arch/x86/mm/init_64.c | 52 ++++++++++++++++++++++++++++++++++++++++
> include/linux/memory_hotplug.h | 11 +-------
> include/linux/mm.h | 3 +-
> mm/memory_hotplug.c | 33 ++++++++++++++++++++++---
> 8 files changed, 109 insertions(+), 14 deletions(-)
>
> diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
> index c641333..33943db 100644
> --- a/arch/ia64/mm/discontig.c
> +++ b/arch/ia64/mm/discontig.c
> @@ -822,4 +822,10 @@ int __meminit vmemmap_populate(struct page *start_page,
> {
> return vmemmap_populate_basepages(start_page, size, node);
> }
> +
> +void register_page_bootmem_memmap(unsigned long section_nr,
> + struct page *start_page, unsigned long size)
> +{
> + /* TODO */
> +}
> #endif
> diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
> index 95a4529..6466440 100644
> --- a/arch/powerpc/mm/init_64.c
> +++ b/arch/powerpc/mm/init_64.c
> @@ -297,5 +297,11 @@ int __meminit vmemmap_populate(struct page *start_page,
>
> return 0;
> }
> +
> +void register_page_bootmem_memmap(unsigned long section_nr,
> + struct page *start_page, unsigned long size)
> +{
> + /* TODO */
> +}
> #endif /* CONFIG_SPARSEMEM_VMEMMAP */
>
> diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
> index 6ed1426..2c14bc2 100644
> --- a/arch/s390/mm/vmem.c
> +++ b/arch/s390/mm/vmem.c
> @@ -272,6 +272,12 @@ out:
> return ret;
> }
>
> +void register_page_bootmem_memmap(unsigned long section_nr,
> + struct page *start_page, unsigned long size)
> +{
> + /* TODO */
> +}
> +
> /*
> * Add memory segment to the segment list if it doesn't overlap with
> * an already present segment.
> diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
> index 85be1ca..7e28c9e 100644
> --- a/arch/sparc/mm/init_64.c
> +++ b/arch/sparc/mm/init_64.c
> @@ -2231,6 +2231,12 @@ void __meminit vmemmap_populate_print_last(void)
> node_start = 0;
> }
> }
> +
> +void register_page_bootmem_memmap(unsigned long section_nr,
> + struct page *start_page, unsigned long size)
> +{
> + /* TODO */
> +}
> #endif /* CONFIG_SPARSEMEM_VMEMMAP */
>
> static void prot_init_common(unsigned long page_none,
> diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
> index f78509c..aeaa27e 100644
> --- a/arch/x86/mm/init_64.c
> +++ b/arch/x86/mm/init_64.c
> @@ -1000,6 +1000,58 @@ vmemmap_populate(struct page *start_page, unsigned long size, int node)
> return 0;
> }
>
> +void register_page_bootmem_memmap(unsigned long section_nr,
> + struct page *start_page, unsigned long size)
> +{
> + unsigned long addr = (unsigned long)start_page;
> + unsigned long end = (unsigned long)(start_page + size);
> + unsigned long next;
> + pgd_t *pgd;
> + pud_t *pud;
> + pmd_t *pmd;
> +
> + for (; addr < end; addr = next) {
> + pte_t *pte = NULL;
> +
> + pgd = pgd_offset_k(addr);
> + if (pgd_none(*pgd)) {
> + next = (addr + PAGE_SIZE) & PAGE_MASK;
> + continue;
> + }
> + get_page_bootmem(section_nr, pgd_page(*pgd), MIX_SECTION_INFO);
> +
> + pud = pud_offset(pgd, addr);
> + if (pud_none(*pud)) {
> + next = (addr + PAGE_SIZE) & PAGE_MASK;
> + continue;
> + }
> + get_page_bootmem(section_nr, pud_page(*pud), MIX_SECTION_INFO);
> +
> + if (!cpu_has_pse) {
> + next = (addr + PAGE_SIZE) & PAGE_MASK;
> + pmd = pmd_offset(pud, addr);
> + if (pmd_none(*pmd))
> + continue;
> + get_page_bootmem(section_nr, pmd_page(*pmd),
> + MIX_SECTION_INFO);
> +
> + pte = pte_offset_kernel(pmd, addr);
> + if (pte_none(*pte))
> + continue;
> + get_page_bootmem(section_nr, pte_page(*pte),
> + SECTION_INFO);
> + } else {
> + next = pmd_addr_end(addr, end);
> +
> + pmd = pmd_offset(pud, addr);
> + if (pmd_none(*pmd))
> + continue;
> + get_page_bootmem(section_nr, pmd_page(*pmd),
> + SECTION_INFO);
Hi Tang,
In this case, pmd maps 512 pages, but you only get_page_bootmem() on the first page.
I think the whole 512 pages should be get_page_bootmem(), what do you think?
Thanks,
Jianguo Wu
> + }
> + }
> +}
> +
> void __meminit vmemmap_populate_print_last(void)
> {
> if (p_start) {
> diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
> index 31a563b..2441f36 100644
> --- a/include/linux/memory_hotplug.h
> +++ b/include/linux/memory_hotplug.h
> @@ -174,17 +174,10 @@ static inline void arch_refresh_nodedata(int nid, pg_data_t *pgdat)
> #endif /* CONFIG_NUMA */
> #endif /* CONFIG_HAVE_ARCH_NODEDATA_EXTENSION */
>
> -#ifdef CONFIG_SPARSEMEM_VMEMMAP
> -static inline void register_page_bootmem_info_node(struct pglist_data *pgdat)
> -{
> -}
> -static inline void put_page_bootmem(struct page *page)
> -{
> -}
> -#else
> extern void register_page_bootmem_info_node(struct pglist_data *pgdat);
> extern void put_page_bootmem(struct page *page);
> -#endif
> +extern void get_page_bootmem(unsigned long ingo, struct page *page,
> + unsigned long type);
>
> /*
> * Lock for memory hotplug guarantees 1) all callbacks for memory hotplug
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 6320407..1eca498 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -1709,7 +1709,8 @@ int vmemmap_populate_basepages(struct page *start_page,
> unsigned long pages, int node);
> int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
> void vmemmap_populate_print_last(void);
> -
> +void register_page_bootmem_memmap(unsigned long section_nr, struct page *map,
> + unsigned long size);
>
> enum mf_flags {
> MF_COUNT_INCREASED = 1 << 0,
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> index 2c5d734..34c656b 100644
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -91,9 +91,8 @@ static void release_memory_resource(struct resource *res)
> }
>
> #ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
> -#ifndef CONFIG_SPARSEMEM_VMEMMAP
> -static void get_page_bootmem(unsigned long info, struct page *page,
> - unsigned long type)
> +void get_page_bootmem(unsigned long info, struct page *page,
> + unsigned long type)
> {
> page->lru.next = (struct list_head *) type;
> SetPagePrivate(page);
> @@ -128,6 +127,7 @@ void __ref put_page_bootmem(struct page *page)
>
> }
>
> +#ifndef CONFIG_SPARSEMEM_VMEMMAP
> static void register_page_bootmem_info_section(unsigned long start_pfn)
> {
> unsigned long *usemap, mapsize, section_nr, i;
> @@ -161,6 +161,32 @@ static void register_page_bootmem_info_section(unsigned long start_pfn)
> get_page_bootmem(section_nr, page, MIX_SECTION_INFO);
>
> }
> +#else
> +static void register_page_bootmem_info_section(unsigned long start_pfn)
> +{
> + unsigned long *usemap, mapsize, section_nr, i;
> + struct mem_section *ms;
> + struct page *page, *memmap;
> +
> + if (!pfn_valid(start_pfn))
> + return;
> +
> + section_nr = pfn_to_section_nr(start_pfn);
> + ms = __nr_to_section(section_nr);
> +
> + memmap = sparse_decode_mem_map(ms->section_mem_map, section_nr);
> +
> + register_page_bootmem_memmap(section_nr, memmap, PAGES_PER_SECTION);
> +
> + usemap = __nr_to_section(section_nr)->pageblock_flags;
> + page = virt_to_page(usemap);
> +
> + mapsize = PAGE_ALIGN(usemap_size()) >> PAGE_SHIFT;
> +
> + for (i = 0; i < mapsize; i++, page++)
> + get_page_bootmem(section_nr, page, MIX_SECTION_INFO);
> +}
> +#endif
>
> void register_page_bootmem_info_node(struct pglist_data *pgdat)
> {
> @@ -203,7 +229,6 @@ void register_page_bootmem_info_node(struct pglist_data *pgdat)
> register_page_bootmem_info_section(pfn);
> }
> }
> -#endif /* !CONFIG_SPARSEMEM_VMEMMAP */
>
> static void grow_zone_span(struct zone *zone, unsigned long start_pfn,
> unsigned long end_pfn)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
WARNING: multiple messages have this Message-ID (diff)
From: Jianguo Wu <wujianguo@huawei.com>
To: Tang Chen <tangchen@cn.fujitsu.com>
Cc: akpm@linux-foundation.org, rientjes@google.com, liuj97@gmail.com,
len.brown@intel.com, benh@kernel.crashing.org, paulus@samba.org,
cl@linux.com, minchan.kim@gmail.com,
kosaki.motohiro@jp.fujitsu.com, isimatu.yasuaki@jp.fujitsu.com,
wency@cn.fujitsu.com, hpa@zytor.com, linfeng@cn.fujitsu.com,
laijs@cn.fujitsu.com, mgorman@suse.de, yinghai@kernel.org,
x86@kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org, linux-acpi@vger.kernel.org,
linux-s390@vger.kernel.org, linux-sh@vger.kernel.org,
linux-ia64@vger.kernel.org, cmetcalf@tilera.com,
sparclinux@vger.kernel.org
Subject: Re: [PATCH v5 06/14] memory-hotplug: implement register_page_bootmem_info_section of sparse-vmemmap
Date: Tue, 25 Dec 2012 08:09:53 +0000 [thread overview]
Message-ID: <50D95F51.9090007@huawei.com> (raw)
In-Reply-To: <1356350964-13437-7-git-send-email-tangchen@cn.fujitsu.com>
On 2012/12/24 20:09, Tang Chen wrote:
> From: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
>
> For removing memmap region of sparse-vmemmap which is allocated bootmem,
> memmap region of sparse-vmemmap needs to be registered by get_page_bootmem().
> So the patch searches pages of virtual mapping and registers the pages by
> get_page_bootmem().
>
> Note: register_page_bootmem_memmap() is not implemented for ia64, ppc, s390,
> and sparc.
>
> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
> Signed-off-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
> ---
> arch/ia64/mm/discontig.c | 6 ++++
> arch/powerpc/mm/init_64.c | 6 ++++
> arch/s390/mm/vmem.c | 6 ++++
> arch/sparc/mm/init_64.c | 6 ++++
> arch/x86/mm/init_64.c | 52 ++++++++++++++++++++++++++++++++++++++++
> include/linux/memory_hotplug.h | 11 +-------
> include/linux/mm.h | 3 +-
> mm/memory_hotplug.c | 33 ++++++++++++++++++++++---
> 8 files changed, 109 insertions(+), 14 deletions(-)
>
> diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
> index c641333..33943db 100644
> --- a/arch/ia64/mm/discontig.c
> +++ b/arch/ia64/mm/discontig.c
> @@ -822,4 +822,10 @@ int __meminit vmemmap_populate(struct page *start_page,
> {
> return vmemmap_populate_basepages(start_page, size, node);
> }
> +
> +void register_page_bootmem_memmap(unsigned long section_nr,
> + struct page *start_page, unsigned long size)
> +{
> + /* TODO */
> +}
> #endif
> diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
> index 95a4529..6466440 100644
> --- a/arch/powerpc/mm/init_64.c
> +++ b/arch/powerpc/mm/init_64.c
> @@ -297,5 +297,11 @@ int __meminit vmemmap_populate(struct page *start_page,
>
> return 0;
> }
> +
> +void register_page_bootmem_memmap(unsigned long section_nr,
> + struct page *start_page, unsigned long size)
> +{
> + /* TODO */
> +}
> #endif /* CONFIG_SPARSEMEM_VMEMMAP */
>
> diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
> index 6ed1426..2c14bc2 100644
> --- a/arch/s390/mm/vmem.c
> +++ b/arch/s390/mm/vmem.c
> @@ -272,6 +272,12 @@ out:
> return ret;
> }
>
> +void register_page_bootmem_memmap(unsigned long section_nr,
> + struct page *start_page, unsigned long size)
> +{
> + /* TODO */
> +}
> +
> /*
> * Add memory segment to the segment list if it doesn't overlap with
> * an already present segment.
> diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
> index 85be1ca..7e28c9e 100644
> --- a/arch/sparc/mm/init_64.c
> +++ b/arch/sparc/mm/init_64.c
> @@ -2231,6 +2231,12 @@ void __meminit vmemmap_populate_print_last(void)
> node_start = 0;
> }
> }
> +
> +void register_page_bootmem_memmap(unsigned long section_nr,
> + struct page *start_page, unsigned long size)
> +{
> + /* TODO */
> +}
> #endif /* CONFIG_SPARSEMEM_VMEMMAP */
>
> static void prot_init_common(unsigned long page_none,
> diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
> index f78509c..aeaa27e 100644
> --- a/arch/x86/mm/init_64.c
> +++ b/arch/x86/mm/init_64.c
> @@ -1000,6 +1000,58 @@ vmemmap_populate(struct page *start_page, unsigned long size, int node)
> return 0;
> }
>
> +void register_page_bootmem_memmap(unsigned long section_nr,
> + struct page *start_page, unsigned long size)
> +{
> + unsigned long addr = (unsigned long)start_page;
> + unsigned long end = (unsigned long)(start_page + size);
> + unsigned long next;
> + pgd_t *pgd;
> + pud_t *pud;
> + pmd_t *pmd;
> +
> + for (; addr < end; addr = next) {
> + pte_t *pte = NULL;
> +
> + pgd = pgd_offset_k(addr);
> + if (pgd_none(*pgd)) {
> + next = (addr + PAGE_SIZE) & PAGE_MASK;
> + continue;
> + }
> + get_page_bootmem(section_nr, pgd_page(*pgd), MIX_SECTION_INFO);
> +
> + pud = pud_offset(pgd, addr);
> + if (pud_none(*pud)) {
> + next = (addr + PAGE_SIZE) & PAGE_MASK;
> + continue;
> + }
> + get_page_bootmem(section_nr, pud_page(*pud), MIX_SECTION_INFO);
> +
> + if (!cpu_has_pse) {
> + next = (addr + PAGE_SIZE) & PAGE_MASK;
> + pmd = pmd_offset(pud, addr);
> + if (pmd_none(*pmd))
> + continue;
> + get_page_bootmem(section_nr, pmd_page(*pmd),
> + MIX_SECTION_INFO);
> +
> + pte = pte_offset_kernel(pmd, addr);
> + if (pte_none(*pte))
> + continue;
> + get_page_bootmem(section_nr, pte_page(*pte),
> + SECTION_INFO);
> + } else {
> + next = pmd_addr_end(addr, end);
> +
> + pmd = pmd_offset(pud, addr);
> + if (pmd_none(*pmd))
> + continue;
> + get_page_bootmem(section_nr, pmd_page(*pmd),
> + SECTION_INFO);
Hi Tang,
In this case, pmd maps 512 pages, but you only get_page_bootmem() on the first page.
I think the whole 512 pages should be get_page_bootmem(), what do you think?
Thanks,
Jianguo Wu
> + }
> + }
> +}
> +
> void __meminit vmemmap_populate_print_last(void)
> {
> if (p_start) {
> diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
> index 31a563b..2441f36 100644
> --- a/include/linux/memory_hotplug.h
> +++ b/include/linux/memory_hotplug.h
> @@ -174,17 +174,10 @@ static inline void arch_refresh_nodedata(int nid, pg_data_t *pgdat)
> #endif /* CONFIG_NUMA */
> #endif /* CONFIG_HAVE_ARCH_NODEDATA_EXTENSION */
>
> -#ifdef CONFIG_SPARSEMEM_VMEMMAP
> -static inline void register_page_bootmem_info_node(struct pglist_data *pgdat)
> -{
> -}
> -static inline void put_page_bootmem(struct page *page)
> -{
> -}
> -#else
> extern void register_page_bootmem_info_node(struct pglist_data *pgdat);
> extern void put_page_bootmem(struct page *page);
> -#endif
> +extern void get_page_bootmem(unsigned long ingo, struct page *page,
> + unsigned long type);
>
> /*
> * Lock for memory hotplug guarantees 1) all callbacks for memory hotplug
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 6320407..1eca498 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -1709,7 +1709,8 @@ int vmemmap_populate_basepages(struct page *start_page,
> unsigned long pages, int node);
> int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
> void vmemmap_populate_print_last(void);
> -
> +void register_page_bootmem_memmap(unsigned long section_nr, struct page *map,
> + unsigned long size);
>
> enum mf_flags {
> MF_COUNT_INCREASED = 1 << 0,
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> index 2c5d734..34c656b 100644
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -91,9 +91,8 @@ static void release_memory_resource(struct resource *res)
> }
>
> #ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
> -#ifndef CONFIG_SPARSEMEM_VMEMMAP
> -static void get_page_bootmem(unsigned long info, struct page *page,
> - unsigned long type)
> +void get_page_bootmem(unsigned long info, struct page *page,
> + unsigned long type)
> {
> page->lru.next = (struct list_head *) type;
> SetPagePrivate(page);
> @@ -128,6 +127,7 @@ void __ref put_page_bootmem(struct page *page)
>
> }
>
> +#ifndef CONFIG_SPARSEMEM_VMEMMAP
> static void register_page_bootmem_info_section(unsigned long start_pfn)
> {
> unsigned long *usemap, mapsize, section_nr, i;
> @@ -161,6 +161,32 @@ static void register_page_bootmem_info_section(unsigned long start_pfn)
> get_page_bootmem(section_nr, page, MIX_SECTION_INFO);
>
> }
> +#else
> +static void register_page_bootmem_info_section(unsigned long start_pfn)
> +{
> + unsigned long *usemap, mapsize, section_nr, i;
> + struct mem_section *ms;
> + struct page *page, *memmap;
> +
> + if (!pfn_valid(start_pfn))
> + return;
> +
> + section_nr = pfn_to_section_nr(start_pfn);
> + ms = __nr_to_section(section_nr);
> +
> + memmap = sparse_decode_mem_map(ms->section_mem_map, section_nr);
> +
> + register_page_bootmem_memmap(section_nr, memmap, PAGES_PER_SECTION);
> +
> + usemap = __nr_to_section(section_nr)->pageblock_flags;
> + page = virt_to_page(usemap);
> +
> + mapsize = PAGE_ALIGN(usemap_size()) >> PAGE_SHIFT;
> +
> + for (i = 0; i < mapsize; i++, page++)
> + get_page_bootmem(section_nr, page, MIX_SECTION_INFO);
> +}
> +#endif
>
> void register_page_bootmem_info_node(struct pglist_data *pgdat)
> {
> @@ -203,7 +229,6 @@ void register_page_bootmem_info_node(struct pglist_data *pgdat)
> register_page_bootmem_info_section(pfn);
> }
> }
> -#endif /* !CONFIG_SPARSEMEM_VMEMMAP */
>
> static void grow_zone_span(struct zone *zone, unsigned long start_pfn,
> unsigned long end_pfn)
WARNING: multiple messages have this Message-ID (diff)
From: Jianguo Wu <wujianguo@huawei.com>
To: Tang Chen <tangchen@cn.fujitsu.com>
Cc: linux-ia64@vger.kernel.org, linux-sh@vger.kernel.org,
linux-mm@kvack.org, paulus@samba.org, hpa@zytor.com,
sparclinux@vger.kernel.org, cl@linux.com,
linux-s390@vger.kernel.org, x86@kernel.org,
linux-acpi@vger.kernel.org, isimatu.yasuaki@jp.fujitsu.com,
linfeng@cn.fujitsu.com, mgorman@suse.de,
kosaki.motohiro@jp.fujitsu.com, rientjes@google.com,
liuj97@gmail.com, len.brown@intel.com, wency@cn.fujitsu.com,
cmetcalf@tilera.com, yinghai@kernel.org, laijs@cn.fujitsu.com,
linux-kernel@vger.kernel.org, minchan.kim@gmail.com,
akpm@linux-foundation.org, linuxppc-dev@lists.ozlabs.org
Subject: Re: [PATCH v5 06/14] memory-hotplug: implement register_page_bootmem_info_section of sparse-vmemmap
Date: Tue, 25 Dec 2012 16:09:53 +0800 [thread overview]
Message-ID: <50D95F51.9090007@huawei.com> (raw)
In-Reply-To: <1356350964-13437-7-git-send-email-tangchen@cn.fujitsu.com>
On 2012/12/24 20:09, Tang Chen wrote:
> From: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
>
> For removing memmap region of sparse-vmemmap which is allocated bootmem,
> memmap region of sparse-vmemmap needs to be registered by get_page_bootmem().
> So the patch searches pages of virtual mapping and registers the pages by
> get_page_bootmem().
>
> Note: register_page_bootmem_memmap() is not implemented for ia64, ppc, s390,
> and sparc.
>
> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
> Signed-off-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
> ---
> arch/ia64/mm/discontig.c | 6 ++++
> arch/powerpc/mm/init_64.c | 6 ++++
> arch/s390/mm/vmem.c | 6 ++++
> arch/sparc/mm/init_64.c | 6 ++++
> arch/x86/mm/init_64.c | 52 ++++++++++++++++++++++++++++++++++++++++
> include/linux/memory_hotplug.h | 11 +-------
> include/linux/mm.h | 3 +-
> mm/memory_hotplug.c | 33 ++++++++++++++++++++++---
> 8 files changed, 109 insertions(+), 14 deletions(-)
>
> diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
> index c641333..33943db 100644
> --- a/arch/ia64/mm/discontig.c
> +++ b/arch/ia64/mm/discontig.c
> @@ -822,4 +822,10 @@ int __meminit vmemmap_populate(struct page *start_page,
> {
> return vmemmap_populate_basepages(start_page, size, node);
> }
> +
> +void register_page_bootmem_memmap(unsigned long section_nr,
> + struct page *start_page, unsigned long size)
> +{
> + /* TODO */
> +}
> #endif
> diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
> index 95a4529..6466440 100644
> --- a/arch/powerpc/mm/init_64.c
> +++ b/arch/powerpc/mm/init_64.c
> @@ -297,5 +297,11 @@ int __meminit vmemmap_populate(struct page *start_page,
>
> return 0;
> }
> +
> +void register_page_bootmem_memmap(unsigned long section_nr,
> + struct page *start_page, unsigned long size)
> +{
> + /* TODO */
> +}
> #endif /* CONFIG_SPARSEMEM_VMEMMAP */
>
> diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
> index 6ed1426..2c14bc2 100644
> --- a/arch/s390/mm/vmem.c
> +++ b/arch/s390/mm/vmem.c
> @@ -272,6 +272,12 @@ out:
> return ret;
> }
>
> +void register_page_bootmem_memmap(unsigned long section_nr,
> + struct page *start_page, unsigned long size)
> +{
> + /* TODO */
> +}
> +
> /*
> * Add memory segment to the segment list if it doesn't overlap with
> * an already present segment.
> diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
> index 85be1ca..7e28c9e 100644
> --- a/arch/sparc/mm/init_64.c
> +++ b/arch/sparc/mm/init_64.c
> @@ -2231,6 +2231,12 @@ void __meminit vmemmap_populate_print_last(void)
> node_start = 0;
> }
> }
> +
> +void register_page_bootmem_memmap(unsigned long section_nr,
> + struct page *start_page, unsigned long size)
> +{
> + /* TODO */
> +}
> #endif /* CONFIG_SPARSEMEM_VMEMMAP */
>
> static void prot_init_common(unsigned long page_none,
> diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
> index f78509c..aeaa27e 100644
> --- a/arch/x86/mm/init_64.c
> +++ b/arch/x86/mm/init_64.c
> @@ -1000,6 +1000,58 @@ vmemmap_populate(struct page *start_page, unsigned long size, int node)
> return 0;
> }
>
> +void register_page_bootmem_memmap(unsigned long section_nr,
> + struct page *start_page, unsigned long size)
> +{
> + unsigned long addr = (unsigned long)start_page;
> + unsigned long end = (unsigned long)(start_page + size);
> + unsigned long next;
> + pgd_t *pgd;
> + pud_t *pud;
> + pmd_t *pmd;
> +
> + for (; addr < end; addr = next) {
> + pte_t *pte = NULL;
> +
> + pgd = pgd_offset_k(addr);
> + if (pgd_none(*pgd)) {
> + next = (addr + PAGE_SIZE) & PAGE_MASK;
> + continue;
> + }
> + get_page_bootmem(section_nr, pgd_page(*pgd), MIX_SECTION_INFO);
> +
> + pud = pud_offset(pgd, addr);
> + if (pud_none(*pud)) {
> + next = (addr + PAGE_SIZE) & PAGE_MASK;
> + continue;
> + }
> + get_page_bootmem(section_nr, pud_page(*pud), MIX_SECTION_INFO);
> +
> + if (!cpu_has_pse) {
> + next = (addr + PAGE_SIZE) & PAGE_MASK;
> + pmd = pmd_offset(pud, addr);
> + if (pmd_none(*pmd))
> + continue;
> + get_page_bootmem(section_nr, pmd_page(*pmd),
> + MIX_SECTION_INFO);
> +
> + pte = pte_offset_kernel(pmd, addr);
> + if (pte_none(*pte))
> + continue;
> + get_page_bootmem(section_nr, pte_page(*pte),
> + SECTION_INFO);
> + } else {
> + next = pmd_addr_end(addr, end);
> +
> + pmd = pmd_offset(pud, addr);
> + if (pmd_none(*pmd))
> + continue;
> + get_page_bootmem(section_nr, pmd_page(*pmd),
> + SECTION_INFO);
Hi Tang,
In this case, pmd maps 512 pages, but you only get_page_bootmem() on the first page.
I think the whole 512 pages should be get_page_bootmem(), what do you think?
Thanks,
Jianguo Wu
> + }
> + }
> +}
> +
> void __meminit vmemmap_populate_print_last(void)
> {
> if (p_start) {
> diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
> index 31a563b..2441f36 100644
> --- a/include/linux/memory_hotplug.h
> +++ b/include/linux/memory_hotplug.h
> @@ -174,17 +174,10 @@ static inline void arch_refresh_nodedata(int nid, pg_data_t *pgdat)
> #endif /* CONFIG_NUMA */
> #endif /* CONFIG_HAVE_ARCH_NODEDATA_EXTENSION */
>
> -#ifdef CONFIG_SPARSEMEM_VMEMMAP
> -static inline void register_page_bootmem_info_node(struct pglist_data *pgdat)
> -{
> -}
> -static inline void put_page_bootmem(struct page *page)
> -{
> -}
> -#else
> extern void register_page_bootmem_info_node(struct pglist_data *pgdat);
> extern void put_page_bootmem(struct page *page);
> -#endif
> +extern void get_page_bootmem(unsigned long ingo, struct page *page,
> + unsigned long type);
>
> /*
> * Lock for memory hotplug guarantees 1) all callbacks for memory hotplug
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 6320407..1eca498 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -1709,7 +1709,8 @@ int vmemmap_populate_basepages(struct page *start_page,
> unsigned long pages, int node);
> int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
> void vmemmap_populate_print_last(void);
> -
> +void register_page_bootmem_memmap(unsigned long section_nr, struct page *map,
> + unsigned long size);
>
> enum mf_flags {
> MF_COUNT_INCREASED = 1 << 0,
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> index 2c5d734..34c656b 100644
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -91,9 +91,8 @@ static void release_memory_resource(struct resource *res)
> }
>
> #ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
> -#ifndef CONFIG_SPARSEMEM_VMEMMAP
> -static void get_page_bootmem(unsigned long info, struct page *page,
> - unsigned long type)
> +void get_page_bootmem(unsigned long info, struct page *page,
> + unsigned long type)
> {
> page->lru.next = (struct list_head *) type;
> SetPagePrivate(page);
> @@ -128,6 +127,7 @@ void __ref put_page_bootmem(struct page *page)
>
> }
>
> +#ifndef CONFIG_SPARSEMEM_VMEMMAP
> static void register_page_bootmem_info_section(unsigned long start_pfn)
> {
> unsigned long *usemap, mapsize, section_nr, i;
> @@ -161,6 +161,32 @@ static void register_page_bootmem_info_section(unsigned long start_pfn)
> get_page_bootmem(section_nr, page, MIX_SECTION_INFO);
>
> }
> +#else
> +static void register_page_bootmem_info_section(unsigned long start_pfn)
> +{
> + unsigned long *usemap, mapsize, section_nr, i;
> + struct mem_section *ms;
> + struct page *page, *memmap;
> +
> + if (!pfn_valid(start_pfn))
> + return;
> +
> + section_nr = pfn_to_section_nr(start_pfn);
> + ms = __nr_to_section(section_nr);
> +
> + memmap = sparse_decode_mem_map(ms->section_mem_map, section_nr);
> +
> + register_page_bootmem_memmap(section_nr, memmap, PAGES_PER_SECTION);
> +
> + usemap = __nr_to_section(section_nr)->pageblock_flags;
> + page = virt_to_page(usemap);
> +
> + mapsize = PAGE_ALIGN(usemap_size()) >> PAGE_SHIFT;
> +
> + for (i = 0; i < mapsize; i++, page++)
> + get_page_bootmem(section_nr, page, MIX_SECTION_INFO);
> +}
> +#endif
>
> void register_page_bootmem_info_node(struct pglist_data *pgdat)
> {
> @@ -203,7 +229,6 @@ void register_page_bootmem_info_node(struct pglist_data *pgdat)
> register_page_bootmem_info_section(pfn);
> }
> }
> -#endif /* !CONFIG_SPARSEMEM_VMEMMAP */
>
> static void grow_zone_span(struct zone *zone, unsigned long start_pfn,
> unsigned long end_pfn)
WARNING: multiple messages have this Message-ID (diff)
From: Jianguo Wu <wujianguo@huawei.com>
To: Tang Chen <tangchen@cn.fujitsu.com>
Cc: akpm@linux-foundation.org, rientjes@google.com, liuj97@gmail.com,
len.brown@intel.com, benh@kernel.crashing.org, paulus@samba.org,
cl@linux.com, minchan.kim@gmail.com,
kosaki.motohiro@jp.fujitsu.com, isimatu.yasuaki@jp.fujitsu.com,
wency@cn.fujitsu.com, hpa@zytor.com, linfeng@cn.fujitsu.com,
laijs@cn.fujitsu.com, mgorman@suse.de, yinghai@kernel.org,
x86@kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org, linux-acpi@vger.kernel.org,
linux-s390@vger.kernel.org, linux-sh@vger.kernel.org,
linux-ia64@vger.kernel.org, cmetcalf@tilera.com,
sparclinux@vger.kernel.org
Subject: Re: [PATCH v5 06/14] memory-hotplug: implement register_page_bootmem_info_section of sparse-vmemmap
Date: Tue, 25 Dec 2012 16:09:53 +0800 [thread overview]
Message-ID: <50D95F51.9090007@huawei.com> (raw)
In-Reply-To: <1356350964-13437-7-git-send-email-tangchen@cn.fujitsu.com>
On 2012/12/24 20:09, Tang Chen wrote:
> From: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
>
> For removing memmap region of sparse-vmemmap which is allocated bootmem,
> memmap region of sparse-vmemmap needs to be registered by get_page_bootmem().
> So the patch searches pages of virtual mapping and registers the pages by
> get_page_bootmem().
>
> Note: register_page_bootmem_memmap() is not implemented for ia64, ppc, s390,
> and sparc.
>
> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
> Signed-off-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
> ---
> arch/ia64/mm/discontig.c | 6 ++++
> arch/powerpc/mm/init_64.c | 6 ++++
> arch/s390/mm/vmem.c | 6 ++++
> arch/sparc/mm/init_64.c | 6 ++++
> arch/x86/mm/init_64.c | 52 ++++++++++++++++++++++++++++++++++++++++
> include/linux/memory_hotplug.h | 11 +-------
> include/linux/mm.h | 3 +-
> mm/memory_hotplug.c | 33 ++++++++++++++++++++++---
> 8 files changed, 109 insertions(+), 14 deletions(-)
>
> diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
> index c641333..33943db 100644
> --- a/arch/ia64/mm/discontig.c
> +++ b/arch/ia64/mm/discontig.c
> @@ -822,4 +822,10 @@ int __meminit vmemmap_populate(struct page *start_page,
> {
> return vmemmap_populate_basepages(start_page, size, node);
> }
> +
> +void register_page_bootmem_memmap(unsigned long section_nr,
> + struct page *start_page, unsigned long size)
> +{
> + /* TODO */
> +}
> #endif
> diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
> index 95a4529..6466440 100644
> --- a/arch/powerpc/mm/init_64.c
> +++ b/arch/powerpc/mm/init_64.c
> @@ -297,5 +297,11 @@ int __meminit vmemmap_populate(struct page *start_page,
>
> return 0;
> }
> +
> +void register_page_bootmem_memmap(unsigned long section_nr,
> + struct page *start_page, unsigned long size)
> +{
> + /* TODO */
> +}
> #endif /* CONFIG_SPARSEMEM_VMEMMAP */
>
> diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
> index 6ed1426..2c14bc2 100644
> --- a/arch/s390/mm/vmem.c
> +++ b/arch/s390/mm/vmem.c
> @@ -272,6 +272,12 @@ out:
> return ret;
> }
>
> +void register_page_bootmem_memmap(unsigned long section_nr,
> + struct page *start_page, unsigned long size)
> +{
> + /* TODO */
> +}
> +
> /*
> * Add memory segment to the segment list if it doesn't overlap with
> * an already present segment.
> diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
> index 85be1ca..7e28c9e 100644
> --- a/arch/sparc/mm/init_64.c
> +++ b/arch/sparc/mm/init_64.c
> @@ -2231,6 +2231,12 @@ void __meminit vmemmap_populate_print_last(void)
> node_start = 0;
> }
> }
> +
> +void register_page_bootmem_memmap(unsigned long section_nr,
> + struct page *start_page, unsigned long size)
> +{
> + /* TODO */
> +}
> #endif /* CONFIG_SPARSEMEM_VMEMMAP */
>
> static void prot_init_common(unsigned long page_none,
> diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
> index f78509c..aeaa27e 100644
> --- a/arch/x86/mm/init_64.c
> +++ b/arch/x86/mm/init_64.c
> @@ -1000,6 +1000,58 @@ vmemmap_populate(struct page *start_page, unsigned long size, int node)
> return 0;
> }
>
> +void register_page_bootmem_memmap(unsigned long section_nr,
> + struct page *start_page, unsigned long size)
> +{
> + unsigned long addr = (unsigned long)start_page;
> + unsigned long end = (unsigned long)(start_page + size);
> + unsigned long next;
> + pgd_t *pgd;
> + pud_t *pud;
> + pmd_t *pmd;
> +
> + for (; addr < end; addr = next) {
> + pte_t *pte = NULL;
> +
> + pgd = pgd_offset_k(addr);
> + if (pgd_none(*pgd)) {
> + next = (addr + PAGE_SIZE) & PAGE_MASK;
> + continue;
> + }
> + get_page_bootmem(section_nr, pgd_page(*pgd), MIX_SECTION_INFO);
> +
> + pud = pud_offset(pgd, addr);
> + if (pud_none(*pud)) {
> + next = (addr + PAGE_SIZE) & PAGE_MASK;
> + continue;
> + }
> + get_page_bootmem(section_nr, pud_page(*pud), MIX_SECTION_INFO);
> +
> + if (!cpu_has_pse) {
> + next = (addr + PAGE_SIZE) & PAGE_MASK;
> + pmd = pmd_offset(pud, addr);
> + if (pmd_none(*pmd))
> + continue;
> + get_page_bootmem(section_nr, pmd_page(*pmd),
> + MIX_SECTION_INFO);
> +
> + pte = pte_offset_kernel(pmd, addr);
> + if (pte_none(*pte))
> + continue;
> + get_page_bootmem(section_nr, pte_page(*pte),
> + SECTION_INFO);
> + } else {
> + next = pmd_addr_end(addr, end);
> +
> + pmd = pmd_offset(pud, addr);
> + if (pmd_none(*pmd))
> + continue;
> + get_page_bootmem(section_nr, pmd_page(*pmd),
> + SECTION_INFO);
Hi Tangi 1/4 ?
In this case, pmd maps 512 pages, but you only get_page_bootmem() on the first page.
I think the whole 512 pages should be get_page_bootmem(), what do you think?
Thanks,
Jianguo Wu
> + }
> + }
> +}
> +
> void __meminit vmemmap_populate_print_last(void)
> {
> if (p_start) {
> diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
> index 31a563b..2441f36 100644
> --- a/include/linux/memory_hotplug.h
> +++ b/include/linux/memory_hotplug.h
> @@ -174,17 +174,10 @@ static inline void arch_refresh_nodedata(int nid, pg_data_t *pgdat)
> #endif /* CONFIG_NUMA */
> #endif /* CONFIG_HAVE_ARCH_NODEDATA_EXTENSION */
>
> -#ifdef CONFIG_SPARSEMEM_VMEMMAP
> -static inline void register_page_bootmem_info_node(struct pglist_data *pgdat)
> -{
> -}
> -static inline void put_page_bootmem(struct page *page)
> -{
> -}
> -#else
> extern void register_page_bootmem_info_node(struct pglist_data *pgdat);
> extern void put_page_bootmem(struct page *page);
> -#endif
> +extern void get_page_bootmem(unsigned long ingo, struct page *page,
> + unsigned long type);
>
> /*
> * Lock for memory hotplug guarantees 1) all callbacks for memory hotplug
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 6320407..1eca498 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -1709,7 +1709,8 @@ int vmemmap_populate_basepages(struct page *start_page,
> unsigned long pages, int node);
> int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
> void vmemmap_populate_print_last(void);
> -
> +void register_page_bootmem_memmap(unsigned long section_nr, struct page *map,
> + unsigned long size);
>
> enum mf_flags {
> MF_COUNT_INCREASED = 1 << 0,
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> index 2c5d734..34c656b 100644
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -91,9 +91,8 @@ static void release_memory_resource(struct resource *res)
> }
>
> #ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
> -#ifndef CONFIG_SPARSEMEM_VMEMMAP
> -static void get_page_bootmem(unsigned long info, struct page *page,
> - unsigned long type)
> +void get_page_bootmem(unsigned long info, struct page *page,
> + unsigned long type)
> {
> page->lru.next = (struct list_head *) type;
> SetPagePrivate(page);
> @@ -128,6 +127,7 @@ void __ref put_page_bootmem(struct page *page)
>
> }
>
> +#ifndef CONFIG_SPARSEMEM_VMEMMAP
> static void register_page_bootmem_info_section(unsigned long start_pfn)
> {
> unsigned long *usemap, mapsize, section_nr, i;
> @@ -161,6 +161,32 @@ static void register_page_bootmem_info_section(unsigned long start_pfn)
> get_page_bootmem(section_nr, page, MIX_SECTION_INFO);
>
> }
> +#else
> +static void register_page_bootmem_info_section(unsigned long start_pfn)
> +{
> + unsigned long *usemap, mapsize, section_nr, i;
> + struct mem_section *ms;
> + struct page *page, *memmap;
> +
> + if (!pfn_valid(start_pfn))
> + return;
> +
> + section_nr = pfn_to_section_nr(start_pfn);
> + ms = __nr_to_section(section_nr);
> +
> + memmap = sparse_decode_mem_map(ms->section_mem_map, section_nr);
> +
> + register_page_bootmem_memmap(section_nr, memmap, PAGES_PER_SECTION);
> +
> + usemap = __nr_to_section(section_nr)->pageblock_flags;
> + page = virt_to_page(usemap);
> +
> + mapsize = PAGE_ALIGN(usemap_size()) >> PAGE_SHIFT;
> +
> + for (i = 0; i < mapsize; i++, page++)
> + get_page_bootmem(section_nr, page, MIX_SECTION_INFO);
> +}
> +#endif
>
> void register_page_bootmem_info_node(struct pglist_data *pgdat)
> {
> @@ -203,7 +229,6 @@ void register_page_bootmem_info_node(struct pglist_data *pgdat)
> register_page_bootmem_info_section(pfn);
> }
> }
> -#endif /* !CONFIG_SPARSEMEM_VMEMMAP */
>
> static void grow_zone_span(struct zone *zone, unsigned long start_pfn,
> unsigned long end_pfn)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
WARNING: multiple messages have this Message-ID (diff)
From: Jianguo Wu <wujianguo@huawei.com>
To: Tang Chen <tangchen@cn.fujitsu.com>
Cc: <akpm@linux-foundation.org>, <rientjes@google.com>,
<liuj97@gmail.com>, <len.brown@intel.com>,
<benh@kernel.crashing.org>, <paulus@samba.org>, <cl@linux.com>,
<minchan.kim@gmail.com>, <kosaki.motohiro@jp.fujitsu.com>,
<isimatu.yasuaki@jp.fujitsu.com>, <wency@cn.fujitsu.com>,
<hpa@zytor.com>, <linfeng@cn.fujitsu.com>, <laijs@cn.fujitsu.com>,
<mgorman@suse.de>, <yinghai@kernel.org>, <x86@kernel.org>,
<linux-mm@kvack.org>, <linux-kernel@vger.kernel.org>,
<linuxppc-dev@lists.ozlabs.org>, <linux-acpi@vger.kernel.org>,
<linux-s390@vger.kernel.org>, <linux-sh@vger.kernel.org>,
<linux-ia64@vger.kernel.org>, <cmetcalf@tilera.com>,
<sparclinux@vger.kernel.org>
Subject: Re: [PATCH v5 06/14] memory-hotplug: implement register_page_bootmem_info_section of sparse-vmemmap
Date: Tue, 25 Dec 2012 16:09:53 +0800 [thread overview]
Message-ID: <50D95F51.9090007@huawei.com> (raw)
In-Reply-To: <1356350964-13437-7-git-send-email-tangchen@cn.fujitsu.com>
On 2012/12/24 20:09, Tang Chen wrote:
> From: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
>
> For removing memmap region of sparse-vmemmap which is allocated bootmem,
> memmap region of sparse-vmemmap needs to be registered by get_page_bootmem().
> So the patch searches pages of virtual mapping and registers the pages by
> get_page_bootmem().
>
> Note: register_page_bootmem_memmap() is not implemented for ia64, ppc, s390,
> and sparc.
>
> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
> Signed-off-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
> ---
> arch/ia64/mm/discontig.c | 6 ++++
> arch/powerpc/mm/init_64.c | 6 ++++
> arch/s390/mm/vmem.c | 6 ++++
> arch/sparc/mm/init_64.c | 6 ++++
> arch/x86/mm/init_64.c | 52 ++++++++++++++++++++++++++++++++++++++++
> include/linux/memory_hotplug.h | 11 +-------
> include/linux/mm.h | 3 +-
> mm/memory_hotplug.c | 33 ++++++++++++++++++++++---
> 8 files changed, 109 insertions(+), 14 deletions(-)
>
> diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
> index c641333..33943db 100644
> --- a/arch/ia64/mm/discontig.c
> +++ b/arch/ia64/mm/discontig.c
> @@ -822,4 +822,10 @@ int __meminit vmemmap_populate(struct page *start_page,
> {
> return vmemmap_populate_basepages(start_page, size, node);
> }
> +
> +void register_page_bootmem_memmap(unsigned long section_nr,
> + struct page *start_page, unsigned long size)
> +{
> + /* TODO */
> +}
> #endif
> diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
> index 95a4529..6466440 100644
> --- a/arch/powerpc/mm/init_64.c
> +++ b/arch/powerpc/mm/init_64.c
> @@ -297,5 +297,11 @@ int __meminit vmemmap_populate(struct page *start_page,
>
> return 0;
> }
> +
> +void register_page_bootmem_memmap(unsigned long section_nr,
> + struct page *start_page, unsigned long size)
> +{
> + /* TODO */
> +}
> #endif /* CONFIG_SPARSEMEM_VMEMMAP */
>
> diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
> index 6ed1426..2c14bc2 100644
> --- a/arch/s390/mm/vmem.c
> +++ b/arch/s390/mm/vmem.c
> @@ -272,6 +272,12 @@ out:
> return ret;
> }
>
> +void register_page_bootmem_memmap(unsigned long section_nr,
> + struct page *start_page, unsigned long size)
> +{
> + /* TODO */
> +}
> +
> /*
> * Add memory segment to the segment list if it doesn't overlap with
> * an already present segment.
> diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
> index 85be1ca..7e28c9e 100644
> --- a/arch/sparc/mm/init_64.c
> +++ b/arch/sparc/mm/init_64.c
> @@ -2231,6 +2231,12 @@ void __meminit vmemmap_populate_print_last(void)
> node_start = 0;
> }
> }
> +
> +void register_page_bootmem_memmap(unsigned long section_nr,
> + struct page *start_page, unsigned long size)
> +{
> + /* TODO */
> +}
> #endif /* CONFIG_SPARSEMEM_VMEMMAP */
>
> static void prot_init_common(unsigned long page_none,
> diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
> index f78509c..aeaa27e 100644
> --- a/arch/x86/mm/init_64.c
> +++ b/arch/x86/mm/init_64.c
> @@ -1000,6 +1000,58 @@ vmemmap_populate(struct page *start_page, unsigned long size, int node)
> return 0;
> }
>
> +void register_page_bootmem_memmap(unsigned long section_nr,
> + struct page *start_page, unsigned long size)
> +{
> + unsigned long addr = (unsigned long)start_page;
> + unsigned long end = (unsigned long)(start_page + size);
> + unsigned long next;
> + pgd_t *pgd;
> + pud_t *pud;
> + pmd_t *pmd;
> +
> + for (; addr < end; addr = next) {
> + pte_t *pte = NULL;
> +
> + pgd = pgd_offset_k(addr);
> + if (pgd_none(*pgd)) {
> + next = (addr + PAGE_SIZE) & PAGE_MASK;
> + continue;
> + }
> + get_page_bootmem(section_nr, pgd_page(*pgd), MIX_SECTION_INFO);
> +
> + pud = pud_offset(pgd, addr);
> + if (pud_none(*pud)) {
> + next = (addr + PAGE_SIZE) & PAGE_MASK;
> + continue;
> + }
> + get_page_bootmem(section_nr, pud_page(*pud), MIX_SECTION_INFO);
> +
> + if (!cpu_has_pse) {
> + next = (addr + PAGE_SIZE) & PAGE_MASK;
> + pmd = pmd_offset(pud, addr);
> + if (pmd_none(*pmd))
> + continue;
> + get_page_bootmem(section_nr, pmd_page(*pmd),
> + MIX_SECTION_INFO);
> +
> + pte = pte_offset_kernel(pmd, addr);
> + if (pte_none(*pte))
> + continue;
> + get_page_bootmem(section_nr, pte_page(*pte),
> + SECTION_INFO);
> + } else {
> + next = pmd_addr_end(addr, end);
> +
> + pmd = pmd_offset(pud, addr);
> + if (pmd_none(*pmd))
> + continue;
> + get_page_bootmem(section_nr, pmd_page(*pmd),
> + SECTION_INFO);
Hi Tang,
In this case, pmd maps 512 pages, but you only get_page_bootmem() on the first page.
I think the whole 512 pages should be get_page_bootmem(), what do you think?
Thanks,
Jianguo Wu
> + }
> + }
> +}
> +
> void __meminit vmemmap_populate_print_last(void)
> {
> if (p_start) {
> diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
> index 31a563b..2441f36 100644
> --- a/include/linux/memory_hotplug.h
> +++ b/include/linux/memory_hotplug.h
> @@ -174,17 +174,10 @@ static inline void arch_refresh_nodedata(int nid, pg_data_t *pgdat)
> #endif /* CONFIG_NUMA */
> #endif /* CONFIG_HAVE_ARCH_NODEDATA_EXTENSION */
>
> -#ifdef CONFIG_SPARSEMEM_VMEMMAP
> -static inline void register_page_bootmem_info_node(struct pglist_data *pgdat)
> -{
> -}
> -static inline void put_page_bootmem(struct page *page)
> -{
> -}
> -#else
> extern void register_page_bootmem_info_node(struct pglist_data *pgdat);
> extern void put_page_bootmem(struct page *page);
> -#endif
> +extern void get_page_bootmem(unsigned long ingo, struct page *page,
> + unsigned long type);
>
> /*
> * Lock for memory hotplug guarantees 1) all callbacks for memory hotplug
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 6320407..1eca498 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -1709,7 +1709,8 @@ int vmemmap_populate_basepages(struct page *start_page,
> unsigned long pages, int node);
> int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
> void vmemmap_populate_print_last(void);
> -
> +void register_page_bootmem_memmap(unsigned long section_nr, struct page *map,
> + unsigned long size);
>
> enum mf_flags {
> MF_COUNT_INCREASED = 1 << 0,
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> index 2c5d734..34c656b 100644
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -91,9 +91,8 @@ static void release_memory_resource(struct resource *res)
> }
>
> #ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
> -#ifndef CONFIG_SPARSEMEM_VMEMMAP
> -static void get_page_bootmem(unsigned long info, struct page *page,
> - unsigned long type)
> +void get_page_bootmem(unsigned long info, struct page *page,
> + unsigned long type)
> {
> page->lru.next = (struct list_head *) type;
> SetPagePrivate(page);
> @@ -128,6 +127,7 @@ void __ref put_page_bootmem(struct page *page)
>
> }
>
> +#ifndef CONFIG_SPARSEMEM_VMEMMAP
> static void register_page_bootmem_info_section(unsigned long start_pfn)
> {
> unsigned long *usemap, mapsize, section_nr, i;
> @@ -161,6 +161,32 @@ static void register_page_bootmem_info_section(unsigned long start_pfn)
> get_page_bootmem(section_nr, page, MIX_SECTION_INFO);
>
> }
> +#else
> +static void register_page_bootmem_info_section(unsigned long start_pfn)
> +{
> + unsigned long *usemap, mapsize, section_nr, i;
> + struct mem_section *ms;
> + struct page *page, *memmap;
> +
> + if (!pfn_valid(start_pfn))
> + return;
> +
> + section_nr = pfn_to_section_nr(start_pfn);
> + ms = __nr_to_section(section_nr);
> +
> + memmap = sparse_decode_mem_map(ms->section_mem_map, section_nr);
> +
> + register_page_bootmem_memmap(section_nr, memmap, PAGES_PER_SECTION);
> +
> + usemap = __nr_to_section(section_nr)->pageblock_flags;
> + page = virt_to_page(usemap);
> +
> + mapsize = PAGE_ALIGN(usemap_size()) >> PAGE_SHIFT;
> +
> + for (i = 0; i < mapsize; i++, page++)
> + get_page_bootmem(section_nr, page, MIX_SECTION_INFO);
> +}
> +#endif
>
> void register_page_bootmem_info_node(struct pglist_data *pgdat)
> {
> @@ -203,7 +229,6 @@ void register_page_bootmem_info_node(struct pglist_data *pgdat)
> register_page_bootmem_info_section(pfn);
> }
> }
> -#endif /* !CONFIG_SPARSEMEM_VMEMMAP */
>
> static void grow_zone_span(struct zone *zone, unsigned long start_pfn,
> unsigned long end_pfn)
next prev parent reply other threads:[~2012-12-25 8:09 UTC|newest]
Thread overview: 194+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-12-24 12:09 [PATCH v5 00/14] memory-hotplug: hot-remove physical memory Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` [PATCH v5 01/14] memory-hotplug: try to offline the memory twice to avoid dependence Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-25 8:35 ` Glauber Costa
2012-12-25 8:35 ` Glauber Costa
2012-12-25 8:35 ` Glauber Costa
2012-12-25 8:35 ` Glauber Costa
2012-12-25 8:35 ` Glauber Costa
2012-12-30 5:58 ` Wen Congyang
2012-12-30 5:58 ` Wen Congyang
2012-12-30 5:58 ` Wen Congyang
2012-12-30 5:58 ` Wen Congyang
2013-01-09 15:09 ` Glauber Costa
2013-01-09 15:09 ` Glauber Costa
2013-01-09 15:09 ` Glauber Costa
2013-01-09 15:09 ` Glauber Costa
2013-01-09 15:09 ` Glauber Costa
2013-01-10 1:38 ` Tang Chen
2013-01-10 1:38 ` Tang Chen
2013-01-10 1:38 ` Tang Chen
2013-01-10 1:38 ` Tang Chen
2013-02-06 3:07 ` Tang Chen
2013-02-06 3:07 ` Tang Chen
2013-02-06 3:07 ` Tang Chen
2013-02-06 3:07 ` Tang Chen
2013-02-06 9:17 ` Tang Chen
2013-02-06 9:17 ` Tang Chen
2013-02-06 9:17 ` Tang Chen
2013-02-06 9:17 ` Tang Chen
2013-02-06 10:10 ` Tang Chen
2013-02-06 10:10 ` Tang Chen
2013-02-06 10:10 ` Tang Chen
2013-02-06 10:10 ` Tang Chen
2013-02-06 14:24 ` Glauber Costa
2013-02-06 14:24 ` Glauber Costa
2013-02-06 14:24 ` Glauber Costa
2013-02-06 14:24 ` Glauber Costa
2013-02-06 14:24 ` Glauber Costa
2013-02-07 7:56 ` Tang Chen
2013-02-07 7:56 ` Tang Chen
2013-02-07 7:56 ` Tang Chen
2013-02-07 7:56 ` Tang Chen
2012-12-26 3:02 ` Kamezawa Hiroyuki
2012-12-26 3:02 ` Kamezawa Hiroyuki
2012-12-26 3:02 ` Kamezawa Hiroyuki
2012-12-26 3:02 ` Kamezawa Hiroyuki
2012-12-30 5:49 ` Wen Congyang
2012-12-30 5:49 ` Wen Congyang
2012-12-30 5:49 ` Wen Congyang
2012-12-30 5:49 ` Wen Congyang
2012-12-24 12:09 ` [PATCH v5 02/14] memory-hotplug: check whether all memory blocks are offlined or not when removing memory Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` [PATCH v5 02/14] memory-hotplug: check whether all memory blocks are offlined or not when removing m Tang Chen
2012-12-26 3:10 ` [PATCH v5 02/14] memory-hotplug: check whether all memory blocks are offlined or not when removing memory Kamezawa Hiroyuki
2012-12-26 3:10 ` Kamezawa Hiroyuki
2012-12-26 3:10 ` Kamezawa Hiroyuki
2012-12-26 3:10 ` [PATCH v5 02/14] memory-hotplug: check whether all memory blocks are offlined or not when removi Kamezawa Hiroyuki
2012-12-27 3:10 ` [PATCH v5 02/14] memory-hotplug: check whether all memory blocks are offlined or not when removing memory Tang Chen
2012-12-27 3:10 ` Tang Chen
2012-12-27 3:10 ` Tang Chen
2012-12-27 3:10 ` [PATCH v5 02/14] memory-hotplug: check whether all memory blocks are offlined or not when removi Tang Chen
2012-12-24 12:09 ` [PATCH v5 03/14] memory-hotplug: remove redundant codes Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-26 3:20 ` Kamezawa Hiroyuki
2012-12-26 3:20 ` Kamezawa Hiroyuki
2012-12-26 3:20 ` Kamezawa Hiroyuki
2012-12-26 3:20 ` Kamezawa Hiroyuki
2012-12-27 3:09 ` Tang Chen
2012-12-27 3:09 ` Tang Chen
2012-12-27 3:09 ` Tang Chen
2012-12-27 3:09 ` Tang Chen
2012-12-24 12:09 ` [PATCH v5 04/14] memory-hotplug: remove /sys/firmware/memmap/X sysfs Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-26 3:30 ` Kamezawa Hiroyuki
2012-12-26 3:30 ` Kamezawa Hiroyuki
2012-12-26 3:30 ` Kamezawa Hiroyuki
2012-12-26 3:30 ` Kamezawa Hiroyuki
2012-12-27 3:09 ` Tang Chen
2012-12-27 3:09 ` Tang Chen
2012-12-27 3:09 ` Tang Chen
2012-12-27 3:09 ` Tang Chen
2013-01-02 14:24 ` Christoph Lameter
2013-01-02 14:24 ` Christoph Lameter
2013-01-02 14:24 ` Christoph Lameter
2013-01-02 14:24 ` Christoph Lameter
2012-12-24 12:09 ` [PATCH v5 05/14] memory-hotplug: introduce new function arch_remove_memory() for removing page table depends on architecture Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` [PATCH v5 05/14] memory-hotplug: introduce new function arch_remove_memory() for removing page table Tang Chen
2012-12-26 3:37 ` [PATCH v5 05/14] memory-hotplug: introduce new function arch_remove_memory() for removing page table depends on architecture Kamezawa Hiroyuki
2012-12-26 3:37 ` Kamezawa Hiroyuki
2012-12-26 3:37 ` Kamezawa Hiroyuki
2012-12-26 3:37 ` [PATCH v5 05/14] memory-hotplug: introduce new function arch_remove_memory() for removing page t Kamezawa Hiroyuki
2012-12-24 12:09 ` [PATCH v5 06/14] memory-hotplug: implement register_page_bootmem_info_section of sparse-vmemmap Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-25 8:09 ` Jianguo Wu [this message]
2012-12-25 8:09 ` Jianguo Wu
2012-12-25 8:09 ` Jianguo Wu
2012-12-25 8:09 ` Jianguo Wu
2012-12-25 8:09 ` Jianguo Wu
2012-12-26 3:21 ` Tang Chen
2012-12-26 3:21 ` Tang Chen
2012-12-26 3:21 ` Tang Chen
2012-12-26 3:21 ` Tang Chen
2012-12-24 12:09 ` [PATCH v5 07/14] memory-hotplug: move pgdat_resize_lock into sparse_remove_one_section() Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-26 3:47 ` Kamezawa Hiroyuki
2012-12-26 3:47 ` Kamezawa Hiroyuki
2012-12-26 3:47 ` Kamezawa Hiroyuki
2012-12-26 3:47 ` Kamezawa Hiroyuki
2012-12-26 6:20 ` Tang Chen
2012-12-26 6:20 ` Tang Chen
2012-12-26 6:20 ` Tang Chen
2012-12-26 6:20 ` Tang Chen
2012-12-24 12:09 ` [PATCH v5 08/14] memory-hotplug: Common APIs to support page tables hot-remove Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-25 8:17 ` Jianguo Wu
2012-12-25 8:17 ` Jianguo Wu
2012-12-25 8:17 ` Jianguo Wu
2012-12-25 8:17 ` Jianguo Wu
2012-12-26 2:49 ` Tang Chen
2012-12-26 2:49 ` Tang Chen
2012-12-26 2:49 ` Tang Chen
2012-12-26 2:49 ` Tang Chen
2012-12-26 3:11 ` Tang Chen
2012-12-26 3:11 ` Tang Chen
2012-12-26 3:11 ` Tang Chen
2012-12-26 3:11 ` Tang Chen
2012-12-26 3:19 ` Tang Chen
2012-12-26 3:19 ` Tang Chen
2012-12-26 3:19 ` Tang Chen
2012-12-26 3:19 ` Tang Chen
2012-12-24 12:09 ` [PATCH v5 09/14] memory-hotplug: remove page table of x86_64 architecture Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` [PATCH v5 10/14] memory-hotplug: remove memmap of sparse-vmemmap Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` [PATCH v5 11/14] memory-hotplug: Integrated __remove_section() of CONFIG_SPARSEMEM_VMEMMAP Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` [PATCH v5 12/14] memory-hotplug: memory_hotplug: clear zone when removing the memory Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` [PATCH v5 13/14] memory-hotplug: remove sysfs file of node Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` [PATCH v5 14/14] memory-hotplug: free node_data when a node is offlined Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-24 12:09 ` Tang Chen
2012-12-26 3:55 ` Kamezawa Hiroyuki
2012-12-26 3:55 ` Kamezawa Hiroyuki
2012-12-26 3:55 ` Kamezawa Hiroyuki
2012-12-26 3:55 ` Kamezawa Hiroyuki
2012-12-27 12:16 ` Wen Congyang
2012-12-27 12:16 ` Wen Congyang
2012-12-27 12:16 ` Wen Congyang
2012-12-27 12:16 ` Wen Congyang
2012-12-28 0:28 ` Kamezawa Hiroyuki
2012-12-28 0:28 ` Kamezawa Hiroyuki
2012-12-28 0:28 ` Kamezawa Hiroyuki
2012-12-28 0:28 ` Kamezawa Hiroyuki
2012-12-30 5:55 ` Wen Congyang
2012-12-30 6:02 ` Wen Congyang
2012-12-30 6:02 ` Wen Congyang
2012-12-30 6:02 ` Wen Congyang
2012-12-30 5:55 ` Wen Congyang
2012-12-30 5:55 ` Wen Congyang
2013-01-07 5:30 ` Kamezawa Hiroyuki
2013-01-07 5:30 ` Kamezawa Hiroyuki
2013-01-07 5:30 ` Kamezawa Hiroyuki
2013-01-07 5:30 ` Kamezawa Hiroyuki
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=50D95F51.9090007@huawei.com \
--to=wujianguo@huawei.com \
--cc=akpm@linux-foundation.org \
--cc=benh@kernel.crashing.org \
--cc=cl@linux.com \
--cc=cmetcalf@tilera.com \
--cc=hpa@zytor.com \
--cc=isimatu.yasuaki@jp.fujitsu.com \
--cc=kosaki.motohiro@jp.fujitsu.com \
--cc=laijs@cn.fujitsu.com \
--cc=len.brown@intel.com \
--cc=linfeng@cn.fujitsu.com \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-ia64@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-s390@vger.kernel.org \
--cc=linux-sh@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=liuj97@gmail.com \
--cc=mgorman@suse.de \
--cc=minchan.kim@gmail.com \
--cc=paulus@samba.org \
--cc=rientjes@google.com \
--cc=sparclinux@vger.kernel.org \
--cc=tangchen@cn.fujitsu.com \
--cc=wency@cn.fujitsu.com \
--cc=x86@kernel.org \
--cc=yinghai@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.