mm: madvise: MADV_DONTNEED_LOCKED
[platform/kernel/linux-starfive.git] / mm / madvise.c
index 2e62136..b41858e 100644 (file)
@@ -52,6 +52,7 @@ static int madvise_need_mmap_write(int behavior)
        case MADV_REMOVE:
        case MADV_WILLNEED:
        case MADV_DONTNEED:
+       case MADV_DONTNEED_LOCKED:
        case MADV_COLD:
        case MADV_PAGEOUT:
        case MADV_FREE:
@@ -502,14 +503,9 @@ static void madvise_cold_page_range(struct mmu_gather *tlb,
        tlb_end_vma(tlb, vma);
 }
 
-static inline bool can_madv_lru_non_huge_vma(struct vm_area_struct *vma)
-{
-       return !(vma->vm_flags & (VM_LOCKED|VM_PFNMAP));
-}
-
 static inline bool can_madv_lru_vma(struct vm_area_struct *vma)
 {
-       return can_madv_lru_non_huge_vma(vma) && !is_vm_hugetlb_page(vma);
+       return !(vma->vm_flags & (VM_LOCKED|VM_PFNMAP|VM_HUGETLB));
 }
 
 static long madvise_cold(struct vm_area_struct *vma,
@@ -787,10 +783,16 @@ static bool madvise_dontneed_free_valid_vma(struct vm_area_struct *vma,
                                            unsigned long *end,
                                            int behavior)
 {
-       if (!is_vm_hugetlb_page(vma))
-               return can_madv_lru_non_huge_vma(vma);
+       if (!is_vm_hugetlb_page(vma)) {
+               unsigned int forbidden = VM_PFNMAP;
+
+               if (behavior != MADV_DONTNEED_LOCKED)
+                       forbidden |= VM_LOCKED;
+
+               return !(vma->vm_flags & forbidden);
+       }
 
-       if (behavior != MADV_DONTNEED)
+       if (behavior != MADV_DONTNEED && behavior != MADV_DONTNEED_LOCKED)
                return false;
        if (start & ~huge_page_mask(hstate_vma(vma)))
                return false;
@@ -854,7 +856,7 @@ static long madvise_dontneed_free(struct vm_area_struct *vma,
                VM_WARN_ON(start >= end);
        }
 
-       if (behavior == MADV_DONTNEED)
+       if (behavior == MADV_DONTNEED || behavior == MADV_DONTNEED_LOCKED)
                return madvise_dontneed_single_vma(vma, start, end);
        else if (behavior == MADV_FREE)
                return madvise_free_single_vma(vma, start, end);
@@ -993,6 +995,7 @@ static int madvise_vma_behavior(struct vm_area_struct *vma,
                return madvise_pageout(vma, prev, start, end);
        case MADV_FREE:
        case MADV_DONTNEED:
+       case MADV_DONTNEED_LOCKED:
                return madvise_dontneed_free(vma, prev, start, end, behavior);
        case MADV_POPULATE_READ:
        case MADV_POPULATE_WRITE:
@@ -1123,6 +1126,7 @@ madvise_behavior_valid(int behavior)
        case MADV_REMOVE:
        case MADV_WILLNEED:
        case MADV_DONTNEED:
+       case MADV_DONTNEED_LOCKED:
        case MADV_FREE:
        case MADV_COLD:
        case MADV_PAGEOUT: