mm: mm_event: add special kernel allocation stat
[GitHub/LineageOS/android_kernel_motorola_exynos9610.git] / mm / filemap.c
index 51aef4e992eafe93c01f69a948b2b38d79db4975..dff99a346d67b3a2dbda1b5b6b0741da76d03de4 100644 (file)
@@ -36,6 +36,8 @@
 #include <linux/memcontrol.h>
 #include <linux/cleancache.h>
 #include <linux/rmap.h>
+#include <linux/delayacct.h>
+#include <linux/psi.h>
 #include "internal.h"
 
 #define CREATE_TRACE_POINTS
@@ -817,12 +819,9 @@ int add_to_page_cache_lru(struct page *page, struct address_space *mapping,
                 * data from the working set, only to cache data that will
                 * get overwritten with something else, is a waste of memory.
                 */
-               if (!(gfp_mask & __GFP_WRITE) &&
-                   shadow && workingset_refault(shadow)) {
-                       SetPageActive(page);
-                       workingset_activation(page);
-               } else
-                       ClearPageActive(page);
+               WARN_ON_ONCE(PageActive(page));
+               if (!(gfp_mask & __GFP_WRITE) && shadow)
+                       workingset_refault(page, shadow);
                lru_cache_add(page);
        }
        return ret;
@@ -978,8 +977,18 @@ static inline int wait_on_page_bit_common(wait_queue_head_t *q,
 {
        struct wait_page_queue wait_page;
        wait_queue_entry_t *wait = &wait_page.wait;
+       bool thrashing = false;
+       unsigned long pflags;
        int ret = 0;
 
+       if (bit_nr == PG_locked &&
+           !PageUptodate(page) && PageWorkingset(page)) {
+               if (!PageSwapBacked(page))
+                       delayacct_thrashing_start();
+               psi_memstall_enter(&pflags);
+               thrashing = true;
+       }
+
        init_wait(wait);
        wait->flags = lock ? WQ_FLAG_EXCLUSIVE : 0;
        wait->func = wake_page_function;
@@ -1018,6 +1027,12 @@ static inline int wait_on_page_bit_common(wait_queue_head_t *q,
 
        finish_wait(q, wait);
 
+       if (thrashing) {
+               if (!PageSwapBacked(page))
+                       delayacct_thrashing_end();
+               psi_memstall_leave(&pflags);
+       }
+
        /*
         * A signal could leave PageWaiters set. Clearing it here if
         * !waitqueue_active would be possible (by open-coding finish_wait),