2014-12-05 08:57:46

by Wang, Yalin

[permalink] [raw]
Subject: [RFC] mm:add KPF_ZERO_PAGE flag for /proc/kpageflags

This patch add KPF_ZERO_PAGE flag for zero_page,
so that userspace process can notice zero_page from
/proc/kpageflags, and then do memory analysis more accurately.

Signed-off-by: Yalin Wang <[email protected]>
---
fs/proc/page.c | 3 +++
include/uapi/linux/kernel-page-flags.h | 1 +
2 files changed, 4 insertions(+)

diff --git a/fs/proc/page.c b/fs/proc/page.c
index 1e3187d..120dbf7 100644
--- a/fs/proc/page.c
+++ b/fs/proc/page.c
@@ -136,6 +136,9 @@ u64 stable_page_flags(struct page *page)
if (PageBalloon(page))
u |= 1 << KPF_BALLOON;

+ if (is_zero_pfn(page_to_pfn(page)))
+ u |= 1 << KPF_ZERO_PAGE;
+
u |= kpf_copy_bit(k, KPF_LOCKED, PG_locked);

u |= kpf_copy_bit(k, KPF_SLAB, PG_slab);
diff --git a/include/uapi/linux/kernel-page-flags.h b/include/uapi/linux/kernel-page-flags.h
index 2f96d23..a6c4962 100644
--- a/include/uapi/linux/kernel-page-flags.h
+++ b/include/uapi/linux/kernel-page-flags.h
@@ -32,6 +32,7 @@
#define KPF_KSM 21
#define KPF_THP 22
#define KPF_BALLOON 23
+#define KPF_ZERO_PAGE 24


#endif /* _UAPILINUX_KERNEL_PAGE_FLAGS_H */
--
2.1.3


2014-12-05 09:20:41

by Konstantin Khlebnikov

[permalink] [raw]
Subject: Re: [RFC] mm:add KPF_ZERO_PAGE flag for /proc/kpageflags

On Fri, Dec 5, 2014 at 11:57 AM, Wang, Yalin <[email protected]> wrote:
> This patch add KPF_ZERO_PAGE flag for zero_page,
> so that userspace process can notice zero_page from
> /proc/kpageflags, and then do memory analysis more accurately.

It would be nice to mark also huge_zero_page. See (completely
untested) patch in attachment.

>
> Signed-off-by: Yalin Wang <[email protected]>
> ---
> fs/proc/page.c | 3 +++
> include/uapi/linux/kernel-page-flags.h | 1 +
> 2 files changed, 4 insertions(+)
>
> diff --git a/fs/proc/page.c b/fs/proc/page.c
> index 1e3187d..120dbf7 100644
> --- a/fs/proc/page.c
> +++ b/fs/proc/page.c
> @@ -136,6 +136,9 @@ u64 stable_page_flags(struct page *page)
> if (PageBalloon(page))
> u |= 1 << KPF_BALLOON;
>
> + if (is_zero_pfn(page_to_pfn(page)))
> + u |= 1 << KPF_ZERO_PAGE;
> +
> u |= kpf_copy_bit(k, KPF_LOCKED, PG_locked);
>
> u |= kpf_copy_bit(k, KPF_SLAB, PG_slab);
> diff --git a/include/uapi/linux/kernel-page-flags.h b/include/uapi/linux/kernel-page-flags.h
> index 2f96d23..a6c4962 100644
> --- a/include/uapi/linux/kernel-page-flags.h
> +++ b/include/uapi/linux/kernel-page-flags.h
> @@ -32,6 +32,7 @@
> #define KPF_KSM 21
> #define KPF_THP 22
> #define KPF_BALLOON 23
> +#define KPF_ZERO_PAGE 24
>
>
> #endif /* _UAPILINUX_KERNEL_PAGE_FLAGS_H */
> --
> 2.1.3


Attachments:
kpageflags-zero-huge-page (2.56 kB)

2014-12-05 10:21:27

by Wang, Yalin

[permalink] [raw]
Subject: [RFC V2] mm:add KPF_ZERO_PAGE flag for /proc/kpageflags

This patch add KPF_ZERO_PAGE flag for zero_page,
so that userspace process can notice zero_page from
/proc/kpageflags, and then do memory analysis more accurately.

Signed-off-by: Yalin Wang <[email protected]>
---
fs/proc/page.c | 14 +++++++++++---
include/linux/huge_mm.h | 12 ++++++++++++
include/uapi/linux/kernel-page-flags.h | 1 +
mm/huge_memory.c | 7 +------
4 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/fs/proc/page.c b/fs/proc/page.c
index 1e3187d..dbe5630 100644
--- a/fs/proc/page.c
+++ b/fs/proc/page.c
@@ -5,6 +5,7 @@
#include <linux/ksm.h>
#include <linux/mm.h>
#include <linux/mmzone.h>
+#include <linux/huge_mm.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/hugetlb.h>
@@ -121,9 +122,16 @@ u64 stable_page_flags(struct page *page)
* just checks PG_head/PG_tail, so we need to check PageLRU/PageAnon
* to make sure a given page is a thp, not a non-huge compound page.
*/
- else if (PageTransCompound(page) && (PageLRU(compound_head(page)) ||
- PageAnon(compound_head(page))))
- u |= 1 << KPF_THP;
+ else if (PageTransCompound(page)) {
+ struct page *head = compound_head(page);
+
+ if (PageLRU(head) || PageAnon(head))
+ u |= 1 << KPF_THP;
+ else if (is_huge_zero_page(head))
+ u |= 1 << KPF_ZERO_PAGE;
+ } else if (is_zero_pfn(page_to_pfn(page)))
+ u |= 1 << KPF_ZERO_PAGE;
+

/*
* Caveats on high order pages: page->_count will only be set
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index ad9051b..f10b20f 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -157,6 +157,13 @@ static inline int hpage_nr_pages(struct page *page)
extern int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long addr, pmd_t pmd, pmd_t *pmdp);

+extern struct page *huge_zero_page;
+
+static inline bool is_huge_zero_page(struct page *page)
+{
+ return ACCESS_ONCE(huge_zero_page) == page;
+}
+
#else /* CONFIG_TRANSPARENT_HUGEPAGE */
#define HPAGE_PMD_SHIFT ({ BUILD_BUG(); 0; })
#define HPAGE_PMD_MASK ({ BUILD_BUG(); 0; })
@@ -206,6 +213,11 @@ static inline int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_str
return 0;
}

+static inline bool is_huge_zero_page(struct page *page)
+{
+ return false;
+}
+
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */

#endif /* _LINUX_HUGE_MM_H */
diff --git a/include/uapi/linux/kernel-page-flags.h b/include/uapi/linux/kernel-page-flags.h
index 2f96d23..a6c4962 100644
--- a/include/uapi/linux/kernel-page-flags.h
+++ b/include/uapi/linux/kernel-page-flags.h
@@ -32,6 +32,7 @@
#define KPF_KSM 21
#define KPF_THP 22
#define KPF_BALLOON 23
+#define KPF_ZERO_PAGE 24


#endif /* _UAPILINUX_KERNEL_PAGE_FLAGS_H */
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index de98415..d7bc7a5 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -171,12 +171,7 @@ static int start_khugepaged(void)
}

