Skip to content

Commit 1c676e0

Browse files
sj-awstorvalds
authored andcommitted
mm/idle_page_tracking: make PG_idle reusable
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. [[email protected]: set PAGE_EXTENSION for non-64BIT] Link: https://lkml.kernel.org/r/[email protected] [[email protected]: tweak Kconfig text] [[email protected]: hide PAGE_IDLE_FLAG from users] Link: https://lkml.kernel.org/r/[email protected] Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: SeongJae Park <[email protected]> Reviewed-by: Shakeel Butt <[email protected]> Reviewed-by: Fernand Sieber <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Amit Shah <[email protected]> Cc: Benjamin Herrenschmidt <[email protected]> Cc: Brendan Higgins <[email protected]> Cc: David Hildenbrand <[email protected]> Cc: David Rientjes <[email protected]> Cc: David Woodhouse <[email protected]> Cc: Fan Du <[email protected]> Cc: Greg Kroah-Hartman <[email protected]> Cc: Greg Thelen <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Joe Perches <[email protected]> Cc: Jonathan Cameron <[email protected]> Cc: Jonathan Corbet <[email protected]> Cc: Leonard Foerster <[email protected]> Cc: Marco Elver <[email protected]> Cc: Markus Boehme <[email protected]> Cc: Maximilian Heyne <[email protected]> Cc: Mel Gorman <[email protected]> Cc: Minchan Kim <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Rik van Riel <[email protected]> Cc: Shuah Khan <[email protected]> Cc: Steven Rostedt (VMware) <[email protected]> Cc: Vladimir Davydov <[email protected]> Cc: Vlastimil Babka <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent b9a6ac4 commit 1c676e0

File tree

7 files changed

+27
-19
lines changed

7 files changed

+27
-19
lines changed

include/linux/page-flags.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ enum pageflags {
131131
#ifdef CONFIG_MEMORY_FAILURE
132132
PG_hwpoison, /* hardware poisoned page. Don't touch */
133133
#endif
134-
#if defined(CONFIG_IDLE_PAGE_TRACKING) && defined(CONFIG_64BIT)
134+
#if defined(CONFIG_PAGE_IDLE_FLAG) && defined(CONFIG_64BIT)
135135
PG_young,
136136
PG_idle,
137137
#endif
@@ -441,7 +441,7 @@ PAGEFLAG_FALSE(HWPoison)
441441
#define __PG_HWPOISON 0
442442
#endif
443443

444-
#if defined(CONFIG_IDLE_PAGE_TRACKING) && defined(CONFIG_64BIT)
444+
#if defined(CONFIG_PAGE_IDLE_FLAG) && defined(CONFIG_64BIT)
445445
TESTPAGEFLAG(Young, young, PF_ANY)
446446
SETPAGEFLAG(Young, young, PF_ANY)
447447
TESTCLEARFLAG(Young, young, PF_ANY)

include/linux/page_ext.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ struct page_ext_operations {
1919
enum page_ext_flags {
2020
PAGE_EXT_OWNER,
2121
PAGE_EXT_OWNER_ALLOCATED,
22-
#if defined(CONFIG_IDLE_PAGE_TRACKING) && !defined(CONFIG_64BIT)
22+
#if defined(CONFIG_PAGE_IDLE_FLAG) && !defined(CONFIG_64BIT)
2323
PAGE_EXT_YOUNG,
2424
PAGE_EXT_IDLE,
2525
#endif

include/linux/page_idle.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#include <linux/page-flags.h>
77
#include <linux/page_ext.h>
88

9-
#ifdef CONFIG_IDLE_PAGE_TRACKING
9+
#ifdef CONFIG_PAGE_IDLE_FLAG
1010

1111
#ifdef CONFIG_64BIT
1212
static inline bool page_is_young(struct page *page)
@@ -106,7 +106,7 @@ static inline void clear_page_idle(struct page *page)
106106
}
107107
#endif /* CONFIG_64BIT */
108108

109-
#else /* !CONFIG_IDLE_PAGE_TRACKING */
109+
#else /* !CONFIG_PAGE_IDLE_FLAG */
110110

111111
static inline bool page_is_young(struct page *page)
112112
{
@@ -135,6 +135,6 @@ static inline void clear_page_idle(struct page *page)
135135
{
136136
}
137137

138-
#endif /* CONFIG_IDLE_PAGE_TRACKING */
138+
#endif /* CONFIG_PAGE_IDLE_FLAG */
139139

140140
#endif /* _LINUX_MM_PAGE_IDLE_H */

include/trace/events/mmflags.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
#define IF_HAVE_PG_HWPOISON(flag,string)
7676
#endif
7777

78-
#if defined(CONFIG_IDLE_PAGE_TRACKING) && defined(CONFIG_64BIT)
78+
#if defined(CONFIG_PAGE_IDLE_FLAG) && defined(CONFIG_64BIT)
7979
#define IF_HAVE_PG_IDLE(flag,string) ,{1UL << flag, string}
8080
#else
8181
#define IF_HAVE_PG_IDLE(flag,string)

mm/Kconfig

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -739,10 +739,18 @@ config DEFERRED_STRUCT_PAGE_INIT
739739
lifetime of the system until these kthreads finish the
740740
initialisation.
741741

742+
config PAGE_IDLE_FLAG
743+
bool
744+
select PAGE_EXTENSION if !64BIT
745+
help
746+
This adds PG_idle and PG_young flags to 'struct page'. PTE Accessed
747+
bit writers can set the state of the bit in the flags so that PTE
748+
Accessed bit readers may avoid disturbance.
749+
742750
config IDLE_PAGE_TRACKING
743751
bool "Enable idle page tracking"
744752
depends on SYSFS && MMU
745-
select PAGE_EXTENSION if !64BIT
753+
select PAGE_IDLE_FLAG
746754
help
747755
This feature allows to estimate the amount of user pages that have
748756
not been touched during a given period of time. This information can

mm/page_ext.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,21 @@
5858
* can utilize this callback to initialize the state of it correctly.
5959
*/
6060

61+
#if defined(CONFIG_PAGE_IDLE_FLAG) && !defined(CONFIG_64BIT)
62+
static bool need_page_idle(void)
63+
{
64+
return true;
65+
}
66+
struct page_ext_operations page_idle_ops = {
67+
.need = need_page_idle,
68+
};
69+
#endif
70+
6171
static struct page_ext_operations *page_ext_ops[] = {
6272
#ifdef CONFIG_PAGE_OWNER
6373
&page_owner_ops,
6474
#endif
65-
#if defined(CONFIG_IDLE_PAGE_TRACKING) && !defined(CONFIG_64BIT)
75+
#if defined(CONFIG_PAGE_IDLE_FLAG) && !defined(CONFIG_64BIT)
6676
&page_idle_ops,
6777
#endif
6878
};

mm/page_idle.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -207,16 +207,6 @@ static const struct attribute_group page_idle_attr_group = {
207207
.name = "page_idle",
208208
};
209209

210-
#ifndef CONFIG_64BIT
211-
static bool need_page_idle(void)
212-
{
213-
return true;
214-
}
215-
struct page_ext_operations page_idle_ops = {
216-
.need = need_page_idle,
217-
};
218-
#endif
219-
220210
static int __init page_idle_init(void)
221211
{
222212
int err;

0 commit comments

Comments
 (0)