@@ -180,6 +180,13 @@ static ssize_t page_idle_bitmap_read(struct file *file, struct kobject *kobj,
unsigned long pfn, end_pfn;
int bit, ret;
+ /*
+ * Idle page tracking currently works only on LRU pages, so drain
+ * them. This can cause slowness, but in the future we could
+ * remove this operation if we are tracking non-LRU pages too.
+ */
+ lru_add_drain_all();
+
ret = page_idle_get_frames(pos, count, NULL, &pfn, &end_pfn);
if (ret == -ENXIO)
return 0; /* Reads beyond max_pfn do nothing */
@@ -211,6 +218,13 @@ static ssize_t page_idle_bitmap_write(struct file *file, struct kobject *kobj,
unsigned long pfn, end_pfn;
int bit, ret;
+ /*
+ * Idle page tracking currently works only on LRU pages, so drain
+ * them. This can cause slowness, but in the future we could
+ * remove this operation if we are tracking non-LRU pages too.
+ */
+ lru_add_drain_all();
+
ret = page_idle_get_frames(pos, count, NULL, &pfn, &end_pfn);
if (ret)
return ret;
@@ -428,6 +442,13 @@ ssize_t page_idle_proc_generic(struct file *file, char __user *ubuff,
walk.private = &priv;
walk.mm = mm;
+ /*
+ * Idle page tracking currently works only on LRU pages, so drain
+ * them. This can cause slowness, but in the future we could
+ * remove this operation if we are tracking non-LRU pages too.
+ */
+ lru_add_drain_all();
+
down_read(&mm->mmap_sem);
/*
During idle page tracking, we see that sometimes faulted anon pages are in pagevec but are not drained to LRU. Idle page tracking only considers pages on LRU. I am able to find multiple issues involving this. One issue looks like idle tracking is completely broken. It shows up in my testing as if a page that is marked as idle is always "accessed" -- because it was never marked as idle (due to not draining of pagevec). The other issue shows up as a failure during swapping (support for which this series adds), with the following sequence: 1. Allocate some pages 2. Write to them 3. Mark them as idle <--- fails 4. Introduce some memory pressure to induce swapping. 5. Check the swap bit I introduced in this series. <--- fails to set idle bit in swap PTE. To fix this, this patch drains all CPU's pagevec before starting idle tracking. Signed-off-by: Joel Fernandes (Google) <joel@joelfernandes.org> --- mm/page_idle.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)