static atomic_t huge_zero_refcount;
-static struct page *huge_zero_page __read_mostly;
-
-static inline bool is_huge_zero_page(struct page *page)
-{
- return ACCESS_ONCE(huge_zero_page) == page;
-}
+struct page *huge_zero_page __read_mostly;

static inline bool is_huge_zero_pmd(pmd_t pmd)
{
--
2.1.3

2014-12-05 10:22:42

by Wang, Yalin

[permalink] [raw]
Subject: RE: [RFC] mm:add KPF_ZERO_PAGE flag for /proc/kpageflags

> -----Original Message-----
> From: Konstantin Khlebnikov [mailto:[email protected]]
> Sent: Friday, December 05, 2014 5:21 PM
> To: Wang, Yalin
> Cc: [email protected]; [email protected]; linux-arm-
> [email protected]; [email protected]; n-
> [email protected]
> Subject: Re: [RFC] mm:add KPF_ZERO_PAGE flag for /proc/kpageflags
>
> On Fri, Dec 5, 2014 at 11:57 AM, Wang, Yalin <[email protected]>
> wrote:
> > This patch add KPF_ZERO_PAGE flag for zero_page, so that userspace
> > process can notice zero_page from /proc/kpageflags, and then do memory
> > analysis more accurately.
>
> It would be nice to mark also huge_zero_page. See (completely
> untested) patch in attachment.
>
Got it,
Thanks for your patch.
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?

2014-12-05 11:06:12

by Kirill A. Shutemov

[permalink] [raw]
Subject: Re: [RFC V2] mm:add KPF_ZERO_PAGE flag for /proc/kpageflags

On Fri, Dec 05, 2014 at 06:21:17PM +0800, Wang, Yalin wrote:
> This patch add KPF_ZERO_PAGE flag for zero_page,
> so that userspace process can notice zero_page from
> /proc/kpageflags, and then do memory analysis more accurately.
>
> Signed-off-by: Yalin Wang <[email protected]>
> ---
> fs/proc/page.c | 14 +++++++++++---
> include/linux/huge_mm.h | 12 ++++++++++++
> include/uapi/linux/kernel-page-flags.h | 1 +
> mm/huge_memory.c | 7 +------
> 4 files changed, 25 insertions(+), 9 deletions(-)
>
> diff --git a/fs/proc/page.c b/fs/proc/page.c
> index 1e3187d..dbe5630 100644
> --- a/fs/proc/page.c
> +++ b/fs/proc/page.c
> @@ -5,6 +5,7 @@
> #include <linux/ksm.h>
> #include <linux/mm.h>
> #include <linux/mmzone.h>
> +#include <linux/huge_mm.h>
> #include <linux/proc_fs.h>
> #include <linux/seq_file.h>
> #include <linux/hugetlb.h>
> @@ -121,9 +122,16 @@ u64 stable_page_flags(struct page *page)
> * just checks PG_head/PG_tail, so we need to check PageLRU/PageAnon
> * to make sure a given page is a thp, not a non-huge compound page.
> */
> - else if (PageTransCompound(page) && (PageLRU(compound_head(page)) ||
> - PageAnon(compound_head(page))))
> - u |= 1 << KPF_THP;
> + else if (PageTransCompound(page)) {
> + struct page *head = compound_head(page);
> +
> + if (PageLRU(head) || PageAnon(head))
> + u |= 1 << KPF_THP;
> + else if (is_huge_zero_page(head))
> + u |= 1 << KPF_ZERO_PAGE;

IIUC, KPF_THP bit should be set for huge zero page too.

--
Kirill A. Shutemov

2014-12-05 22:31:37

by Andrew Morton

[permalink] [raw]
Subject: Re: [RFC] mm:add KPF_ZERO_PAGE flag for /proc/kpageflags

On Fri, 5 Dec 2014 18:22:33 +0800 "Wang, Yalin" <[email protected]> wrote:

> > -----Original Message-----
> > From: Konstantin Khlebnikov [mailto:[email protected]]
> > Sent: Friday, December 05, 2014 5:21 PM
> > To: Wang, Yalin
> > Cc: [email protected]; [email protected]; linux-arm-
> > [email protected]; [email protected]; n-
> > [email protected]
> > Subject: Re: [RFC] mm:add KPF_ZERO_PAGE flag for /proc/kpageflags
> >
> > On Fri, Dec 5, 2014 at 11:57 AM, Wang, Yalin <[email protected]>
> > wrote:
> > > This patch add KPF_ZERO_PAGE flag for zero_page, so that userspace
> > > process can notice zero_page from /proc/kpageflags, and then do memory
> > > analysis more accurately.
> >
> > It would be nice to mark also huge_zero_page. See (completely
> > untested) patch in attachment.
> >
> Got it,
> Thanks for your patch.

Documentation/vm/pagemap.txt will need updating please.

2014-12-08 01:51:23

by Wang, Yalin

[permalink] [raw]
Subject: [RFC V3] mm:add KPF_ZERO_PAGE flag for /proc/kpageflags

This patch add KPF_ZERO_PAGE flag for zero_page,
so that userspace process can notice zero_page from
/proc/kpageflags, and then do memory analysis more accurately.

Signed-off-by: Yalin Wang <[email protected]>
---
fs/proc/page.c | 16 +++++++++++++---
include/linux/huge_mm.h | 12 ++++++++++++
include/uapi/linux/kernel-page-flags.h | 1 +
mm/huge_memory.c | 7 +------
4 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/fs/proc/page.c b/fs/proc/page.c
index 1e3187d..7eee2d8 100644
--- a/fs/proc/page.c
+++ b/fs/proc/page.c
@@ -5,6 +5,7 @@
#include <linux/ksm.h>
#include <linux/mm.h>
#include <linux/mmzone.h>
+#include <linux/huge_mm.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/hugetlb.h>
@@ -121,9 +122,18 @@ u64 stable_page_flags(struct page *page)
* just checks PG_head/PG_tail, so we need to check PageLRU/PageAnon
* to make sure a given page is a thp, not a non-huge compound page.
*/
- else if (PageTransCompound(page) && (PageLRU(compound_head(page)) ||
- PageAnon(compound_head(page))))
- u |= 1 << KPF_THP;
+ else if (PageTransCompound(page)) {
+ struct page *head = compound_head(page);
+
+ if (PageLRU(head) || PageAnon(head))
+ u |= 1 << KPF_THP;
+ else if (is_huge_zero_page(head)) {
+ u |= 1 << KPF_ZERO_PAGE;
+ u |= 1 << KPF_THP;
+ }
+ } else if (is_zero_pfn(page_to_pfn(page)))
+ u |= 1 << KPF_ZERO_PAGE;
+

/*
* Caveats on high order pages: page->_count will only be set
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index ad9051b..f10b20f 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -157,6 +157,13 @@ static inline int hpage_nr_pages(struct page *page)
extern int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long addr, pmd_t pmd, pmd_t *pmdp);

+extern struct page *huge_zero_page;
+
+static inline bool is_huge_zero_page(struct page *page)
+{
+ return ACCESS_ONCE(huge_zero_page) == page;
+}
+
#else /* CONFIG_TRANSPARENT_HUGEPAGE */
#define HPAGE_PMD_SHIFT ({ BUILD_BUG(); 0; })
#define HPAGE_PMD_MASK ({ BUILD_BUG(); 0; })
@@ -206,6 +213,11 @@ static inline int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_str
return 0;
}

+static inline bool is_huge_zero_page(struct page *page)
+{
+ return false;
+}
+
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */

#endif /* _LINUX_HUGE_MM_H */
diff --git a/include/uapi/linux/kernel-page-flags.h b/include/uapi/linux/kernel-page-flags.h
index 2f96d23..a6c4962 100644
--- a/include/uapi/linux/kernel-page-flags.h
+++ b/include/uapi/linux/kernel-page-flags.h
@@ -32,6 +32,7 @@
#define KPF_KSM 21
#define KPF_THP 22
#define KPF_BALLOON 23
+#define KPF_ZERO_PAGE 24


#endif /* _UAPILINUX_KERNEL_PAGE_FLAGS_H */
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index de98415..d7bc7a5 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -171,12 +171,7 @@ static int start_khugepaged(void)
}

