2013-05-23 08:43:05

by Wanpeng Li

[permalink] [raw]
Subject: [PATCH v2 1/4] mm/memory-hotplug: fix lowmem count overflow when offline pages

Changelog:
v1 -> v2:
* show number of HighTotal before hotremove
* remove CONFIG_HIGHMEM
* cc stable kernels
* add Michal reviewed-by

Logic memory-remove code fails to correctly account the Total High Memory
when a memory block which contains High Memory is offlined as shown in the
example below. The following patch fixes it.

Stable for 2.6.24+.

Before logic memory remove:

MemTotal: 7603740 kB
MemFree: 6329612 kB
Buffers: 94352 kB
Cached: 872008 kB
SwapCached: 0 kB
Active: 626932 kB
Inactive: 519216 kB
Active(anon): 180776 kB
Inactive(anon): 222944 kB
Active(file): 446156 kB
Inactive(file): 296272 kB
Unevictable: 0 kB
Mlocked: 0 kB
HighTotal: 7294672 kB
HighFree: 5704696 kB
LowTotal: 309068 kB
LowFree: 624916 kB

After logic memory remove:

MemTotal: 7079452 kB
MemFree: 5805976 kB
Buffers: 94372 kB
Cached: 872000 kB
SwapCached: 0 kB
Active: 626936 kB
Inactive: 519236 kB
Active(anon): 180780 kB
Inactive(anon): 222944 kB
Active(file): 446156 kB
Inactive(file): 296292 kB
Unevictable: 0 kB
Mlocked: 0 kB
HighTotal: 7294672 kB
HighFree: 5181024 kB
LowTotal: 4294752076 kB
LowFree: 624952 kB

Reviewed-by: Michal Hocko <[email protected]>
Signed-off-by: Wanpeng Li <[email protected]>
---
mm/page_alloc.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 98cbdf6..23b921f 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -6140,6 +6140,8 @@ __offline_isolated_pages(unsigned long start_pfn, unsigned long end_pfn)
list_del(&page->lru);
rmv_page_order(page);
zone->free_area[order].nr_free--;
+ if (PageHighMem(page))
+ totalhigh_pages -= 1 << order;
for (i = 0; i < (1 << order); i++)
SetPageReserved((page+i));
pfn += (1 << order);
--
1.8.1.2


2013-05-23 08:43:12

by Wanpeng Li

[permalink] [raw]
Subject: [PATCH v2 3/4] mm/hugetlb: remove hugetlb_prefault

Changelog:
v1 -> v2:
* add Michal reviewed-by

hugetlb_prefault are not used any more, this patch remove it.

Reviewed-by: Michal Hocko <[email protected]>
Signed-off-by: Wanpeng Li <[email protected]>
---
include/linux/hugetlb.h | 2 --
1 file changed, 2 deletions(-)

diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 6b4890f..a811149 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -55,7 +55,6 @@ void __unmap_hugepage_range_final(struct mmu_gather *tlb,
void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
unsigned long start, unsigned long end,
struct page *ref_page);
-int hugetlb_prefault(struct address_space *, struct vm_area_struct *);
void hugetlb_report_meminfo(struct seq_file *);
int hugetlb_report_node_meminfo(int, char *);
void hugetlb_show_meminfo(void);
@@ -110,7 +109,6 @@ static inline unsigned long hugetlb_total_pages(void)
#define follow_hugetlb_page(m,v,p,vs,a,b,i,w) ({ BUG(); 0; })
#define follow_huge_addr(mm, addr, write) ERR_PTR(-EINVAL)
#define copy_hugetlb_page_range(src, dst, vma) ({ BUG(); 0; })
-#define hugetlb_prefault(mapping, vma) ({ BUG(); 0; })
static inline void hugetlb_report_meminfo(struct seq_file *m)
{
}
--
1.8.1.2

2013-05-23 08:43:16

by Wanpeng Li

[permalink] [raw]
Subject: [PATCH v2 2/4] mm/pageblock: remove get/set_pageblock_flags

Changelog:
v1 -> v2:
* add Michal reviewed-by

get_pageblock_flags and set_pageblock_flags are not used any
more, this patch remove them.

Reviewed-by: Michal Hocko <[email protected]>
Signed-off-by: Wanpeng Li <[email protected]>
---
include/linux/pageblock-flags.h | 6 ------
1 file changed, 6 deletions(-)

diff --git a/include/linux/pageblock-flags.h b/include/linux/pageblock-flags.h
index be655e4..2ee8cd2 100644
--- a/include/linux/pageblock-flags.h
+++ b/include/linux/pageblock-flags.h
@@ -80,10 +80,4 @@ void set_pageblock_flags_group(struct page *page, unsigned long flags,
PB_migrate_skip)
#endif /* CONFIG_COMPACTION */

-#define get_pageblock_flags(page) \
- get_pageblock_flags_group(page, 0, PB_migrate_end)
-#define set_pageblock_flags(page, flags) \
- set_pageblock_flags_group(page, flags, \
- 0, PB_migrate_end)
-
#endif /* PAGEBLOCK_FLAGS_H */
--
1.8.1.2

2013-05-23 08:43:15

by Wanpeng Li

[permalink] [raw]
Subject: [PATCH v2 4/4] mm/hugetlb: use already exist interface huge_page_shift

Changelog:
v1 -> v2:
* update alloc_bootmem_huge_page in powerpc
* add Michal reviewed-by

