hugetlb.c (9bf9d47a29afbf7a43eae74a988a4aefe88ccbfd) | hugetlb.c (106c992a5ebef28193cf5958e49ceff5e4aebb04) |
---|---|
1/* 2 * Generic hugetlb support. 3 * (C) Nadia Yvette Chambers, April 2004 4 */ 5#include <linux/list.h> 6#include <linux/init.h> 7#include <linux/module.h> 8#include <linux/mm.h> --- 2233 unchanged lines hidden (view full) --- 2242}; 2243 2244static pte_t make_huge_pte(struct vm_area_struct *vma, struct page *page, 2245 int writable) 2246{ 2247 pte_t entry; 2248 2249 if (writable) { | 1/* 2 * Generic hugetlb support. 3 * (C) Nadia Yvette Chambers, April 2004 4 */ 5#include <linux/list.h> 6#include <linux/init.h> 7#include <linux/module.h> 8#include <linux/mm.h> --- 2233 unchanged lines hidden (view full) --- 2242}; 2243 2244static pte_t make_huge_pte(struct vm_area_struct *vma, struct page *page, 2245 int writable) 2246{ 2247 pte_t entry; 2248 2249 if (writable) { |
2250 entry = 2251 pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot))); | 2250 entry = huge_pte_mkwrite(huge_pte_mkdirty(mk_huge_pte(page, 2251 vma->vm_page_prot))); |
2252 } else { | 2252 } else { |
2253 entry = huge_pte_wrprotect(mk_pte(page, vma->vm_page_prot)); | 2253 entry = huge_pte_wrprotect(mk_huge_pte(page, 2254 vma->vm_page_prot)); |
2254 } 2255 entry = pte_mkyoung(entry); 2256 entry = pte_mkhuge(entry); 2257 entry = arch_make_huge_pte(entry, vma, page, writable); 2258 2259 return entry; 2260} 2261 2262static void set_huge_ptep_writable(struct vm_area_struct *vma, 2263 unsigned long address, pte_t *ptep) 2264{ 2265 pte_t entry; 2266 | 2255 } 2256 entry = pte_mkyoung(entry); 2257 entry = pte_mkhuge(entry); 2258 entry = arch_make_huge_pte(entry, vma, page, writable); 2259 2260 return entry; 2261} 2262 2263static void set_huge_ptep_writable(struct vm_area_struct *vma, 2264 unsigned long address, pte_t *ptep) 2265{ 2266 pte_t entry; 2267 |
2267 entry = pte_mkwrite(pte_mkdirty(huge_ptep_get(ptep))); | 2268 entry = huge_pte_mkwrite(huge_pte_mkdirty(huge_ptep_get(ptep))); |
2268 if (huge_ptep_set_access_flags(vma, address, ptep, entry, 1)) 2269 update_mmu_cache(vma, address, ptep); 2270} 2271 2272 2273int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, 2274 struct vm_area_struct *vma) 2275{ --- 98 unchanged lines hidden (view full) --- 2374 pte = huge_ptep_get(ptep); 2375 if (huge_pte_none(pte)) 2376 continue; 2377 2378 /* 2379 * HWPoisoned hugepage is already unmapped and dropped reference 2380 */ 2381 if (unlikely(is_hugetlb_entry_hwpoisoned(pte))) { | 2269 if (huge_ptep_set_access_flags(vma, address, ptep, entry, 1)) 2270 update_mmu_cache(vma, address, ptep); 2271} 2272 2273 2274int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, 2275 struct vm_area_struct *vma) 2276{ --- 98 unchanged lines hidden (view full) --- 2375 pte = huge_ptep_get(ptep); 2376 if (huge_pte_none(pte)) 2377 continue; 2378 2379 /* 2380 * HWPoisoned hugepage is already unmapped and dropped reference 2381 */ 2382 if (unlikely(is_hugetlb_entry_hwpoisoned(pte))) { |
2382 pte_clear(mm, address, ptep); | 2383 huge_pte_clear(mm, address, ptep); |
2383 continue; 2384 } 2385 2386 page = pte_page(pte); 2387 /* 2388 * If a reference page is supplied, it is because a specific 2389 * page is being unmapped, not a range. Ensure the page we 2390 * are about to unmap is the actual page of interest. --- 7 unchanged lines hidden (view full) --- 2398 * future faults in this VMA will fail rather than 2399 * looking like data was lost 2400 */ 2401 set_vma_resv_flags(vma, HPAGE_RESV_UNMAPPED); 2402 } 2403 2404 pte = huge_ptep_get_and_clear(mm, address, ptep); 2405 tlb_remove_tlb_entry(tlb, ptep, address); | 2384 continue; 2385 } 2386 2387 page = pte_page(pte); 2388 /* 2389 * If a reference page is supplied, it is because a specific 2390 * page is being unmapped, not a range. Ensure the page we 2391 * are about to unmap is the actual page of interest. --- 7 unchanged lines hidden (view full) --- 2399 * future faults in this VMA will fail rather than 2400 * looking like data was lost 2401 */ 2402 set_vma_resv_flags(vma, HPAGE_RESV_UNMAPPED); 2403 } 2404 2405 pte = huge_ptep_get_and_clear(mm, address, ptep); 2406 tlb_remove_tlb_entry(tlb, ptep, address); |
2406 if (pte_dirty(pte)) | 2407 if (huge_pte_dirty(pte)) |
2407 set_page_dirty(page); 2408 2409 page_remove_rmap(page); 2410 force_flush = !__tlb_remove_page(tlb, page); 2411 if (force_flush) 2412 break; 2413 /* Bail out after unmapping reference page if supplied */ 2414 if (ref_page) --- 436 unchanged lines hidden (view full) --- 2851 /* 2852 * If we are going to COW the mapping later, we examine the pending 2853 * reservations for this page now. This will ensure that any 2854 * allocations necessary to record that reservation occur outside the 2855 * spinlock. For private mappings, we also lookup the pagecache 2856 * page now as it is used to determine if a reservation has been 2857 * consumed. 2858 */ | 2408 set_page_dirty(page); 2409 2410 page_remove_rmap(page); 2411 force_flush = !__tlb_remove_page(tlb, page); 2412 if (force_flush) 2413 break; 2414 /* Bail out after unmapping reference page if supplied */ 2415 if (ref_page) --- 436 unchanged lines hidden (view full) --- 2852 /* 2853 * If we are going to COW the mapping later, we examine the pending 2854 * reservations for this page now. This will ensure that any 2855 * allocations necessary to record that reservation occur outside the 2856 * spinlock. For private mappings, we also lookup the pagecache 2857 * page now as it is used to determine if a reservation has been 2858 * consumed. 2859 */ |
2859 if ((flags & FAULT_FLAG_WRITE) && !pte_write(entry)) { | 2860 if ((flags & FAULT_FLAG_WRITE) && !huge_pte_write(entry)) { |
2860 if (vma_needs_reservation(h, vma, address) < 0) { 2861 ret = VM_FAULT_OOM; 2862 goto out_mutex; 2863 } 2864 2865 if (!(vma->vm_flags & VM_MAYSHARE)) 2866 pagecache_page = hugetlbfs_pagecache_page(h, 2867 vma, address); --- 13 unchanged lines hidden (view full) --- 2881 2882 spin_lock(&mm->page_table_lock); 2883 /* Check for a racing update before calling hugetlb_cow */ 2884 if (unlikely(!pte_same(entry, huge_ptep_get(ptep)))) 2885 goto out_page_table_lock; 2886 2887 2888 if (flags & FAULT_FLAG_WRITE) { | 2861 if (vma_needs_reservation(h, vma, address) < 0) { 2862 ret = VM_FAULT_OOM; 2863 goto out_mutex; 2864 } 2865 2866 if (!(vma->vm_flags & VM_MAYSHARE)) 2867 pagecache_page = hugetlbfs_pagecache_page(h, 2868 vma, address); --- 13 unchanged lines hidden (view full) --- 2882 2883 spin_lock(&mm->page_table_lock); 2884 /* Check for a racing update before calling hugetlb_cow */ 2885 if (unlikely(!pte_same(entry, huge_ptep_get(ptep)))) 2886 goto out_page_table_lock; 2887 2888 2889 if (flags & FAULT_FLAG_WRITE) { |
2889 if (!pte_write(entry)) { | 2890 if (!huge_pte_write(entry)) { |
2890 ret = hugetlb_cow(mm, vma, address, ptep, entry, 2891 pagecache_page); 2892 goto out_page_table_lock; 2893 } | 2891 ret = hugetlb_cow(mm, vma, address, ptep, entry, 2892 pagecache_page); 2893 goto out_page_table_lock; 2894 } |
2894 entry = pte_mkdirty(entry); | 2895 entry = huge_pte_mkdirty(entry); |
2895 } 2896 entry = pte_mkyoung(entry); 2897 if (huge_ptep_set_access_flags(vma, address, ptep, entry, 2898 flags & FAULT_FLAG_WRITE)) 2899 update_mmu_cache(vma, address, ptep); 2900 2901out_page_table_lock: 2902 spin_unlock(&mm->page_table_lock); --- 64 unchanged lines hidden (view full) --- 2967 * hwpoisoned hugepages (in which case we need to prevent the 2968 * caller from accessing to them.) In order to do this, we use 2969 * here is_swap_pte instead of is_hugetlb_entry_migration and 2970 * is_hugetlb_entry_hwpoisoned. This is because it simply covers 2971 * both cases, and because we can't follow correct pages 2972 * directly from any kind of swap entries. 2973 */ 2974 if (absent || is_swap_pte(huge_ptep_get(pte)) || | 2896 } 2897 entry = pte_mkyoung(entry); 2898 if (huge_ptep_set_access_flags(vma, address, ptep, entry, 2899 flags & FAULT_FLAG_WRITE)) 2900 update_mmu_cache(vma, address, ptep); 2901 2902out_page_table_lock: 2903 spin_unlock(&mm->page_table_lock); --- 64 unchanged lines hidden (view full) --- 2968 * hwpoisoned hugepages (in which case we need to prevent the 2969 * caller from accessing to them.) In order to do this, we use 2970 * here is_swap_pte instead of is_hugetlb_entry_migration and 2971 * is_hugetlb_entry_hwpoisoned. This is because it simply covers 2972 * both cases, and because we can't follow correct pages 2973 * directly from any kind of swap entries. 2974 */ 2975 if (absent || is_swap_pte(huge_ptep_get(pte)) || |
2975 ((flags & FOLL_WRITE) && !pte_write(huge_ptep_get(pte)))) { | 2976 ((flags & FOLL_WRITE) && 2977 !huge_pte_write(huge_ptep_get(pte)))) { |
2976 int ret; 2977 2978 spin_unlock(&mm->page_table_lock); 2979 ret = hugetlb_fault(mm, vma, vaddr, 2980 (flags & FOLL_WRITE) ? FAULT_FLAG_WRITE : 0); 2981 spin_lock(&mm->page_table_lock); 2982 if (!(ret & VM_FAULT_ERROR)) 2983 continue; --- 53 unchanged lines hidden (view full) --- 3037 if (!ptep) 3038 continue; 3039 if (huge_pmd_unshare(mm, &address, ptep)) { 3040 pages++; 3041 continue; 3042 } 3043 if (!huge_pte_none(huge_ptep_get(ptep))) { 3044 pte = huge_ptep_get_and_clear(mm, address, ptep); | 2978 int ret; 2979 2980 spin_unlock(&mm->page_table_lock); 2981 ret = hugetlb_fault(mm, vma, vaddr, 2982 (flags & FOLL_WRITE) ? FAULT_FLAG_WRITE : 0); 2983 spin_lock(&mm->page_table_lock); 2984 if (!(ret & VM_FAULT_ERROR)) 2985 continue; --- 53 unchanged lines hidden (view full) --- 3039 if (!ptep) 3040 continue; 3041 if (huge_pmd_unshare(mm, &address, ptep)) { 3042 pages++; 3043 continue; 3044 } 3045 if (!huge_pte_none(huge_ptep_get(ptep))) { 3046 pte = huge_ptep_get_and_clear(mm, address, ptep); |
3045 pte = pte_mkhuge(pte_modify(pte, newprot)); | 3047 pte = pte_mkhuge(huge_pte_modify(pte, newprot)); |
3046 pte = arch_make_huge_pte(pte, vma, NULL, 0); 3047 set_huge_pte_at(mm, address, ptep, pte); 3048 pages++; 3049 } 3050 } 3051 spin_unlock(&mm->page_table_lock); 3052 /* 3053 * Must flush TLB before releasing i_mmap_mutex: x86's huge_pmd_unshare --- 145 unchanged lines hidden --- | 3048 pte = arch_make_huge_pte(pte, vma, NULL, 0); 3049 set_huge_pte_at(mm, address, ptep, pte); 3050 pages++; 3051 } 3052 } 3053 spin_unlock(&mm->page_table_lock); 3054 /* 3055 * Must flush TLB before releasing i_mmap_mutex: x86's huge_pmd_unshare --- 145 unchanged lines hidden --- |