Skip to content

Commit

Permalink
mm/idle_page_tracking: make PG_idle reusable
Browse files Browse the repository at this point in the history
PG_idle and PG_young allow the two PTE Accessed bit users, Idle Page
Tracking and the reclaim logic concurrently work while not interfering
with each other.  That is, when they need to clear the Accessed bit, they
set PG_young to represent the previous state of the bit, respectively.
And when they need to read the bit, if the bit is cleared, they further
read the PG_young to know whether the other has cleared the bit meanwhile
or not.

For yet another user of the PTE Accessed bit, we could add another page
flag, or extend the mechanism to use the flags.  For the DAMON usecase,
however, we don't need to do that just yet.  IDLE_PAGE_TRACKING and DAMON
are mutually exclusive, so there's only ever going to be one user of the
current set of flags.

In this commit, we split out the CONFIG options to allow for the use of
PG_young and PG_idle outside of idle page tracking.

In the next commit, DAMON's reference implementation of the virtual memory
address space monitoring primitives will use it.

[sjpark@amazon.de: set PAGE_EXTENSION for non-64BIT]
  Link: https://lkml.kernel.org/r/20210806095153.6444-1-sj38.park@gmail.com
[akpm@linux-foundation.org: tweak Kconfig text]
[sjpark@amazon.de: hide PAGE_IDLE_FLAG from users]
  Link: https://lkml.kernel.org/r/20210813081238.34705-1-sj38.park@gmail.com

