With the page->mapping requirement gone from memcg, we can charge anon and file-thp pages in one single step, right after they're allocated. This removes two out of three API calls - especially the tricky commit step that needed to happen at just the right time between when the page is "set up" and when it's "published" - somewhat vague and fluid concepts that varied by page type. All we need is a freshly allocated page and a memcg context to charge. v2: prevent double charges on pre-allocated hugepages in khugepaged [hannes@cmpxchg.org: Fix crash - *hpage could be ERR_PTR instead of NULL] Link: http://lkml.kernel.org/r/20200512215813.GA487759@cmpxchg.org Signed-off-by: Johannes Weiner <hannes@cmpxchg.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Reviewed-by: Joonsoo Kim <iamjoonsoo.kim@lge.com> Cc: Alex Shi <alex.shi@linux.alibaba.com> Cc: Hugh Dickins <hughd@google.com> Cc: "Kirill A. Shutemov" <kirill@shutemov.name> Cc: Michal Hocko <mhocko@suse.com> Cc: Roman Gushchin <guro@fb.com> Cc: Shakeel Butt <shakeelb@google.com> Cc: Balbir Singh <bsingharora@gmail.com> Cc: Qian Cai <cai@lca.pw> Link: http://lkml.kernel.org/r/20200508183105.225460-13-hannes@cmpxchg.org Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Unified · Split
| @@ -501,7 +501,6 @@ struct vm_fault { · 500 unmodified lines | ||
| 501 | 501 | pte_t orig_pte; /* Value of PTE at the time of fault */ |
| 502 | 502 | |
| 503 | 503 | struct page *cow_page; /* Page handler may use for COW fault */ |
| 504 | − struct mem_cgroup *memcg; /* Cgroup cow_page belongs to */ | |
| 505 | 504 | struct page *page; /* ->fault handlers should return a |
| 506 | 505 | * page here, unless VM_FAULT_NOPAGE |
| 507 | 506 | * is set (which is also implied by |
| @@ -946,8 +945,7 @@ static inline pte_t maybe_mkwrite(pte_t pte, struct vm_area_struct *vma) · 438 unmodified lines | ||
| 946 | 945 | return pte; |
| 947 | 946 | } |
| 948 | 947 | |
| 949 | −vm_fault_t alloc_set_pte(struct vm_fault *vmf, struct mem_cgroup *memcg, | |
| 950 | − struct page *page); | |
| 948 | +vm_fault_t alloc_set_pte(struct vm_fault *vmf, struct page *page); | |
| 951 | 949 | vm_fault_t finish_fault(struct vm_fault *vmf); |
| 952 | 950 | vm_fault_t finish_mkwrite_fault(struct vm_fault *vmf); |
| 953 | 951 | #endif |
| @@ -162,14 +162,13 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr, · 161 unmodified lines | ||
| 162 | 162 | }; |
| 163 | 163 | int err; |
| 164 | 164 | struct mmu_notifier_range range; |
| 165 | − struct mem_cgroup *memcg; | |
| 166 | 165 | |
| 167 | 166 | mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, vma, mm, addr, |
| 168 | 167 | addr + PAGE_SIZE); |
| 169 | 168 | |
| 170 | 169 | if (new_page) { |
| 171 | − err = mem_cgroup_try_charge(new_page, vma->vm_mm, GFP_KERNEL, | |
| 172 | − &memcg); | |
| 170 | + err = mem_cgroup_charge(new_page, vma->vm_mm, GFP_KERNEL, | |
| 171 | + false); | |
| 173 | 172 | if (err) |
| 174 | 173 | return err; |
| 175 | 174 | } |
| @@ -179,16 +178,12 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr, · 3 unmodified lines | ||
| 179 | 178 | |
| 180 | 179 | mmu_notifier_invalidate_range_start(&range); |
| 181 | 180 | err = -EAGAIN; |
| 182 | − if (!page_vma_mapped_walk(&pvmw)) { | |
| 183 | − if (new_page) | |
| 184 | − mem_cgroup_cancel_charge(new_page, memcg); | |
| 181 | + if (!page_vma_mapped_walk(&pvmw)) | |
| 185 | 182 | goto unlock; |
| 186 | − } | |
| 187 | 183 | VM_BUG_ON_PAGE(addr != pvmw.address, old_page); |
| 188 | 184 | |
| 189 | 185 | if (new_page) { |
| 190 | 186 | get_page(new_page); |
| 191 | − mem_cgroup_commit_charge(new_page, memcg, false); | |
| 192 | 187 | page_add_new_anon_rmap(new_page, vma, addr, false); |
| 193 | 188 | lru_cache_add_active_or_unevictable(new_page, vma); |
| 194 | 189 | } else |
| @@ -2633,7 +2633,7 @@ void filemap_map_pages(struct vm_fault *vmf, · 2632 unmodified lines | ||
| 2633 | 2633 | if (vmf->pte) |
| 2634 | 2634 | vmf->pte += xas.xa_index - last_pgoff; |
| 2635 | 2635 | last_pgoff = xas.xa_index; |
| 2636 | − if (alloc_set_pte(vmf, NULL, page)) | |
| 2636 | + if (alloc_set_pte(vmf, page)) | |
| 2637 | 2637 | goto unlock; |
| 2638 | 2638 | unlock_page(page); |
| 2639 | 2639 | goto next; |
| @@ -587,19 +587,19 @@ static vm_fault_t __do_huge_pmd_anonymous_page(struct vm_fault *vmf, · 586 unmodified lines | ||
| 587 | 587 | struct page *page, gfp_t gfp) |
| 588 | 588 | { |
| 589 | 589 | struct vm_area_struct *vma = vmf->vma; |
| 590 | − struct mem_cgroup *memcg; | |
| 591 | 590 | pgtable_t pgtable; |
| 592 | 591 | unsigned long haddr = vmf->address & HPAGE_PMD_MASK; |
| 593 | 592 | vm_fault_t ret = 0; |
| 594 | 593 | |
| 595 | 594 | VM_BUG_ON_PAGE(!PageCompound(page), page); |
| 596 | 595 | |
| 597 | − if (mem_cgroup_try_charge_delay(page, vma->vm_mm, gfp, &memcg)) { | |
| 596 | + if (mem_cgroup_charge(page, vma->vm_mm, gfp, false)) { | |
| 598 | 597 | put_page(page); |
| 599 | 598 | count_vm_event(THP_FAULT_FALLBACK); |
| 600 | 599 | count_vm_event(THP_FAULT_FALLBACK_CHARGE); |
| 601 | 600 | return VM_FAULT_FALLBACK; |
| 602 | 601 | } |
| 602 | + cgroup_throttle_swaprate(page, gfp); | |
| 603 | 603 | |
| 604 | 604 | pgtable = pte_alloc_one(vma->vm_mm); |
| 605 | 605 | if (unlikely(!pgtable)) { |
| @@ -630,7 +630,6 @@ static vm_fault_t __do_huge_pmd_anonymous_page(struct vm_fault *vmf, · 24 unmodified lines | ||
| 630 | 630 | vm_fault_t ret2; |
| 631 | 631 | |
| 632 | 632 | spin_unlock(vmf->ptl); |
| 633 | − mem_cgroup_cancel_charge(page, memcg); | |
| 634 | 633 | put_page(page); |
| 635 | 634 | pte_free(vma->vm_mm, pgtable); |
| 636 | 635 | ret2 = handle_userfault(vmf, VM_UFFD_MISSING); |
| @@ -640,7 +639,6 @@ static vm_fault_t __do_huge_pmd_anonymous_page(struct vm_fault *vmf, · 3 unmodified lines | ||
| 640 | 639 | |
| 641 | 640 | entry = mk_huge_pmd(page, vma->vm_page_prot); |
| 642 | 641 | entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma); |
| 643 | − mem_cgroup_commit_charge(page, memcg, false); | |
| 644 | 642 | page_add_new_anon_rmap(page, vma, haddr, true); |
| 645 | 643 | lru_cache_add_active_or_unevictable(page, vma); |
| 646 | 644 | pgtable_trans_huge_deposit(vma->vm_mm, vmf->pmd, pgtable); |
| @@ -649,7 +647,7 @@ static vm_fault_t __do_huge_pmd_anonymous_page(struct vm_fault *vmf, · 2 unmodified lines | ||
| 649 | 647 | mm_inc_nr_ptes(vma->vm_mm); |
| 650 | 648 | spin_unlock(vmf->ptl); |
| 651 | 649 | count_vm_event(THP_FAULT_ALLOC); |
| 652 | − count_memcg_events(memcg, THP_FAULT_ALLOC, 1); | |
| 650 | + count_memcg_event_mm(vma->vm_mm, THP_FAULT_ALLOC); | |
| 653 | 651 | } |
| 654 | 652 | |
| 655 | 653 | return 0; |
| @@ -658,7 +656,6 @@ unlock_release: · 2 unmodified lines | ||
| 658 | 656 | release: |
| 659 | 657 | if (pgtable) |
| 660 | 658 | pte_free(vma->vm_mm, pgtable); |
| 661 | − mem_cgroup_cancel_charge(page, memcg); | |
| 662 | 659 | put_page(page); |
| 663 | 660 | return ret; |
| 664 | 661 | |
| @@ -1037,7 +1037,6 @@ static void collapse_huge_page(struct mm_struct *mm, · 1036 unmodified lines | ||
| 1037 | 1037 | struct page *new_page; |
| 1038 | 1038 | spinlock_t *pmd_ptl, *pte_ptl; |
| 1039 | 1039 | int isolated = 0, result = 0; |
| 1040 | − struct mem_cgroup *memcg; | |
| 1041 | 1040 | struct vm_area_struct *vma; |
| 1042 | 1041 | struct mmu_notifier_range range; |
| 1043 | 1042 | gfp_t gfp; |
| @@ -1060,15 +1059,15 @@ static void collapse_huge_page(struct mm_struct *mm, · 16 unmodified lines | ||
| 1060 | 1059 | goto out_nolock; |
| 1061 | 1060 | } |
| 1062 | 1061 | |
| 1063 | − if (unlikely(mem_cgroup_try_charge(new_page, mm, gfp, &memcg))) { | |
| 1062 | + if (unlikely(mem_cgroup_charge(new_page, mm, gfp, false))) { | |
| 1064 | 1063 | result = SCAN_CGROUP_CHARGE_FAIL; |
| 1065 | 1064 | goto out_nolock; |
| 1066 | 1065 | } |
| 1066 | + count_memcg_page_event(new_page, THP_COLLAPSE_ALLOC); | |
| 1067 | 1067 | |
| 1068 | 1068 | down_read(&mm->mmap_sem); |
| 1069 | 1069 | result = hugepage_vma_revalidate(mm, address, &vma); |
| 1070 | 1070 | if (result) { |
| 1071 | − mem_cgroup_cancel_charge(new_page, memcg); | |
| 1072 | 1071 | up_read(&mm->mmap_sem); |
| 1073 | 1072 | goto out_nolock; |
| 1074 | 1073 | } |
| @@ -1076,7 +1075,6 @@ static void collapse_huge_page(struct mm_struct *mm, · 1 unmodified line | ||
| 1076 | 1075 | pmd = mm_find_pmd(mm, address); |
| 1077 | 1076 | if (!pmd) { |
| 1078 | 1077 | result = SCAN_PMD_NULL; |
| 1079 | − mem_cgroup_cancel_charge(new_page, memcg); | |
| 1080 | 1078 | up_read(&mm->mmap_sem); |
| 1081 | 1079 | goto out_nolock; |
| 1082 | 1080 | } |
| @@ -1088,7 +1086,6 @@ static void collapse_huge_page(struct mm_struct *mm, · 5 unmodified lines | ||
| 1088 | 1086 | */ |
| 1089 | 1087 | if (unmapped && !__collapse_huge_page_swapin(mm, vma, address, |
| 1090 | 1088 | pmd, referenced)) { |
| 1091 | − mem_cgroup_cancel_charge(new_page, memcg); | |
| 1092 | 1089 | up_read(&mm->mmap_sem); |
| 1093 | 1090 | goto out_nolock; |
| 1094 | 1091 | } |
| @@ -1175,9 +1172,7 @@ static void collapse_huge_page(struct mm_struct *mm, · 80 unmodified lines | ||
| 1175 | 1172 | |
| 1176 | 1173 | spin_lock(pmd_ptl); |
| 1177 | 1174 | BUG_ON(!pmd_none(*pmd)); |
| 1178 | − mem_cgroup_commit_charge(new_page, memcg, false); | |
| 1179 | 1175 | page_add_new_anon_rmap(new_page, vma, address, true); |
| 1180 | − count_memcg_events(memcg, THP_COLLAPSE_ALLOC, 1); | |
| 1181 | 1176 | lru_cache_add_active_or_unevictable(new_page, vma); |
| 1182 | 1177 | pgtable_trans_huge_deposit(mm, pmd, pgtable); |
| 1183 | 1178 | set_pmd_at(mm, address, pmd, _pmd); |
| @@ -1191,10 +1186,11 @@ static void collapse_huge_page(struct mm_struct *mm, · 7 unmodified lines | ||
| 1191 | 1186 | out_up_write: |
| 1192 | 1187 | up_write(&mm->mmap_sem); |
| 1193 | 1188 | out_nolock: |
| 1189 | + if (!IS_ERR_OR_NULL(*hpage)) | |
| 1190 | + mem_cgroup_uncharge(*hpage); | |
| 1194 | 1191 | trace_mm_collapse_huge_page(mm, isolated, result); |
| 1195 | 1192 | return; |
| 1196 | 1193 | out: |
| 1197 | − mem_cgroup_cancel_charge(new_page, memcg); | |
| 1198 | 1194 | goto out_up_write; |
| 1199 | 1195 | } |
| 1200 | 1196 | |
| @@ -1618,7 +1614,6 @@ static void collapse_file(struct mm_struct *mm, · 417 unmodified lines | ||
| 1618 | 1614 | struct address_space *mapping = file->f_mapping; |
| 1619 | 1615 | gfp_t gfp; |
| 1620 | 1616 | struct page *new_page; |
| 1621 | − struct mem_cgroup *memcg; | |
| 1622 | 1617 | pgoff_t index, end = start + HPAGE_PMD_NR; |
| 1623 | 1618 | LIST_HEAD(pagelist); |
| 1624 | 1619 | XA_STATE_ORDER(xas, &mapping->i_pages, start, HPAGE_PMD_ORDER); |
| @@ -1637,10 +1632,11 @@ static void collapse_file(struct mm_struct *mm, · 12 unmodified lines | ||
| 1637 | 1632 | goto out; |
| 1638 | 1633 | } |
| 1639 | 1634 | |
| 1640 | − if (unlikely(mem_cgroup_try_charge(new_page, mm, gfp, &memcg))) { | |
| 1635 | + if (unlikely(mem_cgroup_charge(new_page, mm, gfp, false))) { | |
| 1641 | 1636 | result = SCAN_CGROUP_CHARGE_FAIL; |
| 1642 | 1637 | goto out; |
| 1643 | 1638 | } |
| 1639 | + count_memcg_page_event(new_page, THP_COLLAPSE_ALLOC); | |
| 1644 | 1640 | |
| 1645 | 1641 | /* This will be less messy when we use multi-index entries */ |
| 1646 | 1642 | do { |
| @@ -1650,7 +1646,6 @@ static void collapse_file(struct mm_struct *mm, · 3 unmodified lines | ||
| 1650 | 1646 | break; |
| 1651 | 1647 | xas_unlock_irq(&xas); |
| 1652 | 1648 | if (!xas_nomem(&xas, GFP_KERNEL)) { |
| 1653 | − mem_cgroup_cancel_charge(new_page, memcg); | |
| 1654 | 1649 | result = SCAN_FAIL; |
| 1655 | 1650 | goto out; |
| 1656 | 1651 | } |
| @@ -1844,18 +1839,9 @@ out_unlock: · 187 unmodified lines | ||
| 1844 | 1839 | } |
| 1845 | 1840 | |
| 1846 | 1841 | if (nr_none) { |
| 1847 | − struct lruvec *lruvec; | |
| 1848 | − /* | |
| 1849 | − * XXX: We have started try_charge and pinned the | |
| 1850 | − * memcg, but the page isn't committed yet so we | |
| 1851 | − * cannot use mod_lruvec_page_state(). This hackery | |
| 1852 | − * will be cleaned up when remove the page->mapping | |
| 1853 | − * dependency from memcg and fully charge above. | |
| 1854 | − */ | |
| 1855 | − lruvec = mem_cgroup_lruvec(memcg, page_pgdat(new_page)); | |
| 1856 | − __mod_lruvec_state(lruvec, NR_FILE_PAGES, nr_none); | |
| 1842 | + __mod_lruvec_page_state(new_page, NR_FILE_PAGES, nr_none); | |
| 1857 | 1843 | if (is_shmem) |
| 1858 | − __mod_lruvec_state(lruvec, NR_SHMEM, nr_none); | |
| 1844 | + __mod_lruvec_page_state(new_page, NR_SHMEM, nr_none); | |
| 1859 | 1845 | } |
| 1860 | 1846 | |
| 1861 | 1847 | xa_locked: |
| @@ -1893,7 +1879,6 @@ xa_unlocked: · 31 unmodified lines | ||
| 1893 | 1879 | |
| 1894 | 1880 | SetPageUptodate(new_page); |
| 1895 | 1881 | page_ref_add(new_page, HPAGE_PMD_NR - 1); |
| 1896 | − mem_cgroup_commit_charge(new_page, memcg, false); | |
| 1897 | 1882 | |
| 1898 | 1883 | if (is_shmem) { |
| 1899 | 1884 | set_page_dirty(new_page); |
| @@ -1901,7 +1886,6 @@ xa_unlocked: · 1 unmodified line | ||
| 1901 | 1886 | } else { |
| 1902 | 1887 | lru_cache_add_file(new_page); |
| 1903 | 1888 | } |
| 1904 | − count_memcg_events(memcg, THP_COLLAPSE_ALLOC, 1); | |
| 1905 | 1889 | |
| 1906 | 1890 | /* |
| 1907 | 1891 | * Remove pte page tables, so we can re-fault the page as huge. |
| @@ -1948,13 +1932,14 @@ xa_unlocked: · 40 unmodified lines | ||
| 1948 | 1932 | VM_BUG_ON(nr_none); |
| 1949 | 1933 | xas_unlock_irq(&xas); |
| 1950 | 1934 | |
| 1951 | − mem_cgroup_cancel_charge(new_page, memcg); | |
| 1952 | 1935 | new_page->mapping = NULL; |
| 1953 | 1936 | } |
| 1954 | 1937 | |
| 1955 | 1938 | unlock_page(new_page); |
| 1956 | 1939 | out: |
| 1957 | 1940 | VM_BUG_ON(!list_empty(&pagelist)); |
| 1941 | + if (!IS_ERR_OR_NULL(*hpage)) | |
| 1942 | + mem_cgroup_uncharge(*hpage); | |
| 1958 | 1943 | /* TODO: tracepoints */ |
| 1959 | 1944 | } |
| 1960 | 1945 | |
| @@ -2645,7 +2645,6 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf) · 2644 unmodified lines | ||
| 2645 | 2645 | struct page *new_page = NULL; |
| 2646 | 2646 | pte_t entry; |
| 2647 | 2647 | int page_copied = 0; |
| 2648 | − struct mem_cgroup *memcg; | |
| 2649 | 2648 | struct mmu_notifier_range range; |
| 2650 | 2649 | |
| 2651 | 2650 | if (unlikely(anon_vma_prepare(vma))) |
| @@ -2676,8 +2675,9 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf) · 24 unmodified lines | ||
| 2676 | 2675 | } |
| 2677 | 2676 | } |
| 2678 | 2677 | |
| 2679 | − if (mem_cgroup_try_charge_delay(new_page, mm, GFP_KERNEL, &memcg)) | |
| 2678 | + if (mem_cgroup_charge(new_page, mm, GFP_KERNEL, false)) | |
| 2680 | 2679 | goto oom_free_new; |
| 2680 | + cgroup_throttle_swaprate(new_page, GFP_KERNEL); | |
| 2681 | 2681 | |
| 2682 | 2682 | __SetPageUptodate(new_page); |
| 2683 | 2683 | |
| @@ -2710,7 +2710,6 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf) · 26 unmodified lines | ||
| 2710 | 2710 | * thread doing COW. |
| 2711 | 2711 | */ |
| 2712 | 2712 | ptep_clear_flush_notify(vma, vmf->address, vmf->pte); |
| 2713 | − mem_cgroup_commit_charge(new_page, memcg, false); | |
| 2714 | 2713 | page_add_new_anon_rmap(new_page, vma, vmf->address, false); |
| 2715 | 2714 | lru_cache_add_active_or_unevictable(new_page, vma); |
| 2716 | 2715 | /* |
| @@ -2749,8 +2748,6 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf) · 32 unmodified lines | ||
| 2749 | 2748 | /* Free the old page.. */ |
| 2750 | 2749 | new_page = old_page; |
| 2751 | 2750 | page_copied = 1; |
| 2752 | − } else { | |
| 2753 | − mem_cgroup_cancel_charge(new_page, memcg); | |
| 2754 | 2751 | } |
| 2755 | 2752 | |
| 2756 | 2753 | if (new_page) |
| @@ -3088,7 +3085,6 @@ vm_fault_t do_swap_page(struct vm_fault *vmf) · 331 unmodified lines | ||
| 3088 | 3085 | { |
| 3089 | 3086 | struct vm_area_struct *vma = vmf->vma; |
| 3090 | 3087 | struct page *page = NULL, *swapcache; |
| 3091 | − struct mem_cgroup *memcg; | |
| 3092 | 3088 | swp_entry_t entry; |
| 3093 | 3089 | pte_t pte; |
| 3094 | 3090 | int locked; |
| @@ -3193,10 +3189,11 @@ vm_fault_t do_swap_page(struct vm_fault *vmf) · 98 unmodified lines | ||
| 3193 | 3189 | goto out_page; |
| 3194 | 3190 | } |
| 3195 | 3191 | |
| 3196 | − if (mem_cgroup_try_charge_delay(page, vma->vm_mm, GFP_KERNEL, &memcg)) { | |
| 3192 | + if (mem_cgroup_charge(page, vma->vm_mm, GFP_KERNEL, true)) { | |
| 3197 | 3193 | ret = VM_FAULT_OOM; |
| 3198 | 3194 | goto out_page; |
| 3199 | 3195 | } |
| 3196 | + cgroup_throttle_swaprate(page, GFP_KERNEL); | |
| 3200 | 3197 | |
| 3201 | 3198 | /* |
| 3202 | 3199 | * Back out if somebody else already faulted in this pte. |
| @@ -3243,11 +3240,9 @@ vm_fault_t do_swap_page(struct vm_fault *vmf) · 40 unmodified lines | ||
| 3243 | 3240 | |
| 3244 | 3241 | /* ksm created a completely new copy */ |
| 3245 | 3242 | if (unlikely(page != swapcache && swapcache)) { |
| 3246 | − mem_cgroup_commit_charge(page, memcg, false); | |
| 3247 | 3243 | page_add_new_anon_rmap(page, vma, vmf->address, false); |
| 3248 | 3244 | lru_cache_add_active_or_unevictable(page, vma); |
| 3249 | 3245 | } else { |
| 3250 | − mem_cgroup_commit_charge(page, memcg, true); | |
| 3251 | 3246 | do_page_add_anon_rmap(page, vma, vmf->address, exclusive); |
| 3252 | 3247 | activate_page(page); |
| 3253 | 3248 | } |
| @@ -3284,7 +3279,6 @@ unlock: · 30 unmodified lines | ||
| 3284 | 3279 | out: |
| 3285 | 3280 | return ret; |
| 3286 | 3281 | out_nomap: |
| 3287 | − mem_cgroup_cancel_charge(page, memcg); | |
| 3288 | 3282 | pte_unmap_unlock(vmf->pte, vmf->ptl); |
| 3289 | 3283 | out_page: |
| 3290 | 3284 | unlock_page(page); |
| @@ -3305,7 +3299,6 @@ out_release: · 14 unmodified lines | ||
| 3305 | 3299 | static vm_fault_t do_anonymous_page(struct vm_fault *vmf) |
| 3306 | 3300 | { |
| 3307 | 3301 | struct vm_area_struct *vma = vmf->vma; |
| 3308 | − struct mem_cgroup *memcg; | |
| 3309 | 3302 | struct page *page; |
| 3310 | 3303 | vm_fault_t ret = 0; |
| 3311 | 3304 | pte_t entry; |
| @@ -3358,8 +3351,9 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf) · 46 unmodified lines | ||
| 3358 | 3351 | if (!page) |
| 3359 | 3352 | goto oom; |
| 3360 | 3353 | |
| 3361 | − if (mem_cgroup_try_charge_delay(page, vma->vm_mm, GFP_KERNEL, &memcg)) | |
| 3354 | + if (mem_cgroup_charge(page, vma->vm_mm, GFP_KERNEL, false)) | |
| 3362 | 3355 | goto oom_free_page; |
| 3356 | + cgroup_throttle_swaprate(page, GFP_KERNEL); | |
| 3363 | 3357 | |
| 3364 | 3358 | /* |
| 3365 | 3359 | * The memory barrier inside __SetPageUptodate makes sure that |
| @@ -3384,13 +3378,11 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf) · 18 unmodified lines | ||
| 3384 | 3378 | /* Deliver the page fault to userland, check inside PT lock */ |
| 3385 | 3379 | if (userfaultfd_missing(vma)) { |
| 3386 | 3380 | pte_unmap_unlock(vmf->pte, vmf->ptl); |
| 3387 | − mem_cgroup_cancel_charge(page, memcg); | |
| 3388 | 3381 | put_page(page); |
| 3389 | 3382 | return handle_userfault(vmf, VM_UFFD_MISSING); |
| 3390 | 3383 | } |
| 3391 | 3384 | |
| 3392 | 3385 | inc_mm_counter_fast(vma->vm_mm, MM_ANONPAGES); |
| 3393 | − mem_cgroup_commit_charge(page, memcg, false); | |
| 3394 | 3386 | page_add_new_anon_rmap(page, vma, vmf->address, false); |
| 3395 | 3387 | lru_cache_add_active_or_unevictable(page, vma); |
| 3396 | 3388 | setpte: |
| @@ -3402,7 +3394,6 @@ unlock: · 5 unmodified lines | ||
| 3402 | 3394 | pte_unmap_unlock(vmf->pte, vmf->ptl); |
| 3403 | 3395 | return ret; |
| 3404 | 3396 | release: |
| 3405 | − mem_cgroup_cancel_charge(page, memcg); | |
| 3406 | 3397 | put_page(page); |
| 3407 | 3398 | goto unlock; |
| 3408 | 3399 | oom_free_page: |
| @@ -3607,7 +3598,6 @@ static vm_fault_t do_set_pmd(struct vm_fault *vmf, struct page *page) · 198 unmodified lines | ||
| 3607 | 3598 | * mapping. If needed, the fucntion allocates page table or use pre-allocated. |
| 3608 | 3599 | * |
| 3609 | 3600 | * @vmf: fault environment |
| 3610 | − * @memcg: memcg to charge page (only for private mappings) | |
| 3611 | 3601 | * @page: page to map |
| 3612 | 3602 | * |
| 3613 | 3603 | * Caller must take care of unlocking vmf->ptl, if vmf->pte is non-NULL on |
| @@ -3618,8 +3608,7 @@ static vm_fault_t do_set_pmd(struct vm_fault *vmf, struct page *page) · 4 unmodified lines | ||
| 3618 | 3608 | * |
| 3619 | 3609 | * Return: %0 on success, %VM_FAULT_ code in case of error. |
| 3620 | 3610 | */ |
| 3621 | −vm_fault_t alloc_set_pte(struct vm_fault *vmf, struct mem_cgroup *memcg, | |
| 3622 | − struct page *page) | |
| 3611 | +vm_fault_t alloc_set_pte(struct vm_fault *vmf, struct page *page) | |
| 3623 | 3612 | { |
| 3624 | 3613 | struct vm_area_struct *vma = vmf->vma; |
| 3625 | 3614 | bool write = vmf->flags & FAULT_FLAG_WRITE; |
| @@ -3627,9 +3616,6 @@ vm_fault_t alloc_set_pte(struct vm_fault *vmf, struct mem_cgroup *memcg, · 1 unmodified line | ||
| 3627 | 3616 | vm_fault_t ret; |
| 3628 | 3617 | |
| 3629 | 3618 | if (pmd_none(*vmf->pmd) && PageTransCompound(page)) { |
| 3630 | − /* THP on COW? */ | |
| 3631 | − VM_BUG_ON_PAGE(memcg, page); | |
| 3632 | − | |
| 3633 | 3619 | ret = do_set_pmd(vmf, page); |
| 3634 | 3620 | if (ret != VM_FAULT_FALLBACK) |
| 3635 | 3621 | return ret; |
| @@ -3652,7 +3638,6 @@ vm_fault_t alloc_set_pte(struct vm_fault *vmf, struct mem_cgroup *memcg, · 16 unmodified lines | ||
| 3652 | 3638 | /* copy-on-write page */ |
| 3653 | 3639 | if (write && !(vma->vm_flags & VM_SHARED)) { |
| 3654 | 3640 | inc_mm_counter_fast(vma->vm_mm, MM_ANONPAGES); |
| 3655 | − mem_cgroup_commit_charge(page, memcg, false); | |
| 3656 | 3641 | page_add_new_anon_rmap(page, vma, vmf->address, false); |
| 3657 | 3642 | lru_cache_add_active_or_unevictable(page, vma); |
| 3658 | 3643 | } else { |
| @@ -3702,7 +3687,7 @@ vm_fault_t finish_fault(struct vm_fault *vmf) · 43 unmodified lines | ||
| 3702 | 3687 | if (!(vmf->vma->vm_flags & VM_SHARED)) |
| 3703 | 3688 | ret = check_stable_address_space(vmf->vma->vm_mm); |
| 3704 | 3689 | if (!ret) |
| 3705 | − ret = alloc_set_pte(vmf, vmf->memcg, page); | |
| 3690 | + ret = alloc_set_pte(vmf, page); | |
| 3706 | 3691 | if (vmf->pte) |
| 3707 | 3692 | pte_unmap_unlock(vmf->pte, vmf->ptl); |
| 3708 | 3693 | return ret; |
| @@ -3862,11 +3847,11 @@ static vm_fault_t do_cow_fault(struct vm_fault *vmf) · 153 unmodified lines | ||
| 3862 | 3847 | if (!vmf->cow_page) |
| 3863 | 3848 | return VM_FAULT_OOM; |
| 3864 | 3849 | |
| 3865 | − if (mem_cgroup_try_charge_delay(vmf->cow_page, vma->vm_mm, | |
| 3866 | − GFP_KERNEL, &vmf->memcg)) { | |
| 3850 | + if (mem_cgroup_charge(vmf->cow_page, vma->vm_mm, GFP_KERNEL, false)) { | |
| 3867 | 3851 | put_page(vmf->cow_page); |
| 3868 | 3852 | return VM_FAULT_OOM; |
| 3869 | 3853 | } |
| 3854 | + cgroup_throttle_swaprate(vmf->cow_page, GFP_KERNEL); | |
| 3870 | 3855 | |
| 3871 | 3856 | ret = __do_fault(vmf); |
| 3872 | 3857 | if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE | VM_FAULT_RETRY))) |
| @@ -3884,7 +3869,6 @@ static vm_fault_t do_cow_fault(struct vm_fault *vmf) · 11 unmodified lines | ||
| 3884 | 3869 | goto uncharge_out; |
| 3885 | 3870 | return ret; |
| 3886 | 3871 | uncharge_out: |
| 3887 | − mem_cgroup_cancel_charge(vmf->cow_page, vmf->memcg); | |
| 3888 | 3872 | put_page(vmf->cow_page); |
| 3889 | 3873 | return ret; |
| 3890 | 3874 | } |
| @@ -2740,7 +2740,6 @@ static void migrate_vma_insert_page(struct migrate_vma *migrate, · 2739 unmodified lines | ||
| 2740 | 2740 | { |
| 2741 | 2741 | struct vm_area_struct *vma = migrate->vma; |
| 2742 | 2742 | struct mm_struct *mm = vma->vm_mm; |
| 2743 | − struct mem_cgroup *memcg; | |
| 2744 | 2743 | bool flush = false; |
| 2745 | 2744 | spinlock_t *ptl; |
| 2746 | 2745 | pte_t entry; |
| @@ -2787,7 +2786,7 @@ static void migrate_vma_insert_page(struct migrate_vma *migrate, · 40 unmodified lines | ||
| 2787 | 2786 | |
| 2788 | 2787 | if (unlikely(anon_vma_prepare(vma))) |
| 2789 | 2788 | goto abort; |
| 2790 | − if (mem_cgroup_try_charge(page, vma->vm_mm, GFP_KERNEL, &memcg)) | |
| 2789 | + if (mem_cgroup_charge(page, vma->vm_mm, GFP_KERNEL, false)) | |
| 2791 | 2790 | goto abort; |
| 2792 | 2791 | |
| 2793 | 2792 | /* |
| @@ -2832,7 +2831,6 @@ static void migrate_vma_insert_page(struct migrate_vma *migrate, · 38 unmodified lines | ||
| 2832 | 2831 | goto unlock_abort; |
| 2833 | 2832 | |
| 2834 | 2833 | inc_mm_counter(mm, MM_ANONPAGES); |
| 2835 | − mem_cgroup_commit_charge(page, memcg, false); | |
| 2836 | 2834 | page_add_new_anon_rmap(page, vma, addr, false); |
| 2837 | 2835 | if (!is_zone_device_page(page)) |
| 2838 | 2836 | lru_cache_add_active_or_unevictable(page, vma); |
| @@ -2855,7 +2853,6 @@ static void migrate_vma_insert_page(struct migrate_vma *migrate, · 16 unmodified lines | ||
| 2855 | 2853 | |
| 2856 | 2854 | unlock_abort: |
| 2857 | 2855 | pte_unmap_unlock(ptep, ptl); |
| 2858 | − mem_cgroup_cancel_charge(page, memcg); | |
| 2859 | 2856 | abort: |
| 2860 | 2857 | *src &= ~MIGRATE_PFN_MIGRATE; |
| 2861 | 2858 | } |
| @@ -1892,7 +1892,6 @@ static int unuse_pte(struct vm_area_struct *vma, pmd_t *pmd, · 1891 unmodified lines | ||
| 1892 | 1892 | unsigned long addr, swp_entry_t entry, struct page *page) |
| 1893 | 1893 | { |
| 1894 | 1894 | struct page *swapcache; |
| 1895 | − struct mem_cgroup *memcg; | |
| 1896 | 1895 | spinlock_t *ptl; |
| 1897 | 1896 | pte_t *pte; |
| 1898 | 1897 | int ret = 1; |
| @@ -1902,14 +1901,13 @@ static int unuse_pte(struct vm_area_struct *vma, pmd_t *pmd, · 3 unmodified lines | ||
| 1902 | 1901 | if (unlikely(!page)) |
| 1903 | 1902 | return -ENOMEM; |
| 1904 | 1903 | |
| 1905 | − if (mem_cgroup_try_charge(page, vma->vm_mm, GFP_KERNEL, &memcg)) { | |
| 1904 | + if (mem_cgroup_charge(page, vma->vm_mm, GFP_KERNEL, true)) { | |
| 1906 | 1905 | ret = -ENOMEM; |
| 1907 | 1906 | goto out_nolock; |
| 1908 | 1907 | } |
| 1909 | 1908 | |
| 1910 | 1909 | pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); |
| 1911 | 1910 | if (unlikely(!pte_same_as_swp(*pte, swp_entry_to_pte(entry)))) { |
| 1912 | − mem_cgroup_cancel_charge(page, memcg); | |
| 1913 | 1911 | ret = 0; |
| 1914 | 1912 | goto out; |
| 1915 | 1913 | } |
| @@ -1920,10 +1918,8 @@ static int unuse_pte(struct vm_area_struct *vma, pmd_t *pmd, · 4 unmodified lines | ||
| 1920 | 1918 | set_pte_at(vma->vm_mm, addr, pte, |
| 1921 | 1919 | pte_mkold(mk_pte(page, vma->vm_page_prot))); |
| 1922 | 1920 | if (page == swapcache) { |
| 1923 | − mem_cgroup_commit_charge(page, memcg, true); | |
| 1924 | 1921 | page_add_anon_rmap(page, vma, addr, false); |
| 1925 | 1922 | } else { /* ksm created a completely new copy */ |
| 1926 | − mem_cgroup_commit_charge(page, memcg, false); | |
| 1927 | 1923 | page_add_new_anon_rmap(page, vma, addr, false); |
| 1928 | 1924 | lru_cache_add_active_or_unevictable(page, vma); |
| 1929 | 1925 | } |
| @@ -56,7 +56,6 @@ static int mcopy_atomic_pte(struct mm_struct *dst_mm, · 55 unmodified lines | ||
| 56 | 56 | struct page **pagep, |
| 57 | 57 | bool wp_copy) |
| 58 | 58 | { |
| 59 | − struct mem_cgroup *memcg; | |
| 60 | 59 | pte_t _dst_pte, *dst_pte; |
| 61 | 60 | spinlock_t *ptl; |
| 62 | 61 | void *page_kaddr; |
| @@ -97,7 +96,7 @@ static int mcopy_atomic_pte(struct mm_struct *dst_mm, · 34 unmodified lines | ||
| 97 | 96 | __SetPageUptodate(page); |
| 98 | 97 | |
| 99 | 98 | ret = -ENOMEM; |
| 100 | − if (mem_cgroup_try_charge(page, dst_mm, GFP_KERNEL, &memcg)) | |
| 99 | + if (mem_cgroup_charge(page, dst_mm, GFP_KERNEL, false)) | |
| 101 | 100 | goto out_release; |
| 102 | 101 | |
| 103 | 102 | _dst_pte = pte_mkdirty(mk_pte(page, dst_vma->vm_page_prot)); |
| @@ -123,7 +122,6 @@ static int mcopy_atomic_pte(struct mm_struct *dst_mm, · 19 unmodified lines | ||
| 123 | 122 | goto out_release_uncharge_unlock; |
| 124 | 123 | |
| 125 | 124 | inc_mm_counter(dst_mm, MM_ANONPAGES); |
| 126 | − mem_cgroup_commit_charge(page, memcg, false); | |
| 127 | 125 | page_add_new_anon_rmap(page, dst_vma, dst_addr, false); |
| 128 | 126 | lru_cache_add_active_or_unevictable(page, dst_vma); |
| 129 | 127 | |
| @@ -138,7 +136,6 @@ out: · 8 unmodified lines | ||
| 138 | 136 | return ret; |
| 139 | 137 | out_release_uncharge_unlock: |
| 140 | 138 | pte_unmap_unlock(dst_pte, ptl); |
| 141 | − mem_cgroup_cancel_charge(page, memcg); | |
| 142 | 139 | out_release: |
| 143 | 140 | put_page(page); |
| 144 | 141 | goto out; |