Use already exist interface huge_page_shift instead of h->order + PAGE_SHIFT.

Reviewed-by: Michal Hocko <[email protected]>
Signed-off-by: Wanpeng Li <[email protected]>
---
arch/powerpc/mm/hugetlbpage.c | 2 +-
mm/hugetlb.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 237c8e5..cafec93 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -357,7 +357,7 @@ void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages)
int alloc_bootmem_huge_page(struct hstate *hstate)
{
struct huge_bootmem_page *m;
- int idx = shift_to_mmu_psize(hstate->order + PAGE_SHIFT);
+ int idx = shift_to_mmu_psize(huge_page_shift(hstate));
int nr_gpages = gpage_freearray[idx].nr_gpages;

if (nr_gpages == 0)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index f8feeec..b6ff0ee 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -319,7 +319,7 @@ unsigned long vma_kernel_pagesize(struct vm_area_struct *vma)

hstate = hstate_vma(vma);

- return 1UL << (hstate->order + PAGE_SHIFT);
+ return 1UL << huge_page_shift(hstate);
}
EXPORT_SYMBOL_GPL(vma_kernel_pagesize);

--
1.8.1.2

2013-05-26 01:16:29

by KOSAKI Motohiro

[permalink] [raw]
Subject: Re: [PATCH v2 1/4] mm/memory-hotplug: fix lowmem count overflow when offline pages

> ---
> mm/page_alloc.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index 98cbdf6..23b921f 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -6140,6 +6140,8 @@ __offline_isolated_pages(unsigned long start_pfn, unsigned long end_pfn)
> list_del(&page->lru);
> rmv_page_order(page);
> zone->free_area[order].nr_free--;
> + if (PageHighMem(page))
> + totalhigh_pages -= 1 << order;
> for (i = 0; i < (1 << order); i++)
> SetPageReserved((page+i));
> pfn += (1 << order);

memory hotplug don't support 32bit since it was born, at least, when the system has highmem.
Why can't we disable memory hotremove when 32bit at compile time?

2013-05-26 01:44:06

by KOSAKI Motohiro

[permalink] [raw]
Subject: Re: [PATCH v2 1/4] mm/memory-hotplug: fix lowmem count overflow when offline pages

(5/25/13 9:23 PM), Wanpeng Li wrote:
> Hi KOSAKI,
> On Sat, May 25, 2013 at 09:16:24PM -0400, KOSAKI Motohiro wrote:
>>> ---
>>> mm/page_alloc.c | 2 ++
>>> 1 file changed, 2 insertions(+)
>>>
>>> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
>>> index 98cbdf6..23b921f 100644
>>> --- a/mm/page_alloc.c
>>> +++ b/mm/page_alloc.c
>>> @@ -6140,6 +6140,8 @@ __offline_isolated_pages(unsigned long start_pfn, unsigned long end_pfn)
>>> list_del(&page->lru);
>>> rmv_page_order(page);
>>> zone->free_area[order].nr_free--;
>>> + if (PageHighMem(page))
>>> + totalhigh_pages -= 1 << order;
>>> for (i = 0; i < (1 << order); i++)
>>> SetPageReserved((page+i));
>>> pfn += (1 << order);
>>
>> memory hotplug don't support 32bit since it was born, at least, when the system has highmem.
>> Why can't we disable memory hotremove when 32bit at compile time?
>
> Here is logic memory remove instead of ACPI based memory remove. ;-)

I know.

2013-05-26 14:30:04

by Jiang Liu

[permalink] [raw]
Subject: Re: [PATCH v2 1/4] mm/memory-hotplug: fix lowmem count overflow when offline pages

On 05/26/2013 09:16 AM, KOSAKI Motohiro wrote:
>> ---
>> mm/page_alloc.c | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
>> index 98cbdf6..23b921f 100644
>> --- a/mm/page_alloc.c
>> +++ b/mm/page_alloc.c
>> @@ -6140,6 +6140,8 @@ __offline_isolated_pages(unsigned long start_pfn, unsigned long end_pfn)
>> list_del(&page->lru);
>> rmv_page_order(page);
>> zone->free_area[order].nr_free--;
>> + if (PageHighMem(page))
>> + totalhigh_pages -= 1 << order;
>> for (i = 0; i < (1 << order); i++)
>> SetPageReserved((page+i));
>> pfn += (1 << order);
>
> memory hotplug don't support 32bit since it was born, at least, when the system has highmem.
> Why can't we disable memory hotremove when 32bit at compile time?
Hi KOSAKI,
Could you please help to give more information on the background
about why 32bit platforms with highmem can't support memory hot-removal?
We are trying to enable memory hot-removal on some 32bit platforms with
highmem, really appreciate your help here!
Thanks!
Gerry

>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>

2013-05-26 15:00:09

by KOSAKI Motohiro

[permalink] [raw]
Subject: Re: [PATCH v2 1/4] mm/memory-hotplug: fix lowmem count overflow when offline pages

> Hi KOSAKI,
> Could you please help to give more information on the background
> about why 32bit platforms with highmem can't support memory hot-removal?

It doesn't impossible. Just nobody did. I was playing these code as a
maintainer a while
and I saw all of patches doesn't handle highmem correctly. But I
didn't refuse because
I know it's not a regression.

> We are trying to enable memory hot-removal on some 32bit platforms with
> highmem, really appreciate your help here!

But, if you guys have a strong motivation, it's a very good news. I
have no objection not to mark it broken and accept your contributions.