From: Tang Chen <tangchen@cn.fujitsu.com>
To: Wen Congyang <wency@cn.fujitsu.com>
Cc: 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, David Rientjes <rientjes@google.com>,
Jiang Liu <liuj97@gmail.com>, Len Brown <len.brown@intel.com>,
benh@kernel.crashing.org, paulus@samba.org,
Christoph Lameter <cl@linux.com>,
Minchan Kim <minchan.kim@gmail.com>,
Andrew Morton <akpm@linux-foundation.org>,
KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>,
Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>,
Jianguo Wu <wujianguo@huawei.com>
Subject: Re: [Patch v4 10/12] memory-hotplug: memory_hotplug: clear zone when removing the memory
Date: Tue, 04 Dec 2012 18:09:37 +0800 [thread overview]
Message-ID: <50BDCBE1.7030001@cn.fujitsu.com> (raw)
In-Reply-To: <1354010422-19648-11-git-send-email-wency@cn.fujitsu.com>
On 11/27/2012 06:00 PM, Wen Congyang wrote:
> From: Yasuaki Ishimatsu<isimatu.yasuaki@jp.fujitsu.com>
>
> When a memory is added, we update zone's and pgdat's start_pfn and
> spanned_pages in the function __add_zone(). So we should revert them
> when the memory is removed.
>
> The patch adds a new function __remove_zone() to do this.
>
> CC: David Rientjes<rientjes@google.com>
> CC: Jiang Liu<liuj97@gmail.com>
> CC: Len Brown<len.brown@intel.com>
> CC: Christoph Lameter<cl@linux.com>
> Cc: Minchan Kim<minchan.kim@gmail.com>
> CC: Andrew Morton<akpm@linux-foundation.org>
> CC: KOSAKI Motohiro<kosaki.motohiro@jp.fujitsu.com>
> Signed-off-by: Yasuaki Ishimatsu<isimatu.yasuaki@jp.fujitsu.com>
> Signed-off-by: Wen Congyang<wency@cn.fujitsu.com>
Reviewed-by: Tang Chen <tangchen@cn.fujitsu.com>
> ---
> mm/memory_hotplug.c | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 207 insertions(+)
>
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> index 7797e91..aa97d56 100644
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -301,10 +301,213 @@ static int __meminit __add_section(int nid, struct zone *zone,
> return register_new_memory(nid, __pfn_to_section(phys_start_pfn));
> }
>
> +/* find the smallest valid pfn in the range [start_pfn, end_pfn) */
> +static int find_smallest_section_pfn(int nid, struct zone *zone,
> + unsigned long start_pfn,
> + unsigned long end_pfn)
> +{
> + struct mem_section *ms;
> +
> + for (; start_pfn< end_pfn; start_pfn += PAGES_PER_SECTION) {
> + ms = __pfn_to_section(start_pfn);
> +
> + if (unlikely(!valid_section(ms)))
> + continue;
> +
> + if (unlikely(pfn_to_nid(start_pfn) != nid))
> + continue;
> +
> + if (zone&& zone != page_zone(pfn_to_page(start_pfn)))
> + continue;
> +
> + return start_pfn;
> + }
> +
> + return 0;
> +}
> +
> +/* find the biggest valid pfn in the range [start_pfn, end_pfn). */
> +static int find_biggest_section_pfn(int nid, struct zone *zone,
> + unsigned long start_pfn,
> + unsigned long end_pfn)
> +{
> + struct mem_section *ms;
> + unsigned long pfn;
> +
> + /* pfn is the end pfn of a memory section. */
> + pfn = end_pfn - 1;
> + for (; pfn>= start_pfn; pfn -= PAGES_PER_SECTION) {
> + ms = __pfn_to_section(pfn);
> +
> + if (unlikely(!valid_section(ms)))
> + continue;
> +
> + if (unlikely(pfn_to_nid(pfn) != nid))
> + continue;
> +
> + if (zone&& zone != page_zone(pfn_to_page(pfn)))
> + continue;
> +
> + return pfn;
> + }
> +
> + return 0;
> +}
> +
> +static void shrink_zone_span(struct zone *zone, unsigned long start_pfn,
> + unsigned long end_pfn)
> +{
> + unsigned long zone_start_pfn = zone->zone_start_pfn;
> + unsigned long zone_end_pfn = zone->zone_start_pfn + zone->spanned_pages;
> + unsigned long pfn;
> + struct mem_section *ms;
> + int nid = zone_to_nid(zone);
> +
> + zone_span_writelock(zone);
> + if (zone_start_pfn == start_pfn) {
> + /*
> + * If the section is smallest section in the zone, it need
> + * shrink zone->zone_start_pfn and zone->zone_spanned_pages.
> + * In this case, we find second smallest valid mem_section
> + * for shrinking zone.
> + */
> + pfn = find_smallest_section_pfn(nid, zone, end_pfn,
> + zone_end_pfn);
> + if (pfn) {
> + zone->zone_start_pfn = pfn;
> + zone->spanned_pages = zone_end_pfn - pfn;
> + }
> + } else if (zone_end_pfn == end_pfn) {
> + /*
> + * If the section is biggest section in the zone, it need
> + * shrink zone->spanned_pages.
> + * In this case, we find second biggest valid mem_section for
> + * shrinking zone.
> + */
> + pfn = find_biggest_section_pfn(nid, zone, zone_start_pfn,
> + start_pfn);
> + if (pfn)
> + zone->spanned_pages = pfn - zone_start_pfn + 1;
> + }
> +
> + /*
> + * The section is not biggest or smallest mem_section in the zone, it
> + * only creates a hole in the zone. So in this case, we need not
> + * change the zone. But perhaps, the zone has only hole data. Thus
> + * it check the zone has only hole or not.
> + */
> + pfn = zone_start_pfn;
> + for (; pfn< zone_end_pfn; pfn += PAGES_PER_SECTION) {
> + ms = __pfn_to_section(pfn);
> +
> + if (unlikely(!valid_section(ms)))
> + continue;
> +
> + if (page_zone(pfn_to_page(pfn)) != zone)
> + continue;
> +
> + /* If the section is current section, it continues the loop */
> + if (start_pfn == pfn)
> + continue;
> +
> + /* If we find valid section, we have nothing to do */
> + zone_span_writeunlock(zone);
> + return;
> + }
> +
> + /* The zone has no valid section */
> + zone->zone_start_pfn = 0;
> + zone->spanned_pages = 0;
> + zone_span_writeunlock(zone);
> +}
> +
> +static void shrink_pgdat_span(struct pglist_data *pgdat,
> + unsigned long start_pfn, unsigned long end_pfn)
> +{
> + unsigned long pgdat_start_pfn = pgdat->node_start_pfn;
> + unsigned long pgdat_end_pfn =
> + pgdat->node_start_pfn + pgdat->node_spanned_pages;
> + unsigned long pfn;
> + struct mem_section *ms;
> + int nid = pgdat->node_id;
> +
> + if (pgdat_start_pfn == start_pfn) {
> + /*
> + * If the section is smallest section in the pgdat, it need
> + * shrink pgdat->node_start_pfn and pgdat->node_spanned_pages.
> + * In this case, we find second smallest valid mem_section
> + * for shrinking zone.
> + */
> + pfn = find_smallest_section_pfn(nid, NULL, end_pfn,
> + pgdat_end_pfn);
> + if (pfn) {
> + pgdat->node_start_pfn = pfn;
> + pgdat->node_spanned_pages = pgdat_end_pfn - pfn;
> + }
> + } else if (pgdat_end_pfn == end_pfn) {
> + /*
> + * If the section is biggest section in the pgdat, it need
> + * shrink pgdat->node_spanned_pages.
> + * In this case, we find second biggest valid mem_section for
> + * shrinking zone.
> + */
> + pfn = find_biggest_section_pfn(nid, NULL, pgdat_start_pfn,
> + start_pfn);
> + if (pfn)
> + pgdat->node_spanned_pages = pfn - pgdat_start_pfn + 1;
> + }
> +
> + /*
> + * If the section is not biggest or smallest mem_section in the pgdat,
> + * it only creates a hole in the pgdat. So in this case, we need not
> + * change the pgdat.
> + * But perhaps, the pgdat has only hole data. Thus it check the pgdat
> + * has only hole or not.
> + */
> + pfn = pgdat_start_pfn;
> + for (; pfn< pgdat_end_pfn; pfn += PAGES_PER_SECTION) {
> + ms = __pfn_to_section(pfn);
> +
> + if (unlikely(!valid_section(ms)))
> + continue;
> +
> + if (pfn_to_nid(pfn) != nid)
> + continue;
> +
> + /* If the section is current section, it continues the loop */
> + if (start_pfn == pfn)
> + continue;
> +
> + /* If we find valid section, we have nothing to do */
> + return;
> + }
> +
> + /* The pgdat has no valid section */
> + pgdat->node_start_pfn = 0;
> + pgdat->node_spanned_pages = 0;
> +}
> +
> +static void __remove_zone(struct zone *zone, unsigned long start_pfn)
> +{
> + struct pglist_data *pgdat = zone->zone_pgdat;
> + int nr_pages = PAGES_PER_SECTION;
> + int zone_type;
> + unsigned long flags;
> +
> + zone_type = zone - pgdat->node_zones;
> +
> + pgdat_resize_lock(zone->zone_pgdat,&flags);
> + shrink_zone_span(zone, start_pfn, start_pfn + nr_pages);
> + shrink_pgdat_span(pgdat, start_pfn, start_pfn + nr_pages);
> + pgdat_resize_unlock(zone->zone_pgdat,&flags);
> +}
> +
> static int __remove_section(struct zone *zone, struct mem_section *ms)
> {
> unsigned long flags;
> struct pglist_data *pgdat = zone->zone_pgdat;
> + unsigned long start_pfn;
> + int scn_nr;
> int ret = -EINVAL;
>
> if (!valid_section(ms))
> @@ -314,6 +517,10 @@ static int __remove_section(struct zone *zone, struct mem_section *ms)
> if (ret)
> return ret;
>
> + scn_nr = __section_nr(ms);
> + start_pfn = section_nr_to_pfn(scn_nr);
> + __remove_zone(zone, start_pfn);
> +
> pgdat_resize_lock(pgdat,&flags);
> sparse_remove_one_section(zone, ms);
> pgdat_resize_unlock(pgdat,&flags);
--
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: Tang Chen <tangchen@cn.fujitsu.com>
To: Wen Congyang <wency@cn.fujitsu.com>
Cc: 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, David Rientjes <rientjes@google.com>,
Jiang Liu <liuj97@gmail.com>, Len Brown <len.brown@intel.com>,
benh@kernel.crashing.org, paulus@samba.org,
Christoph Lameter <cl@linux.com>,
Minchan Kim <minchan.kim@gmail.com>,
Andrew Morton <akpm@linux-foundation.org>,
KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>,
Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>,
Jianguo Wu <wujianguo@huawei.com>
Subject: Re: [Patch v4 10/12] memory-hotplug: memory_hotplug: clear zone when removing the memory
Date: Tue, 04 Dec 2012 10:09:37 +0000 [thread overview]
Message-ID: <50BDCBE1.7030001@cn.fujitsu.com> (raw)
In-Reply-To: <1354010422-19648-11-git-send-email-wency@cn.fujitsu.com>
On 11/27/2012 06:00 PM, Wen Congyang wrote:
> From: Yasuaki Ishimatsu<isimatu.yasuaki@jp.fujitsu.com>
>
> When a memory is added, we update zone's and pgdat's start_pfn and
> spanned_pages in the function __add_zone(). So we should revert them
> when the memory is removed.
>
> The patch adds a new function __remove_zone() to do this.
>
> CC: David Rientjes<rientjes@google.com>
> CC: Jiang Liu<liuj97@gmail.com>
> CC: Len Brown<len.brown@intel.com>
> CC: Christoph Lameter<cl@linux.com>
> Cc: Minchan Kim<minchan.kim@gmail.com>
> CC: Andrew Morton<akpm@linux-foundation.org>
> CC: KOSAKI Motohiro<kosaki.motohiro@jp.fujitsu.com>
> Signed-off-by: Yasuaki Ishimatsu<isimatu.yasuaki@jp.fujitsu.com>
> Signed-off-by: Wen Congyang<wency@cn.fujitsu.com>
Reviewed-by: Tang Chen <tangchen@cn.fujitsu.com>
> ---
> mm/memory_hotplug.c | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 207 insertions(+)
>
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> index 7797e91..aa97d56 100644
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -301,10 +301,213 @@ static int __meminit __add_section(int nid, struct zone *zone,
> return register_new_memory(nid, __pfn_to_section(phys_start_pfn));
> }
>
> +/* find the smallest valid pfn in the range [start_pfn, end_pfn) */
> +static int find_smallest_section_pfn(int nid, struct zone *zone,
> + unsigned long start_pfn,
> + unsigned long end_pfn)
> +{
> + struct mem_section *ms;
> +
> + for (; start_pfn< end_pfn; start_pfn += PAGES_PER_SECTION) {
> + ms = __pfn_to_section(start_pfn);
> +
> + if (unlikely(!valid_section(ms)))
> + continue;
> +
> + if (unlikely(pfn_to_nid(start_pfn) != nid))
> + continue;
> +
> + if (zone&& zone != page_zone(pfn_to_page(start_pfn)))
> + continue;
> +
> + return start_pfn;
> + }
> +
> + return 0;
> +}
> +
> +/* find the biggest valid pfn in the range [start_pfn, end_pfn). */
> +static int find_biggest_section_pfn(int nid, struct zone *zone,
> + unsigned long start_pfn,
> + unsigned long end_pfn)
> +{
> + struct mem_section *ms;
> + unsigned long pfn;
> +
> + /* pfn is the end pfn of a memory section. */
> + pfn = end_pfn - 1;
> + for (; pfn>= start_pfn; pfn -= PAGES_PER_SECTION) {
> + ms = __pfn_to_section(pfn);
> +
> + if (unlikely(!valid_section(ms)))
> + continue;
> +
> + if (unlikely(pfn_to_nid(pfn) != nid))
> + continue;
> +
> + if (zone&& zone != page_zone(pfn_to_page(pfn)))
> + continue;
> +
> + return pfn;
> + }
> +
> + return 0;
> +}
> +
> +static void shrink_zone_span(struct zone *zone, unsigned long start_pfn,
> + unsigned long end_pfn)
> +{
> + unsigned long zone_start_pfn = zone->zone_start_pfn;
> + unsigned long zone_end_pfn = zone->zone_start_pfn + zone->spanned_pages;
> + unsigned long pfn;
> + struct mem_section *ms;
> + int nid = zone_to_nid(zone);
> +
> + zone_span_writelock(zone);
> + if (zone_start_pfn = start_pfn) {
> + /*
> + * If the section is smallest section in the zone, it need
> + * shrink zone->zone_start_pfn and zone->zone_spanned_pages.
> + * In this case, we find second smallest valid mem_section
> + * for shrinking zone.
> + */
> + pfn = find_smallest_section_pfn(nid, zone, end_pfn,
> + zone_end_pfn);
> + if (pfn) {
> + zone->zone_start_pfn = pfn;
> + zone->spanned_pages = zone_end_pfn - pfn;
> + }
> + } else if (zone_end_pfn = end_pfn) {
> + /*
> + * If the section is biggest section in the zone, it need
> + * shrink zone->spanned_pages.
> + * In this case, we find second biggest valid mem_section for
> + * shrinking zone.
> + */
> + pfn = find_biggest_section_pfn(nid, zone, zone_start_pfn,
> + start_pfn);
> + if (pfn)
> + zone->spanned_pages = pfn - zone_start_pfn + 1;
> + }
> +
> + /*
> + * The section is not biggest or smallest mem_section in the zone, it
> + * only creates a hole in the zone. So in this case, we need not
> + * change the zone. But perhaps, the zone has only hole data. Thus
> + * it check the zone has only hole or not.
> + */
> + pfn = zone_start_pfn;
> + for (; pfn< zone_end_pfn; pfn += PAGES_PER_SECTION) {
> + ms = __pfn_to_section(pfn);
> +
> + if (unlikely(!valid_section(ms)))
> + continue;
> +
> + if (page_zone(pfn_to_page(pfn)) != zone)
> + continue;
> +
> + /* If the section is current section, it continues the loop */
> + if (start_pfn = pfn)
> + continue;
> +
> + /* If we find valid section, we have nothing to do */
> + zone_span_writeunlock(zone);
> + return;
> + }
> +
> + /* The zone has no valid section */
> + zone->zone_start_pfn = 0;
> + zone->spanned_pages = 0;
> + zone_span_writeunlock(zone);
> +}
> +
> +static void shrink_pgdat_span(struct pglist_data *pgdat,
> + unsigned long start_pfn, unsigned long end_pfn)
> +{
> + unsigned long pgdat_start_pfn = pgdat->node_start_pfn;
> + unsigned long pgdat_end_pfn > + pgdat->node_start_pfn + pgdat->node_spanned_pages;
> + unsigned long pfn;
> + struct mem_section *ms;
> + int nid = pgdat->node_id;
> +
> + if (pgdat_start_pfn = start_pfn) {
> + /*
> + * If the section is smallest section in the pgdat, it need
> + * shrink pgdat->node_start_pfn and pgdat->node_spanned_pages.
> + * In this case, we find second smallest valid mem_section
> + * for shrinking zone.
> + */
> + pfn = find_smallest_section_pfn(nid, NULL, end_pfn,
> + pgdat_end_pfn);
> + if (pfn) {
> + pgdat->node_start_pfn = pfn;
> + pgdat->node_spanned_pages = pgdat_end_pfn - pfn;
> + }
> + } else if (pgdat_end_pfn = end_pfn) {
> + /*
> + * If the section is biggest section in the pgdat, it need
> + * shrink pgdat->node_spanned_pages.
> + * In this case, we find second biggest valid mem_section for
> + * shrinking zone.
> + */
> + pfn = find_biggest_section_pfn(nid, NULL, pgdat_start_pfn,
> + start_pfn);
> + if (pfn)
> + pgdat->node_spanned_pages = pfn - pgdat_start_pfn + 1;
> + }
> +
> + /*
> + * If the section is not biggest or smallest mem_section in the pgdat,
> + * it only creates a hole in the pgdat. So in this case, we need not
> + * change the pgdat.
> + * But perhaps, the pgdat has only hole data. Thus it check the pgdat
> + * has only hole or not.
> + */
> + pfn = pgdat_start_pfn;
> + for (; pfn< pgdat_end_pfn; pfn += PAGES_PER_SECTION) {
> + ms = __pfn_to_section(pfn);
> +
> + if (unlikely(!valid_section(ms)))
> + continue;
> +
> + if (pfn_to_nid(pfn) != nid)
> + continue;
> +
> + /* If the section is current section, it continues the loop */
> + if (start_pfn = pfn)
> + continue;
> +
> + /* If we find valid section, we have nothing to do */
> + return;
> + }
> +
> + /* The pgdat has no valid section */
> + pgdat->node_start_pfn = 0;
> + pgdat->node_spanned_pages = 0;
> +}
> +
> +static void __remove_zone(struct zone *zone, unsigned long start_pfn)
> +{
> + struct pglist_data *pgdat = zone->zone_pgdat;
> + int nr_pages = PAGES_PER_SECTION;
> + int zone_type;
> + unsigned long flags;
> +
> + zone_type = zone - pgdat->node_zones;
> +
> + pgdat_resize_lock(zone->zone_pgdat,&flags);
> + shrink_zone_span(zone, start_pfn, start_pfn + nr_pages);
> + shrink_pgdat_span(pgdat, start_pfn, start_pfn + nr_pages);
> + pgdat_resize_unlock(zone->zone_pgdat,&flags);
> +}
> +
> static int __remove_section(struct zone *zone, struct mem_section *ms)
> {
> unsigned long flags;
> struct pglist_data *pgdat = zone->zone_pgdat;
> + unsigned long start_pfn;
> + int scn_nr;
> int ret = -EINVAL;
>
> if (!valid_section(ms))
> @@ -314,6 +517,10 @@ static int __remove_section(struct zone *zone, struct mem_section *ms)
> if (ret)
> return ret;
>
> + scn_nr = __section_nr(ms);
> + start_pfn = section_nr_to_pfn(scn_nr);
> + __remove_zone(zone, start_pfn);
> +
> pgdat_resize_lock(pgdat,&flags);
> sparse_remove_one_section(zone, ms);
> pgdat_resize_unlock(pgdat,&flags);
WARNING: multiple messages have this Message-ID (diff)
From: Tang Chen <tangchen@cn.fujitsu.com>
To: Wen Congyang <wency@cn.fujitsu.com>
Cc: linux-s390@vger.kernel.org, linux-ia64@vger.kernel.org,
Len Brown <len.brown@intel.com>,
linux-acpi@vger.kernel.org, linux-sh@vger.kernel.org,
x86@kernel.org, linux-kernel@vger.kernel.org,
cmetcalf@tilera.com, Jianguo Wu <wujianguo@huawei.com>,
linux-mm@kvack.org,
Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>,
paulus@samba.org, Minchan Kim <minchan.kim@gmail.com>,
KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>,
David Rientjes <rientjes@google.com>,
sparclinux@vger.kernel.org, Christoph Lameter <cl@linux.com>,
linuxppc-dev@lists.ozlabs.org,
Andrew Morton <akpm@linux-foundation.org>,
Jiang Liu <liuj97@gmail.com>
Subject: Re: [Patch v4 10/12] memory-hotplug: memory_hotplug: clear zone when removing the memory
Date: Tue, 04 Dec 2012 18:09:37 +0800 [thread overview]
Message-ID: <50BDCBE1.7030001@cn.fujitsu.com> (raw)
In-Reply-To: <1354010422-19648-11-git-send-email-wency@cn.fujitsu.com>
On 11/27/2012 06:00 PM, Wen Congyang wrote:
> From: Yasuaki Ishimatsu<isimatu.yasuaki@jp.fujitsu.com>
>
> When a memory is added, we update zone's and pgdat's start_pfn and
> spanned_pages in the function __add_zone(). So we should revert them
> when the memory is removed.
>
> The patch adds a new function __remove_zone() to do this.
>
> CC: David Rientjes<rientjes@google.com>
> CC: Jiang Liu<liuj97@gmail.com>
> CC: Len Brown<len.brown@intel.com>
> CC: Christoph Lameter<cl@linux.com>
> Cc: Minchan Kim<minchan.kim@gmail.com>
> CC: Andrew Morton<akpm@linux-foundation.org>
> CC: KOSAKI Motohiro<kosaki.motohiro@jp.fujitsu.com>
> Signed-off-by: Yasuaki Ishimatsu<isimatu.yasuaki@jp.fujitsu.com>
> Signed-off-by: Wen Congyang<wency@cn.fujitsu.com>
Reviewed-by: Tang Chen <tangchen@cn.fujitsu.com>
> ---
> mm/memory_hotplug.c | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 207 insertions(+)
>
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> index 7797e91..aa97d56 100644
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -301,10 +301,213 @@ static int __meminit __add_section(int nid, struct zone *zone,
> return register_new_memory(nid, __pfn_to_section(phys_start_pfn));
> }
>
> +/* find the smallest valid pfn in the range [start_pfn, end_pfn) */
> +static int find_smallest_section_pfn(int nid, struct zone *zone,
> + unsigned long start_pfn,
> + unsigned long end_pfn)
> +{
> + struct mem_section *ms;
> +
> + for (; start_pfn< end_pfn; start_pfn += PAGES_PER_SECTION) {
> + ms = __pfn_to_section(start_pfn);
> +
> + if (unlikely(!valid_section(ms)))
> + continue;
> +
> + if (unlikely(pfn_to_nid(start_pfn) != nid))
> + continue;
> +
> + if (zone&& zone != page_zone(pfn_to_page(start_pfn)))
> + continue;
> +
> + return start_pfn;
> + }
> +
> + return 0;
> +}
> +
> +/* find the biggest valid pfn in the range [start_pfn, end_pfn). */
> +static int find_biggest_section_pfn(int nid, struct zone *zone,
> + unsigned long start_pfn,
> + unsigned long end_pfn)
> +{
> + struct mem_section *ms;
> + unsigned long pfn;
> +
> + /* pfn is the end pfn of a memory section. */
> + pfn = end_pfn - 1;
> + for (; pfn>= start_pfn; pfn -= PAGES_PER_SECTION) {
> + ms = __pfn_to_section(pfn);
> +
> + if (unlikely(!valid_section(ms)))
> + continue;
> +
> + if (unlikely(pfn_to_nid(pfn) != nid))
> + continue;
> +
> + if (zone&& zone != page_zone(pfn_to_page(pfn)))
> + continue;
> +
> + return pfn;
> + }
> +
> + return 0;
> +}
> +
> +static void shrink_zone_span(struct zone *zone, unsigned long start_pfn,
> + unsigned long end_pfn)
> +{
> + unsigned long zone_start_pfn = zone->zone_start_pfn;
> + unsigned long zone_end_pfn = zone->zone_start_pfn + zone->spanned_pages;
> + unsigned long pfn;
> + struct mem_section *ms;
> + int nid = zone_to_nid(zone);
> +
> + zone_span_writelock(zone);
> + if (zone_start_pfn == start_pfn) {
> + /*
> + * If the section is smallest section in the zone, it need
> + * shrink zone->zone_start_pfn and zone->zone_spanned_pages.
> + * In this case, we find second smallest valid mem_section
> + * for shrinking zone.
> + */
> + pfn = find_smallest_section_pfn(nid, zone, end_pfn,
> + zone_end_pfn);
> + if (pfn) {
> + zone->zone_start_pfn = pfn;
> + zone->spanned_pages = zone_end_pfn - pfn;
> + }
> + } else if (zone_end_pfn == end_pfn) {
> + /*
> + * If the section is biggest section in the zone, it need
> + * shrink zone->spanned_pages.
> + * In this case, we find second biggest valid mem_section for
> + * shrinking zone.
> + */
> + pfn = find_biggest_section_pfn(nid, zone, zone_start_pfn,
> + start_pfn);
> + if (pfn)
> + zone->spanned_pages = pfn - zone_start_pfn + 1;
> + }
> +
> + /*
> + * The section is not biggest or smallest mem_section in the zone, it
> + * only creates a hole in the zone. So in this case, we need not
> + * change the zone. But perhaps, the zone has only hole data. Thus
> + * it check the zone has only hole or not.
> + */
> + pfn = zone_start_pfn;
> + for (; pfn< zone_end_pfn; pfn += PAGES_PER_SECTION) {
> + ms = __pfn_to_section(pfn);
> +
> + if (unlikely(!valid_section(ms)))
> + continue;
> +
> + if (page_zone(pfn_to_page(pfn)) != zone)
> + continue;
> +
> + /* If the section is current section, it continues the loop */
> + if (start_pfn == pfn)
> + continue;
> +
> + /* If we find valid section, we have nothing to do */
> + zone_span_writeunlock(zone);
> + return;
> + }
> +
> + /* The zone has no valid section */
> + zone->zone_start_pfn = 0;
> + zone->spanned_pages = 0;
> + zone_span_writeunlock(zone);
> +}
> +
> +static void shrink_pgdat_span(struct pglist_data *pgdat,
> + unsigned long start_pfn, unsigned long end_pfn)
> +{
> + unsigned long pgdat_start_pfn = pgdat->node_start_pfn;
> + unsigned long pgdat_end_pfn =
> + pgdat->node_start_pfn + pgdat->node_spanned_pages;
> + unsigned long pfn;
> + struct mem_section *ms;
> + int nid = pgdat->node_id;
> +
> + if (pgdat_start_pfn == start_pfn) {
> + /*
> + * If the section is smallest section in the pgdat, it need
> + * shrink pgdat->node_start_pfn and pgdat->node_spanned_pages.
> + * In this case, we find second smallest valid mem_section
> + * for shrinking zone.
> + */
> + pfn = find_smallest_section_pfn(nid, NULL, end_pfn,
> + pgdat_end_pfn);
> + if (pfn) {
> + pgdat->node_start_pfn = pfn;
> + pgdat->node_spanned_pages = pgdat_end_pfn - pfn;
> + }
> + } else if (pgdat_end_pfn == end_pfn) {
> + /*
> + * If the section is biggest section in the pgdat, it need
> + * shrink pgdat->node_spanned_pages.
> + * In this case, we find second biggest valid mem_section for
> + * shrinking zone.
> + */
> + pfn = find_biggest_section_pfn(nid, NULL, pgdat_start_pfn,
> + start_pfn);
> + if (pfn)
> + pgdat->node_spanned_pages = pfn - pgdat_start_pfn + 1;
> + }
> +
> + /*
> + * If the section is not biggest or smallest mem_section in the pgdat,
> + * it only creates a hole in the pgdat. So in this case, we need not
> + * change the pgdat.
> + * But perhaps, the pgdat has only hole data. Thus it check the pgdat
> + * has only hole or not.
> + */
> + pfn = pgdat_start_pfn;
> + for (; pfn< pgdat_end_pfn; pfn += PAGES_PER_SECTION) {
> + ms = __pfn_to_section(pfn);
> +
> + if (unlikely(!valid_section(ms)))
> + continue;
> +
> + if (pfn_to_nid(pfn) != nid)
> + continue;
> +
> + /* If the section is current section, it continues the loop */
> + if (start_pfn == pfn)
> + continue;
> +
> + /* If we find valid section, we have nothing to do */
> + return;
> + }
> +
> + /* The pgdat has no valid section */
> + pgdat->node_start_pfn = 0;
> + pgdat->node_spanned_pages = 0;
> +}
> +
> +static void __remove_zone(struct zone *zone, unsigned long start_pfn)
> +{
> + struct pglist_data *pgdat = zone->zone_pgdat;
> + int nr_pages = PAGES_PER_SECTION;
> + int zone_type;
> + unsigned long flags;
> +
> + zone_type = zone - pgdat->node_zones;
> +
> + pgdat_resize_lock(zone->zone_pgdat,&flags);
> + shrink_zone_span(zone, start_pfn, start_pfn + nr_pages);
> + shrink_pgdat_span(pgdat, start_pfn, start_pfn + nr_pages);
> + pgdat_resize_unlock(zone->zone_pgdat,&flags);
> +}
> +
> static int __remove_section(struct zone *zone, struct mem_section *ms)
> {
> unsigned long flags;
> struct pglist_data *pgdat = zone->zone_pgdat;
> + unsigned long start_pfn;
> + int scn_nr;
> int ret = -EINVAL;
>
> if (!valid_section(ms))
> @@ -314,6 +517,10 @@ static int __remove_section(struct zone *zone, struct mem_section *ms)
> if (ret)
> return ret;
>
> + scn_nr = __section_nr(ms);
> + start_pfn = section_nr_to_pfn(scn_nr);
> + __remove_zone(zone, start_pfn);
> +
> pgdat_resize_lock(pgdat,&flags);
> sparse_remove_one_section(zone, ms);
> pgdat_resize_unlock(pgdat,&flags);
WARNING: multiple messages have this Message-ID (diff)
From: Tang Chen <tangchen@cn.fujitsu.com>
To: Wen Congyang <wency@cn.fujitsu.com>
Cc: 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, David Rientjes <rientjes@google.com>,
Jiang Liu <liuj97@gmail.com>, Len Brown <len.brown@intel.com>,
benh@kernel.crashing.org, paulus@samba.org,
Christoph Lameter <cl@linux.com>,
Minchan Kim <minchan.kim@gmail.com>,
Andrew Morton <akpm@linux-foundation.org>,
KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>,
Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>,
Jianguo Wu <wujianguo@huawei.com>
Subject: Re: [Patch v4 10/12] memory-hotplug: memory_hotplug: clear zone when removing the memory
Date: Tue, 04 Dec 2012 18:09:37 +0800 [thread overview]
Message-ID: <50BDCBE1.7030001@cn.fujitsu.com> (raw)
In-Reply-To: <1354010422-19648-11-git-send-email-wency@cn.fujitsu.com>
On 11/27/2012 06:00 PM, Wen Congyang wrote:
> From: Yasuaki Ishimatsu<isimatu.yasuaki@jp.fujitsu.com>
>
> When a memory is added, we update zone's and pgdat's start_pfn and
> spanned_pages in the function __add_zone(). So we should revert them
> when the memory is removed.
>
> The patch adds a new function __remove_zone() to do this.
>
> CC: David Rientjes<rientjes@google.com>
> CC: Jiang Liu<liuj97@gmail.com>
> CC: Len Brown<len.brown@intel.com>
> CC: Christoph Lameter<cl@linux.com>
> Cc: Minchan Kim<minchan.kim@gmail.com>
> CC: Andrew Morton<akpm@linux-foundation.org>
> CC: KOSAKI Motohiro<kosaki.motohiro@jp.fujitsu.com>
> Signed-off-by: Yasuaki Ishimatsu<isimatu.yasuaki@jp.fujitsu.com>
> Signed-off-by: Wen Congyang<wency@cn.fujitsu.com>
Reviewed-by: Tang Chen <tangchen@cn.fujitsu.com>
> ---
> mm/memory_hotplug.c | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 207 insertions(+)
>
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> index 7797e91..aa97d56 100644
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -301,10 +301,213 @@ static int __meminit __add_section(int nid, struct zone *zone,
> return register_new_memory(nid, __pfn_to_section(phys_start_pfn));
> }
>
> +/* find the smallest valid pfn in the range [start_pfn, end_pfn) */
> +static int find_smallest_section_pfn(int nid, struct zone *zone,
> + unsigned long start_pfn,
> + unsigned long end_pfn)
> +{
> + struct mem_section *ms;
> +
> + for (; start_pfn< end_pfn; start_pfn += PAGES_PER_SECTION) {
> + ms = __pfn_to_section(start_pfn);
> +
> + if (unlikely(!valid_section(ms)))
> + continue;
> +
> + if (unlikely(pfn_to_nid(start_pfn) != nid))
> + continue;
> +
> + if (zone&& zone != page_zone(pfn_to_page(start_pfn)))
> + continue;
> +
> + return start_pfn;
> + }
> +
> + return 0;
> +}
> +
> +/* find the biggest valid pfn in the range [start_pfn, end_pfn). */
> +static int find_biggest_section_pfn(int nid, struct zone *zone,
> + unsigned long start_pfn,
> + unsigned long end_pfn)
> +{
> + struct mem_section *ms;
> + unsigned long pfn;
> +
> + /* pfn is the end pfn of a memory section. */
> + pfn = end_pfn - 1;
> + for (; pfn>= start_pfn; pfn -= PAGES_PER_SECTION) {
> + ms = __pfn_to_section(pfn);
> +
> + if (unlikely(!valid_section(ms)))
> + continue;
> +
> + if (unlikely(pfn_to_nid(pfn) != nid))
> + continue;
> +
> + if (zone&& zone != page_zone(pfn_to_page(pfn)))
> + continue;
> +
> + return pfn;
> + }
> +
> + return 0;
> +}
> +
> +static void shrink_zone_span(struct zone *zone, unsigned long start_pfn,
> + unsigned long end_pfn)
> +{
> + unsigned long zone_start_pfn = zone->zone_start_pfn;
> + unsigned long zone_end_pfn = zone->zone_start_pfn + zone->spanned_pages;
> + unsigned long pfn;
> + struct mem_section *ms;
> + int nid = zone_to_nid(zone);
> +
> + zone_span_writelock(zone);
> + if (zone_start_pfn == start_pfn) {
> + /*
> + * If the section is smallest section in the zone, it need
> + * shrink zone->zone_start_pfn and zone->zone_spanned_pages.
> + * In this case, we find second smallest valid mem_section
> + * for shrinking zone.
> + */
> + pfn = find_smallest_section_pfn(nid, zone, end_pfn,
> + zone_end_pfn);
> + if (pfn) {
> + zone->zone_start_pfn = pfn;
> + zone->spanned_pages = zone_end_pfn - pfn;
> + }
> + } else if (zone_end_pfn == end_pfn) {
> + /*
> + * If the section is biggest section in the zone, it need
> + * shrink zone->spanned_pages.
> + * In this case, we find second biggest valid mem_section for
> + * shrinking zone.
> + */
> + pfn = find_biggest_section_pfn(nid, zone, zone_start_pfn,
> + start_pfn);
> + if (pfn)
> + zone->spanned_pages = pfn - zone_start_pfn + 1;
> + }
> +
> + /*
> + * The section is not biggest or smallest mem_section in the zone, it
> + * only creates a hole in the zone. So in this case, we need not
> + * change the zone. But perhaps, the zone has only hole data. Thus
> + * it check the zone has only hole or not.
> + */
> + pfn = zone_start_pfn;
> + for (; pfn< zone_end_pfn; pfn += PAGES_PER_SECTION) {
> + ms = __pfn_to_section(pfn);
> +
> + if (unlikely(!valid_section(ms)))
> + continue;
> +
> + if (page_zone(pfn_to_page(pfn)) != zone)
> + continue;
> +
> + /* If the section is current section, it continues the loop */
> + if (start_pfn == pfn)
> + continue;
> +
> + /* If we find valid section, we have nothing to do */
> + zone_span_writeunlock(zone);
> + return;
> + }
> +
> + /* The zone has no valid section */
> + zone->zone_start_pfn = 0;
> + zone->spanned_pages = 0;
> + zone_span_writeunlock(zone);
> +}
> +
> +static void shrink_pgdat_span(struct pglist_data *pgdat,
> + unsigned long start_pfn, unsigned long end_pfn)
> +{
> + unsigned long pgdat_start_pfn = pgdat->node_start_pfn;
> + unsigned long pgdat_end_pfn =
> + pgdat->node_start_pfn + pgdat->node_spanned_pages;
> + unsigned long pfn;
> + struct mem_section *ms;
> + int nid = pgdat->node_id;
> +
> + if (pgdat_start_pfn == start_pfn) {
> + /*
> + * If the section is smallest section in the pgdat, it need
> + * shrink pgdat->node_start_pfn and pgdat->node_spanned_pages.
> + * In this case, we find second smallest valid mem_section
> + * for shrinking zone.
> + */
> + pfn = find_smallest_section_pfn(nid, NULL, end_pfn,
> + pgdat_end_pfn);
> + if (pfn) {
> + pgdat->node_start_pfn = pfn;
> + pgdat->node_spanned_pages = pgdat_end_pfn - pfn;
> + }
> + } else if (pgdat_end_pfn == end_pfn) {
> + /*
> + * If the section is biggest section in the pgdat, it need
> + * shrink pgdat->node_spanned_pages.
> + * In this case, we find second biggest valid mem_section for
> + * shrinking zone.
> + */
> + pfn = find_biggest_section_pfn(nid, NULL, pgdat_start_pfn,
> + start_pfn);
> + if (pfn)
> + pgdat->node_spanned_pages = pfn - pgdat_start_pfn + 1;
> + }
> +
> + /*
> + * If the section is not biggest or smallest mem_section in the pgdat,
> + * it only creates a hole in the pgdat. So in this case, we need not
> + * change the pgdat.
> + * But perhaps, the pgdat has only hole data. Thus it check the pgdat
> + * has only hole or not.
> + */
> + pfn = pgdat_start_pfn;
> + for (; pfn< pgdat_end_pfn; pfn += PAGES_PER_SECTION) {
> + ms = __pfn_to_section(pfn);
> +
> + if (unlikely(!valid_section(ms)))
> + continue;
> +
> + if (pfn_to_nid(pfn) != nid)
> + continue;
> +
> + /* If the section is current section, it continues the loop */
> + if (start_pfn == pfn)
> + continue;
> +
> + /* If we find valid section, we have nothing to do */
> + return;
> + }
> +
> + /* The pgdat has no valid section */
> + pgdat->node_start_pfn = 0;
> + pgdat->node_spanned_pages = 0;
> +}
> +
> +static void __remove_zone(struct zone *zone, unsigned long start_pfn)
> +{
> + struct pglist_data *pgdat = zone->zone_pgdat;
> + int nr_pages = PAGES_PER_SECTION;
> + int zone_type;
> + unsigned long flags;
> +
> + zone_type = zone - pgdat->node_zones;
> +
> + pgdat_resize_lock(zone->zone_pgdat,&flags);
> + shrink_zone_span(zone, start_pfn, start_pfn + nr_pages);
> + shrink_pgdat_span(pgdat, start_pfn, start_pfn + nr_pages);
> + pgdat_resize_unlock(zone->zone_pgdat,&flags);
> +}
> +
> static int __remove_section(struct zone *zone, struct mem_section *ms)
> {
> unsigned long flags;
> struct pglist_data *pgdat = zone->zone_pgdat;
> + unsigned long start_pfn;
> + int scn_nr;
> int ret = -EINVAL;
>
> if (!valid_section(ms))
> @@ -314,6 +517,10 @@ static int __remove_section(struct zone *zone, struct mem_section *ms)
> if (ret)
> return ret;
>
> + scn_nr = __section_nr(ms);
> + start_pfn = section_nr_to_pfn(scn_nr);
> + __remove_zone(zone, start_pfn);
> +
> pgdat_resize_lock(pgdat,&flags);
> sparse_remove_one_section(zone, ms);
> pgdat_resize_unlock(pgdat,&flags);
next prev parent reply other threads:[~2012-12-04 10:09 UTC|newest]
Thread overview: 176+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-11-27 10:00 [Patch v4 00/12] memory-hotplug: hot-remove physical memory Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 9:58 ` [Patch v4 01/12] memory-hotplug: try to offline the memory twice to avoid dependence Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-12-04 9:17 ` Tang Chen
2012-12-04 9:17 ` Tang Chen
2012-12-04 9:17 ` Tang Chen
2012-12-04 9:17 ` Tang Chen
2012-11-27 9:58 ` [Patch v4 05/12] memory-hotplug: introduce new function arch_remove_memory() for removing page table Wen Congyang
2012-11-27 10:00 ` [Patch v4 05/12] memory-hotplug: introduce new function arch_remove_memory() for removing page table depends on architecture Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` [Patch v4 05/12] memory-hotplug: introduce new function arch_remove_memory() for removing page table Wen Congyang
2012-11-27 10:00 ` [Patch v4 05/12] memory-hotplug: introduce new function arch_remove_memory() for removing page table depends on architecture Wen Congyang
2012-11-27 9:59 ` [Patch v4 05/12] memory-hotplug: introduce new function arch_remove_memory() for removing page table Wen Congyang
2012-12-04 9:30 ` [Patch v4 05/12] memory-hotplug: introduce new function arch_remove_memory() for removing page table depends on architecture Tang Chen
2012-12-04 9:30 ` Tang Chen
2012-12-04 9:30 ` Tang Chen
2012-12-04 9:30 ` [Patch v4 05/12] memory-hotplug: introduce new function arch_remove_memory() for removing page t Tang Chen
2012-11-27 9:59 ` [Patch v4 12/12] memory-hotplug: free node_data when a node is offlined Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 9:59 ` Wen Congyang
2012-11-27 9:59 ` Wen Congyang
2012-12-04 10:10 ` Tang Chen
2012-12-04 10:10 ` Tang Chen
2012-12-04 10:10 ` Tang Chen
2012-12-04 10:10 ` Tang Chen
2012-11-27 9:59 ` [Patch v4 08/12] memory-hotplug: remove memmap of sparse-vmemmap Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-28 9:40 ` Jianguo Wu
2012-11-28 9:40 ` Jianguo Wu
2012-11-28 9:40 ` Jianguo Wu
2012-11-28 9:40 ` Jianguo Wu
2012-11-28 9:40 ` Jianguo Wu
2012-11-30 1:45 ` Wen Congyang
2012-11-30 1:45 ` Wen Congyang
2012-11-30 1:45 ` Wen Congyang
2012-11-30 1:45 ` Wen Congyang
2012-11-30 2:47 ` Jianguo Wu
2012-11-30 2:47 ` Jianguo Wu
2012-11-30 2:47 ` Jianguo Wu
2012-11-30 2:47 ` Jianguo Wu
2012-11-30 2:55 ` Yasuaki Ishimatsu
2012-11-30 2:55 ` Yasuaki Ishimatsu
2012-11-30 2:55 ` Yasuaki Ishimatsu
2012-11-30 2:55 ` Yasuaki Ishimatsu
2012-11-30 2:55 ` Yasuaki Ishimatsu
2012-12-03 2:23 ` Jianguo Wu
2012-12-03 2:23 ` Jianguo Wu
2012-12-03 2:23 ` Jianguo Wu
2012-12-03 2:23 ` Jianguo Wu
2012-12-03 2:23 ` Jianguo Wu
2012-12-04 9:13 ` Tang Chen
2012-12-04 9:13 ` Tang Chen
2012-12-04 9:13 ` Tang Chen
2012-12-04 9:13 ` Tang Chen
2012-12-04 12:20 ` Jianguo Wu
2012-12-04 12:20 ` Jianguo Wu
2012-12-04 12:20 ` Jianguo Wu
2012-12-04 12:20 ` Jianguo Wu
2012-12-04 12:20 ` Jianguo Wu
2012-12-05 2:07 ` Tang Chen
2012-12-05 2:07 ` Tang Chen
2012-12-05 2:07 ` Tang Chen
2012-12-05 2:07 ` Tang Chen
2012-12-05 3:23 ` Jianguo Wu
2012-12-05 3:23 ` Jianguo Wu
2012-12-05 3:23 ` Jianguo Wu
2012-12-05 3:23 ` Jianguo Wu
2012-12-05 3:23 ` Jianguo Wu
2012-12-07 1:42 ` Tang Chen
2012-12-07 1:42 ` Tang Chen
2012-12-07 1:42 ` Tang Chen
2012-12-07 1:42 ` Tang Chen
2012-12-07 2:20 ` Jianguo Wu
2012-12-07 2:20 ` Jianguo Wu
2012-12-07 2:20 ` Jianguo Wu
2012-12-07 2:20 ` Jianguo Wu
2012-12-07 2:20 ` Jianguo Wu
2012-12-04 9:47 ` Tang Chen
2012-12-04 9:47 ` Tang Chen
2012-12-04 9:47 ` Tang Chen
2012-12-04 9:47 ` Tang Chen
2012-11-27 9:59 ` [Patch v4 09/12] memory-hotplug: remove page table of x86_64 architecture Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 9:59 ` Wen Congyang
2012-12-07 6:43 ` Tang Chen
2012-12-07 6:43 ` Tang Chen
2012-12-07 6:43 ` Tang Chen
2012-12-07 6:43 ` Tang Chen
2012-12-07 7:06 ` Jianguo Wu
2012-12-07 7:06 ` Jianguo Wu
2012-12-07 7:06 ` Jianguo Wu
2012-12-07 7:06 ` Jianguo Wu
2012-12-07 7:06 ` Jianguo Wu
2012-11-27 10:00 ` [Patch v4 02/12] memory-hotplug: check whether all memory blocks are offlined or not when removing memory Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` [Patch v4 02/12] memory-hotplug: check whether all memory blocks are offlined or not when removing m Wen Congyang
2012-12-04 9:22 ` [Patch v4 02/12] memory-hotplug: check whether all memory blocks are offlined or not when removing memory Tang Chen
2012-12-04 9:22 ` Tang Chen
2012-12-04 9:22 ` Tang Chen
2012-12-04 9:22 ` [Patch v4 02/12] memory-hotplug: check whether all memory blocks are offlined or not when removi Tang Chen
2012-11-27 10:00 ` [Patch v4 03/12] memory-hotplug: remove redundant codes Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-12-04 9:22 ` Tang Chen
2012-12-04 9:22 ` Tang Chen
2012-12-04 9:22 ` Tang Chen
2012-12-04 9:22 ` Tang Chen
2012-12-04 10:31 ` Tang Chen
2012-12-04 10:31 ` Tang Chen
2012-12-04 10:31 ` Tang Chen
2012-12-04 10:31 ` Tang Chen
2012-11-27 10:00 ` [Patch v4 04/12] memory-hotplug: remove /sys/firmware/memmap/X sysfs Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` [Patch v4 06/12] memory-hotplug: unregister memory section on SPARSEMEM_VMEMMAP Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-12-04 9:34 ` Tang Chen
2012-12-04 9:34 ` Tang Chen
2012-12-04 9:34 ` Tang Chen
2012-12-04 9:34 ` Tang Chen
2012-11-27 10:00 ` [Patch v4 07/12] memory-hotplug: implement register_page_bootmem_info_section of sparse-vmemmap Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` [Patch v4 10/12] memory-hotplug: memory_hotplug: clear zone when removing the memory Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-12-04 10:09 ` Tang Chen [this message]
2012-12-04 10:09 ` Tang Chen
2012-12-04 10:09 ` Tang Chen
2012-12-04 10:09 ` Tang Chen
2012-11-27 10:00 ` [Patch v4 11/12] memory-hotplug: remove sysfs file of node Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-11-27 10:00 ` Wen Congyang
2012-12-04 10:10 ` Tang Chen
2012-12-04 10:10 ` Tang Chen
2012-12-04 10:10 ` Tang Chen
2012-12-04 10:10 ` Tang Chen
2012-11-27 19:27 ` [Patch v4 00/12] memory-hotplug: hot-remove physical memory Andrew Morton
2012-11-27 19:27 ` Andrew Morton
2012-11-27 19:27 ` Andrew Morton
2012-11-27 19:27 ` Andrew Morton
2012-11-27 19:38 ` Rafael J. Wysocki
2012-11-27 19:38 ` Rafael J. Wysocki
2012-11-27 19:38 ` Rafael J. Wysocki
2012-11-27 19:38 ` Rafael J. Wysocki
2012-11-28 0:43 ` Yasuaki Ishimatsu
2012-11-28 0:43 ` Yasuaki Ishimatsu
2012-11-28 0:43 ` Yasuaki Ishimatsu
2012-11-28 0:43 ` Yasuaki Ishimatsu
2012-11-28 0:43 ` Yasuaki Ishimatsu
2012-11-30 6:37 ` Tang Chen
2012-11-30 6:37 ` Tang Chen
2012-11-30 6:37 ` Tang Chen
2012-11-30 6:37 ` Tang Chen
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=50BDCBE1.7030001@cn.fujitsu.com \
--to=tangchen@cn.fujitsu.com \
--cc=akpm@linux-foundation.org \
--cc=benh@kernel.crashing.org \
--cc=cl@linux.com \
--cc=cmetcalf@tilera.com \
--cc=isimatu.yasuaki@jp.fujitsu.com \
--cc=kosaki.motohiro@jp.fujitsu.com \
--cc=len.brown@intel.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=minchan.kim@gmail.com \
--cc=paulus@samba.org \
--cc=rientjes@google.com \
--cc=sparclinux@vger.kernel.org \
--cc=wency@cn.fujitsu.com \
--cc=wujianguo@huawei.com \
--cc=x86@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.