Link: https://lkml.kernel.org/r/20210716081449.22187-5-sj38.park@gmail.com
Signed-off-by: SeongJae Park <sjpark@amazon.de>
Reviewed-by: Shakeel Butt <shakeelb@google.com>
Reviewed-by: Fernand Sieber <sieberf@amazon.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Amit Shah <amit@kernel.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Brendan Higgins <brendanhiggins@google.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: David Rientjes <rientjes@google.com>
Cc: David Woodhouse <dwmw@amazon.com>
Cc: Fan Du <fan.du@intel.com>
Cc: Greg Kroah-Hartman <greg@kroah.com>
Cc: Greg Thelen <gthelen@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Joe Perches <joe@perches.com>
Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Leonard Foerster <foersleo@amazon.de>
Cc: Marco Elver <elver@google.com>
Cc: Markus Boehme <markubo@amazon.de>
Cc: Maximilian Heyne <mheyne@amazon.de>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rik van Riel <riel@surriel.com>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Steven Rostedt (VMware) <rostedt@goodmis.org>
Cc: Vladimir Davydov <vdavydov.dev@gmail.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
SeongJae Park authored and Linus Torvalds committed Sep 8, 2021
1 parent b9a6ac4 commit 1c676e0
Show file tree
Hide file tree
Showing 7 changed files with 27 additions and 19 deletions.
4 changes: 2 additions & 2 deletions include/linux/page-flags.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ enum pageflags {
#ifdef CONFIG_MEMORY_FAILURE
PG_hwpoison, /* hardware poisoned page. Don't touch */
#endif
#if defined(CONFIG_IDLE_PAGE_TRACKING) && defined(CONFIG_64BIT)
#if defined(CONFIG_PAGE_IDLE_FLAG) && defined(CONFIG_64BIT)
PG_young,
PG_idle,
#endif
Expand Down Expand Up @@ -441,7 +441,7 @@ PAGEFLAG_FALSE(HWPoison)
#define __PG_HWPOISON 0
#endif

#if defined(CONFIG_IDLE_PAGE_TRACKING) && defined(CONFIG_64BIT)
#if defined(CONFIG_PAGE_IDLE_FLAG) && defined(CONFIG_64BIT)
TESTPAGEFLAG(Young, young, PF_ANY)
SETPAGEFLAG(Young, young, PF_ANY)
TESTCLEARFLAG(Young, young, PF_ANY)
Expand Down
2 changes: 1 addition & 1 deletion include/linux/page_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ struct page_ext_operations {
enum page_ext_flags {
PAGE_EXT_OWNER,
PAGE_EXT_OWNER_ALLOCATED,
#if defined(CONFIG_IDLE_PAGE_TRACKING) && !defined(CONFIG_64BIT)
#if defined(CONFIG_PAGE_IDLE_FLAG) && !defined(CONFIG_64BIT)
PAGE_EXT_YOUNG,
PAGE_EXT_IDLE,
#endif
Expand Down
6 changes: 3 additions & 3 deletions include/linux/page_idle.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <linux/page-flags.h>
#include <linux/page_ext.h>

#ifdef CONFIG_IDLE_PAGE_TRACKING
#ifdef CONFIG_PAGE_IDLE_FLAG

#ifdef CONFIG_64BIT
static inline bool page_is_young(struct page *page)
Expand Down Expand Up @@ -106,7 +106,7 @@ static inline void clear_page_idle(struct page *page)
}
#endif /* CONFIG_64BIT */

#else /* !CONFIG_IDLE_PAGE_TRACKING */
#else /* !CONFIG_PAGE_IDLE_FLAG */

static inline bool page_is_young(struct page *page)
{
Expand Down Expand Up @@ -135,6 +135,6 @@ static inline void clear_page_idle(struct page *page)
{
}

#endif /* CONFIG_IDLE_PAGE_TRACKING */
#endif /* CONFIG_PAGE_IDLE_FLAG */

#endif /* _LINUX_MM_PAGE_IDLE_H */
2 changes: 1 addition & 1 deletion include/trace/events/mmflags.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
#define IF_HAVE_PG_HWPOISON(flag,string)
#endif

#if defined(CONFIG_IDLE_PAGE_TRACKING) && defined(CONFIG_64BIT)
#if defined(CONFIG_PAGE_IDLE_FLAG) && defined(CONFIG_64BIT)
#define IF_HAVE_PG_IDLE(flag,string) ,{1UL << flag, string}
#else
#define IF_HAVE_PG_IDLE(flag,string)
Expand Down
10 changes: 9 additions & 1 deletion mm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -739,10 +739,18 @@ config DEFERRED_STRUCT_PAGE_INIT
lifetime of the system until these kthreads finish the
initialisation.

config PAGE_IDLE_FLAG
bool
select PAGE_EXTENSION if !64BIT
help
This adds PG_idle and PG_young flags to 'struct page'. PTE Accessed
bit writers can set the state of the bit in the flags so that PTE
Accessed bit readers may avoid disturbance.

config IDLE_PAGE_TRACKING
bool "Enable idle page tracking"
depends on SYSFS && MMU
select PAGE_EXTENSION if !64BIT
select PAGE_IDLE_FLAG
help
This feature allows to estimate the amount of user pages that have
not been touched during a given period of time. This information can
Expand Down
12 changes: 11 additions & 1 deletion mm/page_ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,21 @@
* can utilize this callback to initialize the state of it correctly.
*/

#if defined(CONFIG_PAGE_IDLE_FLAG) && !defined(CONFIG_64BIT)
static bool need_page_idle(void)
{
return true;
}
struct page_ext_operations page_idle_ops = {
.need = need_page_idle,
};
#endif

static struct page_ext_operations *page_ext_ops[] = {
#ifdef CONFIG_PAGE_OWNER
&page_owner_ops,
#endif
#if defined(CONFIG_IDLE_PAGE_TRACKING) && !defined(CONFIG_64BIT)
#if defined(CONFIG_PAGE_IDLE_FLAG) && !defined(CONFIG_64BIT)
&page_idle_ops,
#endif
};
Expand Down
10 changes: 0 additions & 10 deletions mm/page_idle.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,16 +207,6 @@ static const struct attribute_group page_idle_attr_group = {
.name = "page_idle",
};

#ifndef CONFIG_64BIT
static bool need_page_idle(void)
{
return true;
}
struct page_ext_operations page_idle_ops = {
.need = need_page_idle,
};
#endif

static int __init page_idle_init(void)
{
int err;
Expand Down

0 comments on commit 1c676e0

Please sign in to comment.