Merge tag 'char-misc-5.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[linux-2.6-microblaze.git] / mm / workingset.c
index b199726..92e6611 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <linux/memcontrol.h>
+#include <linux/mm_inline.h>
 #include <linux/writeback.h>
 #include <linux/shmem_fs.h>
 #include <linux/pagemap.h>
@@ -262,7 +263,7 @@ void *workingset_eviction(struct page *page, struct mem_cgroup *target_memcg)
        VM_BUG_ON_PAGE(!PageLocked(page), page);
 
        lruvec = mem_cgroup_lruvec(target_memcg, pgdat);
-       workingset_age_nonresident(lruvec, hpage_nr_pages(page));
+       workingset_age_nonresident(lruvec, thp_nr_pages(page));
        /* XXX: target_memcg can be NULL, go through lruvec */
        memcgid = mem_cgroup_id(lruvec_memcg(lruvec));
        eviction = atomic_long_read(&lruvec->nonresident_age);
@@ -280,6 +281,7 @@ void *workingset_eviction(struct page *page, struct mem_cgroup *target_memcg)
  */
 void workingset_refault(struct page *page, void *shadow)
 {
+       bool file = page_is_file_lru(page);
        struct mem_cgroup *eviction_memcg;
        struct lruvec *eviction_lruvec;
        unsigned long refault_distance;
@@ -346,27 +348,34 @@ void workingset_refault(struct page *page, void *shadow)
        memcg = page_memcg(page);
        lruvec = mem_cgroup_lruvec(memcg, pgdat);
 
-       inc_lruvec_state(lruvec, WORKINGSET_REFAULT);
+       inc_lruvec_state(lruvec, WORKINGSET_REFAULT_BASE + file);
 
        /*
         * Compare the distance to the existing workingset size. We
         * don't activate pages that couldn't stay resident even if
-        * all the memory was available to the page cache. Whether
-        * cache can compete with anon or not depends on having swap.
+        * all the memory was available to the workingset. Whether
+        * workingset competition needs to consider anon or not depends
+        * on having swap.
         */
        workingset_size = lruvec_page_state(eviction_lruvec, NR_ACTIVE_FILE);
-       if (mem_cgroup_get_nr_swap_pages(memcg) > 0) {
+       if (!file) {
                workingset_size += lruvec_page_state(eviction_lruvec,
-                                                    NR_INACTIVE_ANON);
+                                                    NR_INACTIVE_FILE);
+       }
+       if (mem_cgroup_get_nr_swap_pages(memcg) > 0) {
                workingset_size += lruvec_page_state(eviction_lruvec,
                                                     NR_ACTIVE_ANON);
+               if (file) {
+                       workingset_size += lruvec_page_state(eviction_lruvec,
+                                                    NR_INACTIVE_ANON);
+               }
        }
        if (refault_distance > workingset_size)
                goto out;
 
        SetPageActive(page);
-       workingset_age_nonresident(lruvec, hpage_nr_pages(page));
-       inc_lruvec_state(lruvec, WORKINGSET_ACTIVATE);
+       workingset_age_nonresident(lruvec, thp_nr_pages(page));
+       inc_lruvec_state(lruvec, WORKINGSET_ACTIVATE_BASE + file);
 
        /* Page was active prior to eviction */
        if (workingset) {
@@ -375,7 +384,7 @@ void workingset_refault(struct page *page, void *shadow)
                spin_lock_irq(&page_pgdat(page)->lru_lock);
                lru_note_cost_page(page);
                spin_unlock_irq(&page_pgdat(page)->lru_lock);
-               inc_lruvec_state(lruvec, WORKINGSET_RESTORE);
+               inc_lruvec_state(lruvec, WORKINGSET_RESTORE_BASE + file);
        }
 out:
        rcu_read_unlock();
@@ -402,7 +411,7 @@ void workingset_activation(struct page *page)
        if (!mem_cgroup_disabled() && !memcg)
                goto out;
        lruvec = mem_cgroup_page_lruvec(page, page_pgdat(page));
-       workingset_age_nonresident(lruvec, hpage_nr_pages(page));
+       workingset_age_nonresident(lruvec, thp_nr_pages(page));
 out:
        rcu_read_unlock();
 }