static atomic_t huge_zero_refcount;
-static struct page *huge_zero_page __read_mostly;
-
-static inline bool is_huge_zero_page(struct page *page)
-{
- return ACCESS_ONCE(huge_zero_page) == page;
-}
+struct page *huge_zero_page __read_mostly;

static inline bool is_huge_zero_pmd(pmd_t pmd)
{
--
2.1.3

2014-12-08 02:00:56

by Wang, Yalin

[permalink] [raw]
Subject: [RFC V4] mm:add KPF_ZERO_PAGE flag for /proc/kpageflags

This patch add KPF_ZERO_PAGE flag for zero_page,
so that userspace process can notice zero_page from
/proc/kpageflags, and then do memory analysis more accurately.

Signed-off-by: Yalin Wang <[email protected]>
---
Documentation/vm/pagemap.txt | 5 +++++
fs/proc/page.c | 16 +++++++++++++---
include/linux/huge_mm.h | 12 ++++++++++++
include/uapi/linux/kernel-page-flags.h | 1 +
mm/huge_memory.c | 7 +------
5 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/Documentation/vm/pagemap.txt b/Documentation/vm/pagemap.txt
index 5948e45..fdeb06e 100644
--- a/Documentation/vm/pagemap.txt
+++ b/Documentation/vm/pagemap.txt
@@ -62,6 +62,8 @@ There are three components to pagemap:
20. NOPAGE
21. KSM
22. THP
+ 23. BALLOON
+ 24. ZERO_PAGE

Short descriptions to the page flags:

@@ -102,6 +104,9 @@ Short descriptions to the page flags:
22. THP
contiguous pages which construct transparent hugepages

+24. ZERO_PAGE
+ zero page for pfn_zero or huge_zero page
+
[IO related page flags]
1. ERROR IO error occurred
3. UPTODATE page has up-to-date data
diff --git a/fs/proc/page.c b/fs/proc/page.c
index 1e3187d..7eee2d8 100644
--- a/fs/proc/page.c
+++ b/fs/proc/page.c
@@ -5,6 +5,7 @@
#include <linux/ksm.h>
#include <linux/mm.h>
#include <linux/mmzone.h>
+#include <linux/huge_mm.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/hugetlb.h>
@@ -121,9 +122,18 @@ u64 stable_page_flags(struct page *page)
* just checks PG_head/PG_tail, so we need to check PageLRU/PageAnon
* to make sure a given page is a thp, not a non-huge compound page.
*/
- else if (PageTransCompound(page) && (PageLRU(compound_head(page)) ||
- PageAnon(compound_head(page))))
- u |= 1 << KPF_THP;
+ else if (PageTransCompound(page)) {
+ struct page *head = compound_head(page);
+
+ if (PageLRU(head) || PageAnon(head))
+ u |= 1 << KPF_THP;
+ else if (is_huge_zero_page(head)) {
+ u |= 1 << KPF_ZERO_PAGE;
+ u |= 1 << KPF_THP;
+ }
+ } else if (is_zero_pfn(page_to_pfn(page)))
+ u |= 1 << KPF_ZERO_PAGE;
+

/*
* Caveats on high order pages: page->_count will only be set
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index ad9051b..f10b20f 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -157,6 +157,13 @@ static inline int hpage_nr_pages(struct page *page)
extern int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long addr, pmd_t pmd, pmd_t *pmdp);

+extern struct page *huge_zero_page;
+
+static inline bool is_huge_zero_page(struct page *page)
+{
+ return ACCESS_ONCE(huge_zero_page) == page;
+}
+
#else /* CONFIG_TRANSPARENT_HUGEPAGE */
#define HPAGE_PMD_SHIFT ({ BUILD_BUG(); 0; })
#define HPAGE_PMD_MASK ({ BUILD_BUG(); 0; })
@@ -206,6 +213,11 @@ static inline int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_str
return 0;
}

+static inline bool is_huge_zero_page(struct page *page)
+{
+ return false;
+}
+
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */

#endif /* _LINUX_HUGE_MM_H */
diff --git a/include/uapi/linux/kernel-page-flags.h b/include/uapi/linux/kernel-page-flags.h
index 2f96d23..a6c4962 100644
--- a/include/uapi/linux/kernel-page-flags.h
+++ b/include/uapi/linux/kernel-page-flags.h
@@ -32,6 +32,7 @@
#define KPF_KSM 21
#define KPF_THP 22
#define KPF_BALLOON 23
+#define KPF_ZERO_PAGE 24


#endif /* _UAPILINUX_KERNEL_PAGE_FLAGS_H */
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index de98415..d7bc7a5 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -171,12 +171,7 @@ static int start_khugepaged(void)
}

static atomic_t huge_zero_refcount;
-static struct page *huge_zero_page __read_mostly;
-
-static inline bool is_huge_zero_page(struct page *page)
-{
- return ACCESS_ONCE(huge_zero_page) == page;
-}
+struct page *huge_zero_page __read_mostly;

static inline bool is_huge_zero_pmd(pmd_t pmd)
{
--
2.1.3

2014-12-08 07:47:52

by Wang, Yalin

[permalink] [raw]
Subject: [PATCH] mm:add VM_BUG_ON() for page_mapcount()

This patch add VM_BUG_ON() for slab page,
because _mapcount is an union with slab struct in struct page,
avoid access _mapcount if this page is a slab page.
Also remove the unneeded bracket.

Signed-off-by: Yalin Wang <[email protected]>
---
include/linux/mm.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index 11b65cf..34124c4 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -373,7 +373,8 @@ static inline void reset_page_mapcount(struct page *page)

static inline int page_mapcount(struct page *page)
{
- return atomic_read(&(page)->_mapcount) + 1;
+ VM_BUG_ON(PageSlab(page));
+ return atomic_read(&page->_mapcount) + 1;
}

static inline int page_count(struct page *page)
--
2.1.3

2014-12-08 09:34:31

by Hillf Danton

[permalink] [raw]
Subject: Re: [PATCH] mm:add VM_BUG_ON() for page_mapcount()

>
> This patch add VM_BUG_ON() for slab page,
> because _mapcount is an union with slab struct in struct page,
> avoid access _mapcount if this page is a slab page.
> Also remove the unneeded bracket.
>
> Signed-off-by: Yalin Wang <[email protected]>
> ---
> include/linux/mm.h | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 11b65cf..34124c4 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -373,7 +373,8 @@ static inline void reset_page_mapcount(struct page *page)
>
> static inline int page_mapcount(struct page *page)
> {
> - return atomic_read(&(page)->_mapcount) + 1;
> + VM_BUG_ON(PageSlab(page));

s/ VM_BUG_ON/ VM_BUG_ON_PAGE/ ?

> + return atomic_read(&page->_mapcount) + 1;
> }
>

2014-12-08 09:51:19

by Wang, Yalin

[permalink] [raw]
Subject: RE: [PATCH] mm:add VM_BUG_ON() for page_mapcount()

> -----Original Message-----
> From: Hillf Danton [mailto:[email protected]]
> Sent: Monday, December 08, 2014 5:33 PM
> To: Wang, Yalin
> Cc: linux-kernel; [email protected]; [email protected];
> Andrew Morton; Hillf Danton
> Subject: Re: [PATCH] mm:add VM_BUG_ON() for page_mapcount()
>
> >
> > This patch add VM_BUG_ON() for slab page, because _mapcount is an
> > union with slab struct in struct page, avoid access _mapcount if this
> > page is a slab page.
> > Also remove the unneeded bracket.
> >
> > Signed-off-by: Yalin Wang <[email protected]>
> > ---
> > include/linux/mm.h | 3 ++-
> > 1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/include/linux/mm.h b/include/linux/mm.h index
> > 11b65cf..34124c4 100644
> > --- a/include/linux/mm.h
> > +++ b/include/linux/mm.h
> > @@ -373,7 +373,8 @@ static inline void reset_page_mapcount(struct page
> > *page)
> >
> > static inline int page_mapcount(struct page *page) {
> > - return atomic_read(&(page)->_mapcount) + 1;
> > + VM_BUG_ON(PageSlab(page));
>
> s/ VM_BUG_ON/ VM_BUG_ON_PAGE/ ?
Yes, I will send again .
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?

2014-12-08 09:58:23

by Wang, Yalin

[permalink] [raw]
Subject: [PATCH V2] mm:add VM_BUG_ON() for page_mapcount()

This patch add VM_BUG_ON_PAGE() for slab page,
because _mapcount is an union with slab struct in struct page,
avoid access _mapcount if this page is a slab page.
Also remove the unneeded bracket.

Signed-off-by: Yalin Wang <[email protected]>
---
include/linux/mm.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index b464611..a117527 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -449,7 +449,8 @@ static inline void page_mapcount_reset(struct page *page)

static inline int page_mapcount(struct page *page)
{
- return atomic_read(&(page)->_mapcount) + 1;
+ VM_BUG_ON_PAGE(PageSlab(page), page);
+ return atomic_read(&page->_mapcount) + 1;
}

static inline int page_count(struct page *page)
--
2.1.3
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?

2014-12-08 09:59:57

by Wang, Yalin

[permalink] [raw]
Subject: [PATCH V3] mm:add VM_BUG_ON_PAGE() for page_mapcount()

This patch add VM_BUG_ON_PAGE() for slab page,
because _mapcount is an union with slab struct in struct page,
avoid access _mapcount if this page is a slab page.
Also remove the unneeded bracket.

Signed-off-by: Yalin Wang <[email protected]>
---
include/linux/mm.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index b464611..a117527 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -449,7 +449,8 @@ static inline void page_mapcount_reset(struct page *page)

static inline int page_mapcount(struct page *page)
{
- return atomic_read(&(page)->_mapcount) + 1;
+ VM_BUG_ON_PAGE(PageSlab(page), page);
+ return atomic_read(&page->_mapcount) + 1;
}

static inline int page_count(struct page *page)
--
2.1.3
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?

2014-12-08 11:48:50

by Kirill A. Shutemov

[permalink] [raw]
Subject: Re: [RFC V4] mm:add KPF_ZERO_PAGE flag for /proc/kpageflags

On Mon, Dec 08, 2014 at 10:00:50AM +0800, Wang, Yalin wrote:
> This patch add KPF_ZERO_PAGE flag for zero_page,
> so that userspace process can notice zero_page from
> /proc/kpageflags, and then do memory analysis more accurately.
>
> Signed-off-by: Yalin Wang <[email protected]>
> ---
> Documentation/vm/pagemap.txt | 5 +++++
> fs/proc/page.c | 16 +++++++++++++---
> include/linux/huge_mm.h | 12 ++++++++++++
> include/uapi/linux/kernel-page-flags.h | 1 +
> mm/huge_memory.c | 7 +------
> 5 files changed, 32 insertions(+), 9 deletions(-)
>
> diff --git a/Documentation/vm/pagemap.txt b/Documentation/vm/pagemap.txt
> index 5948e45..fdeb06e 100644
> --- a/Documentation/vm/pagemap.txt
> +++ b/Documentation/vm/pagemap.txt
> @@ -62,6 +62,8 @@ There are three components to pagemap:
> 20. NOPAGE
> 21. KSM
> 22. THP
> + 23. BALLOON
> + 24. ZERO_PAGE
>
> Short descriptions to the page flags:
>
> @@ -102,6 +104,9 @@ Short descriptions to the page flags:
> 22. THP
> contiguous pages which construct transparent hugepages
>
> +24. ZERO_PAGE
> + zero page for pfn_zero or huge_zero page
> +
> [IO related page flags]
> 1. ERROR IO error occurred
> 3. UPTODATE page has up-to-date data

Would be nice to document BALLOON while you're there.
Otherwise looks good to me.

Acked-by: Kirill A. Shutemov <[email protected]>

--
Kirill A. Shutemov

2014-12-08 11:51:11

by Kirill A. Shutemov

[permalink] [raw]
Subject: Re: [PATCH] mm:add VM_BUG_ON() for page_mapcount()

On Mon, Dec 08, 2014 at 03:47:47PM +0800, Wang, Yalin wrote:
> This patch add VM_BUG_ON() for slab page,
> because _mapcount is an union with slab struct in struct page,
> avoid access _mapcount if this page is a slab page.
> Also remove the unneeded bracket.
>
> Signed-off-by: Yalin Wang <[email protected]>
> ---
> include/linux/mm.h | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 11b65cf..34124c4 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -373,7 +373,8 @@ static inline void reset_page_mapcount(struct page *page)
>
> static inline int page_mapcount(struct page *page)
> {
> - return atomic_read(&(page)->_mapcount) + 1;
> + VM_BUG_ON(PageSlab(page));

VM_BUG_ON_PAGE(), please.

--
Kirill A. Shutemov

2014-12-08 11:55:20

by Kirill A. Shutemov

[permalink] [raw]
Subject: Re: [PATCH V3] mm:add VM_BUG_ON_PAGE() for page_mapcount()

On Mon, Dec 08, 2014 at 05:59:46PM +0800, Wang, Yalin wrote:
> This patch add VM_BUG_ON_PAGE() for slab page,
> because _mapcount is an union with slab struct in struct page,
> avoid access _mapcount if this page is a slab page.
> Also remove the unneeded bracket.
>
> Signed-off-by: Yalin Wang <[email protected]>

Acked-by: Kirill A. Shutemov <[email protected]>
--
Kirill A. Shutemov

2014-12-09 03:19:35

by Hillf Danton

[permalink] [raw]
Subject: Re: [PATCH V3] mm:add VM_BUG_ON_PAGE() for page_mapcount()

>
> This patch add VM_BUG_ON_PAGE() for slab page,
> because _mapcount is an union with slab struct in struct page,
> avoid access _mapcount if this page is a slab page.
> Also remove the unneeded bracket.
>
> Signed-off-by: Yalin Wang <[email protected]>
> ---
Acked-by: Hillf Danton <[email protected]>

> include/linux/mm.h | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index b464611..a117527 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -449,7 +449,8 @@ static inline void page_mapcount_reset(struct page *page)
>
> static inline int page_mapcount(struct page *page)
> {
> - return atomic_read(&(page)->_mapcount) + 1;
> + VM_BUG_ON_PAGE(PageSlab(page), page);
> + return atomic_read(&page->_mapcount) + 1;
> }
>
> static inline int page_count(struct page *page)
> --
> 2.1.3

2014-12-09 03:24:25

by Wang, Yalin

[permalink] [raw]
Subject: [RFC V5] mm:add KPF_ZERO_PAGE flag for /proc/kpageflags

This patch add KPF_ZERO_PAGE flag for zero_page,
so that userspace process can notice zero_page from
/proc/kpageflags, and then do memory analysis more accurately.

Signed-off-by: Yalin Wang <[email protected]>
---
Documentation/vm/pagemap.txt | 8 ++++++++
fs/proc/page.c | 16 +++++++++++++---
include/linux/huge_mm.h | 12 ++++++++++++
include/uapi/linux/kernel-page-flags.h | 1 +
mm/huge_memory.c | 7 +------
tools/vm/page-types.c | 1 +
6 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/Documentation/vm/pagemap.txt b/Documentation/vm/pagemap.txt
index 5948e45..6fbd55e 100644
--- a/Documentation/vm/pagemap.txt
+++ b/Documentation/vm/pagemap.txt
@@ -62,6 +62,8 @@ There are three components to pagemap:
20. NOPAGE
21. KSM
22. THP
+ 23. BALLOON
+ 24. ZERO_PAGE

Short descriptions to the page flags:

@@ -102,6 +104,12 @@ Short descriptions to the page flags:
22. THP
contiguous pages which construct transparent hugepages

+23. BALLOON
+ balloon compaction page
+
+24. ZERO_PAGE
+ zero page for pfn_zero or huge_zero page
+
[IO related page flags]
1. ERROR IO error occurred
3. UPTODATE page has up-to-date data
diff --git a/fs/proc/page.c b/fs/proc/page.c
index 1e3187d..7eee2d8 100644
--- a/fs/proc/page.c
+++ b/fs/proc/page.c
@@ -5,6 +5,7 @@
#include <linux/ksm.h>
#include <linux/mm.h>
#include <linux/mmzone.h>
+#include <linux/huge_mm.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/hugetlb.h>
@@ -121,9 +122,18 @@ u64 stable_page_flags(struct page *page)
* just checks PG_head/PG_tail, so we need to check PageLRU/PageAnon
* to make sure a given page is a thp, not a non-huge compound page.
*/
- else if (PageTransCompound(page) && (PageLRU(compound_head(page)) ||
- PageAnon(compound_head(page))))
- u |= 1 << KPF_THP;
+ else if (PageTransCompound(page)) {
+ struct page *head = compound_head(page);
+
+ if (PageLRU(head) || PageAnon(head))
+ u |= 1 << KPF_THP;
+ else if (is_huge_zero_page(head)) {
+ u |= 1 << KPF_ZERO_PAGE;
+ u |= 1 << KPF_THP;
+ }
+ } else if (is_zero_pfn(page_to_pfn(page)))
+ u |= 1 << KPF_ZERO_PAGE;
+

/*
* Caveats on high order pages: page->_count will only be set
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index ad9051b..f10b20f 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -157,6 +157,13 @@ static inline int hpage_nr_pages(struct page *page)
extern int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long addr, pmd_t pmd, pmd_t *pmdp);

+extern struct page *huge_zero_page;
+
+static inline bool is_huge_zero_page(struct page *page)
+{
+ return ACCESS_ONCE(huge_zero_page) == page;
+}
+
#else /* CONFIG_TRANSPARENT_HUGEPAGE */
#define HPAGE_PMD_SHIFT ({ BUILD_BUG(); 0; })
#define HPAGE_PMD_MASK ({ BUILD_BUG(); 0; })
@@ -206,6 +213,11 @@ static inline int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_str
return 0;
}

+static inline bool is_huge_zero_page(struct page *page)
+{
+ return false;
+}
+
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */

#endif /* _LINUX_HUGE_MM_H */
diff --git a/include/uapi/linux/kernel-page-flags.h b/include/uapi/linux/kernel-page-flags.h
index 2f96d23..a6c4962 100644
--- a/include/uapi/linux/kernel-page-flags.h
+++ b/include/uapi/linux/kernel-page-flags.h
@@ -32,6 +32,7 @@
#define KPF_KSM 21
#define KPF_THP 22
#define KPF_BALLOON 23
+#define KPF_ZERO_PAGE 24


#endif /* _UAPILINUX_KERNEL_PAGE_FLAGS_H */
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index de98415..d7bc7a5 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -171,12 +171,7 @@ static int start_khugepaged(void)
}

static atomic_t huge_zero_refcount;
-static struct page *huge_zero_page __read_mostly;
-
-static inline bool is_huge_zero_page(struct page *page)
-{
- return ACCESS_ONCE(huge_zero_page) == page;
-}
+struct page *huge_zero_page __read_mostly;

static inline bool is_huge_zero_pmd(pmd_t pmd)
{
diff --git a/tools/vm/page-types.c b/tools/vm/page-types.c
index 264fbc2..8bdf16b 100644
--- a/tools/vm/page-types.c
+++ b/tools/vm/page-types.c
@@ -133,6 +133,7 @@ static const char * const page_flag_names[] = {
[KPF_KSM] = "x:ksm",
[KPF_THP] = "t:thp",
[KPF_BALLOON] = "o:balloon",
+ [KPF_ZERO_PAGE] = "z:zero_page",

[KPF_RESERVED] = "r:reserved",
[KPF_MLOCKED] = "m:mlocked",
--
2.1.3

2014-12-10 07:22:26

by Wang, Yalin

[permalink] [raw]
Subject: [RFC] mm:fix zero_page huge_zero_page rss/pss statistic

smaps_pte_entry() doesn't ignore zero_huge_page,
but it ignore zero_page, because vm_normal_page() will
ignore it. We remove vm_normal_page() call, because walk_page_range()
have ignore VM_PFNMAP vma maps, it's safe to just use pfn_valid(),
so that we can also consider zero_page to be a valid page.

Another change is that we only add map_count >= 2 or mapcount == 1
pages into pss, because zero_page and huge_zero_page's _mapcount is
zero, this means pss will consider evey zero page as a PAGE_SIZE for
every process, this is not correct for pss statistic. We ignore
zero page for pss, just add zero page into rss statistic.

Signed-off-by: Yalin Wang <[email protected]>
---
fs/proc/task_mmu.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 4e0388c..ce503d3 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -458,7 +458,9 @@ static void smaps_pte_entry(pte_t ptent, unsigned long addr,
int mapcount;

if (pte_present(ptent)) {
- page = vm_normal_page(vma, addr, ptent);
+ if (!pte_special(ptent) && pfn_valid(pte_pfn(ptent)))
+ page = pfn_to_page(pte_pfn(ptent));
+
} else if (is_swap_pte(ptent)) {
swp_entry_t swpent = pte_to_swp_entry(ptent);

@@ -491,7 +493,7 @@ static void smaps_pte_entry(pte_t ptent, unsigned long addr,
else
mss->shared_clean += ptent_size;
mss->pss += (ptent_size << PSS_SHIFT) / mapcount;
- } else {
+ } else if (mapcount == 1){
if (pte_dirty(ptent) || PageDirty(page))
mss->private_dirty += ptent_size;
else
--
2.1.3

2014-12-10 11:09:06

by Kirill A. Shutemov

[permalink] [raw]
Subject: Re: [RFC] mm:fix zero_page huge_zero_page rss/pss statistic

On Wed, Dec 10, 2014 at 03:22:21PM +0800, Wang, Yalin wrote:
> smaps_pte_entry() doesn't ignore zero_huge_page,
> but it ignore zero_page, because vm_normal_page() will
> ignore it. We remove vm_normal_page() call, because walk_page_range()
> have ignore VM_PFNMAP vma maps, it's safe to just use pfn_valid(),
> so that we can also consider zero_page to be a valid page.

We fixed huge zero page accounting in smaps recentely. See mm tree.

--
Kirill A. Shutemov

2014-12-10 17:06:12

by Konstantin Khlebnikov

[permalink] [raw]
Subject: Re: [RFC V5] mm:add KPF_ZERO_PAGE flag for /proc/kpageflags

On Tue, Dec 9, 2014 at 6:24 AM, Wang, Yalin <[email protected]> wrote:
> This patch add KPF_ZERO_PAGE flag for zero_page,
> so that userspace process can notice zero_page from
> /proc/kpageflags, and then do memory analysis more accurately.
>
> Signed-off-by: Yalin Wang <[email protected]>

Ack. Looks good.

> ---
> Documentation/vm/pagemap.txt | 8 ++++++++
> fs/proc/page.c | 16 +++++++++++++---
> include/linux/huge_mm.h | 12 ++++++++++++
> include/uapi/linux/kernel-page-flags.h | 1 +
> mm/huge_memory.c | 7 +------
> tools/vm/page-types.c | 1 +
> 6 files changed, 36 insertions(+), 9 deletions(-)
>
> diff --git a/Documentation/vm/pagemap.txt b/Documentation/vm/pagemap.txt
> index 5948e45..6fbd55e 100644
> --- a/Documentation/vm/pagemap.txt
> +++ b/Documentation/vm/pagemap.txt
> @@ -62,6 +62,8 @@ There are three components to pagemap:
> 20. NOPAGE
> 21. KSM
> 22. THP
> + 23. BALLOON
> + 24. ZERO_PAGE
>
> Short descriptions to the page flags:
>
> @@ -102,6 +104,12 @@ Short descriptions to the page flags:
> 22. THP
> contiguous pages which construct transparent hugepages
>
> +23. BALLOON
> + balloon compaction page
> +
> +24. ZERO_PAGE
> + zero page for pfn_zero or huge_zero page
> +
> [IO related page flags]
> 1. ERROR IO error occurred
> 3. UPTODATE page has up-to-date data
> diff --git a/fs/proc/page.c b/fs/proc/page.c
> index 1e3187d..7eee2d8 100644
> --- a/fs/proc/page.c
> +++ b/fs/proc/page.c
> @@ -5,6 +5,7 @@
> #include <linux/ksm.h>
> #include <linux/mm.h>
> #include <linux/mmzone.h>
> +#include <linux/huge_mm.h>
> #include <linux/proc_fs.h>
> #include <linux/seq_file.h>
> #include <linux/hugetlb.h>
> @@ -121,9 +122,18 @@ u64 stable_page_flags(struct page *page)
> * just checks PG_head/PG_tail, so we need to check PageLRU/PageAnon
> * to make sure a given page is a thp, not a non-huge compound page.
> */
> - else if (PageTransCompound(page) && (PageLRU(compound_head(page)) ||
> - PageAnon(compound_head(page))))
> - u |= 1 << KPF_THP;
> + else if (PageTransCompound(page)) {
> + struct page *head = compound_head(page);
> +
> + if (PageLRU(head) || PageAnon(head))
> + u |= 1 << KPF_THP;
> + else if (is_huge_zero_page(head)) {
> + u |= 1 << KPF_ZERO_PAGE;
> + u |= 1 << KPF_THP;
> + }
> + } else if (is_zero_pfn(page_to_pfn(page)))
> + u |= 1 << KPF_ZERO_PAGE;
> +
>
> /*
> * Caveats on high order pages: page->_count will only be set
> diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
> index ad9051b..f10b20f 100644
> --- a/include/linux/huge_mm.h
> +++ b/include/linux/huge_mm.h
> @@ -157,6 +157,13 @@ static inline int hpage_nr_pages(struct page *page)
> extern int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
> unsigned long addr, pmd_t pmd, pmd_t *pmdp);
>
> +extern struct page *huge_zero_page;
> +
> +static inline bool is_huge_zero_page(struct page *page)
> +{
> + return ACCESS_ONCE(huge_zero_page) == page;
> +}
> +
> #else /* CONFIG_TRANSPARENT_HUGEPAGE */
> #define HPAGE_PMD_SHIFT ({ BUILD_BUG(); 0; })
> #define HPAGE_PMD_MASK ({ BUILD_BUG(); 0; })
> @@ -206,6 +213,11 @@ static inline int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_str
> return 0;
> }
>
> +static inline bool is_huge_zero_page(struct page *page)
> +{
> + return false;
> +}
> +
> #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
>
> #endif /* _LINUX_HUGE_MM_H */
> diff --git a/include/uapi/linux/kernel-page-flags.h b/include/uapi/linux/kernel-page-flags.h
> index 2f96d23..a6c4962 100644
> --- a/include/uapi/linux/kernel-page-flags.h
> +++ b/include/uapi/linux/kernel-page-flags.h
> @@ -32,6 +32,7 @@
> #define KPF_KSM 21
> #define KPF_THP 22
> #define KPF_BALLOON 23
> +#define KPF_ZERO_PAGE 24
>
>
> #endif /* _UAPILINUX_KERNEL_PAGE_FLAGS_H */
> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> index de98415..d7bc7a5 100644
> --- a/mm/huge_memory.c
> +++ b/mm/huge_memory.c
> @@ -171,12 +171,7 @@ static int start_khugepaged(void)
> }
>
> static atomic_t huge_zero_refcount;
> -static struct page *huge_zero_page __read_mostly;
> -
> -static inline bool is_huge_zero_page(struct page *page)
> -{
> - return ACCESS_ONCE(huge_zero_page) == page;
> -}
> +struct page *huge_zero_page __read_mostly;
>
> static inline bool is_huge_zero_pmd(pmd_t pmd)
> {
> diff --git a/tools/vm/page-types.c b/tools/vm/page-types.c
> index 264fbc2..8bdf16b 100644
> --- a/tools/vm/page-types.c
> +++ b/tools/vm/page-types.c
> @@ -133,6 +133,7 @@ static const char * const page_flag_names[] = {
> [KPF_KSM] = "x:ksm",
> [KPF_THP] = "t:thp",
> [KPF_BALLOON] = "o:balloon",
> + [KPF_ZERO_PAGE] = "z:zero_page",
>
> [KPF_RESERVED] = "r:reserved",
> [KPF_MLOCKED] = "m:mlocked",
> --
> 2.1.3

2014-12-12 01:59:23

by Wang, Yalin

[permalink] [raw]
Subject: RE: [RFC] mm:fix zero_page huge_zero_page rss/pss statistic

> -----Original Message-----
> From: Kirill A. Shutemov [mailto:[email protected]]
> Sent: Wednesday, December 10, 2014 7:06 PM
> To: Wang, Yalin
> Cc: 'Andrew Morton'; 'Konstantin Khlebnikov'; 'linux-
> [email protected]'; '[email protected]'; 'linux-arm-
> [email protected]'; '[email protected]'; '[email protected]';
> '[email protected]'; '[email protected]'
> Subject: Re: [RFC] mm:fix zero_page huge_zero_page rss/pss statistic
>
> On Wed, Dec 10, 2014 at 03:22:21PM +0800, Wang, Yalin wrote:
> > smaps_pte_entry() doesn't ignore zero_huge_page, but it ignore
> > zero_page, because vm_normal_page() will ignore it. We remove
> > vm_normal_page() call, because walk_page_range() have ignore VM_PFNMAP
> > vma maps, it's safe to just use pfn_valid(), so that we can also
> > consider zero_page to be a valid page.
>
> We fixed huge zero page accounting in smaps recentely. See mm tree.
>
Hi
I can't find the git, could you send me a link?
Thank you !

2014-12-12 03:30:59

by Wang, Yalin

[permalink] [raw]
Subject: [RFC] discard task stack pages instead of pageout into swap partition

Hi,

I am think of discard stack pages if the old
Page is under the stack pointer(Assume stack grow down)
of the task, This page don't need pageout, we can free it directly,
When the task need it again, we just use a zero page to
Map, it is safe for stack .

But I don't know how to implement it,
And is there some issue if do like this ?

The following is pseudo code to explain my ideas.
Any comments are appreciated !
Thanks
---
diff --git a/mm/vmscan.c b/mm/vmscan.c
index dcb4707..52e8314 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -962,6 +962,12 @@ static unsigned long shrink_page_list(struct list_head *page_list,
; /* try to reclaim the page below */
}

+ if (page_vm_flags(page) & (VM_GROWSUP | VM_GROWSDOWN) &&
+ PageAnon(page) && !PageSwapCache(page)) {
+ if (page_task_is_sleep(page) && task_sp > page->index) {
+ zap_page_range(vma, page->index, PAGE_SIZE);
+ }
+ }
/*
* Anonymous process memory has backing store?
* Try to allocate it some swap space here.
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?

2014-12-12 11:13:10

by Kirill A. Shutemov

[permalink] [raw]
Subject: Re: [RFC] mm:fix zero_page huge_zero_page rss/pss statistic

On Fri, Dec 12, 2014 at 09:59:15AM +0800, Wang, Yalin wrote:
> > -----Original Message-----
> > From: Kirill A. Shutemov [mailto:[email protected]]
> > Sent: Wednesday, December 10, 2014 7:06 PM
> > To: Wang, Yalin
> > Cc: 'Andrew Morton'; 'Konstantin Khlebnikov'; 'linux-
> > [email protected]'; '[email protected]'; 'linux-arm-
> > [email protected]'; '[email protected]'; '[email protected]';
> > '[email protected]'; '[email protected]'
> > Subject: Re: [RFC] mm:fix zero_page huge_zero_page rss/pss statistic
> >
> > On Wed, Dec 10, 2014 at 03:22:21PM +0800, Wang, Yalin wrote:
> > > smaps_pte_entry() doesn't ignore zero_huge_page, but it ignore
> > > zero_page, because vm_normal_page() will ignore it. We remove
> > > vm_normal_page() call, because walk_page_range() have ignore VM_PFNMAP
> > > vma maps, it's safe to just use pfn_valid(), so that we can also
> > > consider zero_page to be a valid page.
> >
> > We fixed huge zero page accounting in smaps recentely. See mm tree.
> >
> Hi
> I can't find the git, could you send me a link?

http://git.cmpxchg.org/cgit.cgi/linux-mmotm.git/

or just take linux-next.

The fix is already in Linus' tree.

--
Kirill A. Shutemov

2014-12-18 03:50:11

by Wang, Yalin

[permalink] [raw]
Subject: [RFC] MADV_FREE doesn't work when doesn't have swap partition

I notice this commit:
mm: support madvise(MADV_FREE),

it can free clean anonymous pages directly,
doesn't need pageout to swap partition,

but I found it doesn't work on my platform,
which don't enable any swap partitions.

I make a change for this.
Just to explain my issue clearly,
Do we need some other checks to still scan anonymous pages even
Don't have swap partition but have clean anonymous pages?
---
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 5e8772b..8258f3a 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1941,7 +1941,7 @@ static void get_scan_count(struct lruvec *lruvec, int swappiness,
force_scan = true;

/* If we have no swap space, do not bother scanning anon pages. */
- if (!sc->may_swap || (get_nr_swap_pages() <= 0)) {
+ if (!sc->may_swap) {
scan_balance = SCAN_FILE;
goto out;
}
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?

2014-12-19 01:03:40

by Minchan Kim

[permalink] [raw]
Subject: Re: [RFC] MADV_FREE doesn't work when doesn't have swap partition

On Thu, Dec 18, 2014 at 11:50:01AM +0800, Wang, Yalin wrote:
> I notice this commit:
> mm: support madvise(MADV_FREE),
>
> it can free clean anonymous pages directly,
> doesn't need pageout to swap partition,
>
> but I found it doesn't work on my platform,
> which don't enable any swap partitions.

Current implementation, if there is no empty slot in swap, it does
instant free instead of delayed free. Look at madvise_vma.

>
> I make a change for this.
> Just to explain my issue clearly,
> Do we need some other checks to still scan anonymous pages even
> Don't have swap partition but have clean anonymous pages?

There is a few places we should consider if you want to scan anonymous page
withotu swap. Refer 69c854817566 and 74e3f3c3391d.

However, it's not simple at the moment. If we reenable anonymous scan without swap,
it would make much regress of reclaim. So my direction is move normal anonymos pages
into unevictable LRU list because they're real unevictable without swap and
put delayed freeing pages into anon LRU list and age them.

> ---
> diff --git a/mm/vmscan.c b/mm/vmscan.c
> index 5e8772b..8258f3a 100644
> --- a/mm/vmscan.c
> +++ b/mm/vmscan.c
> @@ -1941,7 +1941,7 @@ static void get_scan_count(struct lruvec *lruvec, int swappiness,
> force_scan = true;
>
> /* If we have no swap space, do not bother scanning anon pages. */
> - if (!sc->may_swap || (get_nr_swap_pages() <= 0)) {
> + if (!sc->may_swap) {
> scan_balance = SCAN_FILE;
> goto out;
> }

--
Kind regards,
Minchan Kim

2014-12-19 06:55:40

by Wang, Yalin

[permalink] [raw]
Subject: RE: [RFC] MADV_FREE doesn't work when doesn't have swap partition

> -----Original Message-----
> From: Minchan Kim [mailto:[email protected]]
> Sent: Friday, December 19, 2014 9:05 AM
> To: Wang, Yalin
> Cc: 'Konstantin Khlebnikov'; 'Kirill A. Shutemov'; 'Andrew Morton'; 'linux-
> [email protected]'; '[email protected]'; 'linux-arm-
> [email protected]'; '[email protected]'
> Subject: Re: [RFC] MADV_FREE doesn't work when doesn't have swap partition
>
> On Thu, Dec 18, 2014 at 11:50:01AM +0800, Wang, Yalin wrote:
> > I notice this commit:
> > mm: support madvise(MADV_FREE),
> >
> > it can free clean anonymous pages directly, doesn't need pageout to
> > swap partition,
> >
> > but I found it doesn't work on my platform, which don't enable any
> > swap partitions.
>
> Current implementation, if there is no empty slot in swap, it does instant
> free instead of delayed free. Look at madvise_vma.
>
> >
> > I make a change for this.
> > Just to explain my issue clearly,
> > Do we need some other checks to still scan anonymous pages even Don't
> > have swap partition but have clean anonymous pages?
>
> There is a few places we should consider if you want to scan anonymous page
> withotu swap. Refer 69c854817566 and 74e3f3c3391d.
>
> However, it's not simple at the moment. If we reenable anonymous scan
> without swap, it would make much regress of reclaim. So my direction is
> move normal anonymos pages into unevictable LRU list because they're real
> unevictable without swap and put delayed freeing pages into anon LRU list
> and age them.
>
I understand your solution, sounds a great idea!
When this design will be merged into main stream?

Thanks.
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?

2014-12-22 10:30:25

by Konstantin Khlebnikov

[permalink] [raw]
Subject: Re: [RFC] MADV_FREE doesn't work when doesn't have swap partition

On Fri, Dec 19, 2014 at 4:04 AM, Minchan Kim <[email protected]> wrote:
> On Thu, Dec 18, 2014 at 11:50:01AM +0800, Wang, Yalin wrote:
>> I notice this commit:
>> mm: support madvise(MADV_FREE),
>>
>> it can free clean anonymous pages directly,
>> doesn't need pageout to swap partition,
>>
>> but I found it doesn't work on my platform,
>> which don't enable any swap partitions.
>
> Current implementation, if there is no empty slot in swap, it does
> instant free instead of delayed free. Look at madvise_vma.
>
>>
>> I make a change for this.
>> Just to explain my issue clearly,
>> Do we need some other checks to still scan anonymous pages even
>> Don't have swap partition but have clean anonymous pages?
>
> There is a few places we should consider if you want to scan anonymous page
> withotu swap. Refer 69c854817566 and 74e3f3c3391d.
>
> However, it's not simple at the moment. If we reenable anonymous scan without swap,
> it would make much regress of reclaim. So my direction is move normal anonymos pages
> into unevictable LRU list because they're real unevictable without swap and
> put delayed freeing pages into anon LRU list and age them.

This sounds reasonable. In this case swapon must either scan
unevictable pages and make
some of them evictable again or just move all unevictable pages into
active list and postpone
this job till reclaimer invocation.

>
>> ---
>> diff --git a/mm/vmscan.c b/mm/vmscan.c
>> index 5e8772b..8258f3a 100644
>> --- a/mm/vmscan.c
>> +++ b/mm/vmscan.c
>> @@ -1941,7 +1941,7 @@ static void get_scan_count(struct lruvec *lruvec, int swappiness,
>> force_scan = true;
>>
>> /* If we have no swap space, do not bother scanning anon pages. */
>> - if (!sc->may_swap || (get_nr_swap_pages() <= 0)) {
>> + if (!sc->may_swap) {
>> scan_balance = SCAN_FILE;
>> goto out;
>> }
>
> --
> Kind regards,
> Minchan Kim
>
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to [email protected]. For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

2014-12-26 11:56:56

by Wang, Yalin

[permalink] [raw]
Subject: [RFC] mm:change meminfo cached calculation

This patch subtract sharedram from cached,
sharedram can only be swap into swap partitions,
they should be treated as swap pages, not as cached pages.

Signed-off-by: Yalin Wang <[email protected]>
---
fs/proc/meminfo.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c
index d3ebf2e..2b598a6 100644
--- a/fs/proc/meminfo.c
+++ b/fs/proc/meminfo.c
@@ -45,7 +45,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
committed = percpu_counter_read_positive(&vm_committed_as);

cached = global_page_state(NR_FILE_PAGES) -
- total_swapcache_pages() - i.bufferram;
+ total_swapcache_pages() - i.bufferram - i.sharedram;
if (cached < 0)
cached = 0;

--
2.1.3
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?

2015-06-09 16:14:42

by Vlastimil Babka

[permalink] [raw]
Subject: Re: [PATCH V3] mm:add VM_BUG_ON_PAGE() for page_mapcount()

On 12/08/2014 10:59 AM, Wang, Yalin wrote:
> This patch add VM_BUG_ON_PAGE() for slab page,
> because _mapcount is an union with slab struct in struct page,
> avoid access _mapcount if this page is a slab page.
> Also remove the unneeded bracket.
>
> Signed-off-by: Yalin Wang <[email protected]>
> ---
> include/linux/mm.h | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index b464611..a117527 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -449,7 +449,8 @@ static inline void page_mapcount_reset(struct page *page)
>
> static inline int page_mapcount(struct page *page)
> {
> - return atomic_read(&(page)->_mapcount) + 1;
> + VM_BUG_ON_PAGE(PageSlab(page), page);
> + return atomic_read(&page->_mapcount) + 1;
> }
>

I think this might theoretically trigger on the following code in
compaction's isolate_migratepages_block():

/*
* Migration will fail if an anonymous page is pinned in memory,
* so avoid taking lru_lock and isolating it unnecessarily in an
* admittedly racy check.
*/
if (!page_mapping(page) &&
page_count(page) > page_mapcount(page))
continue;

This is done after PageLRU() was positive, but the lru_lock might be not
taken yet. So, there's some time window during which the page might have
been reclaimed from LRU and become a PageSlab(page). !page_mapping(page)
will be true in that case so it will proceed with page_mapcount(page)
test and trigger the VM_BUG_ON.

(That test was added by DavidR year ago in commit
119d6d59dcc0980dcd581fdadb6b2033b512a473)

Vlastimil





> static inline int page_count(struct page *page)
>