Version:  2.0.40 2.2.26 2.4.37 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10

Linux/mm/madvise.c

  1 /*
  2  *      linux/mm/madvise.c
  3  *
  4  * Copyright (C) 1999  Linus Torvalds
  5  * Copyright (C) 2002  Christoph Hellwig
  6  */
  7 
  8 #include <linux/mman.h>
  9 #include <linux/pagemap.h>
 10 #include <linux/syscalls.h>
 11 #include <linux/mempolicy.h>
 12 #include <linux/page-isolation.h>
 13 #include <linux/hugetlb.h>
 14 #include <linux/falloc.h>
 15 #include <linux/sched.h>
 16 #include <linux/ksm.h>
 17 #include <linux/fs.h>
 18 #include <linux/file.h>
 19 #include <linux/blkdev.h>
 20 #include <linux/backing-dev.h>
 21 #include <linux/swap.h>
 22 #include <linux/swapops.h>
 23 #include <linux/mmu_notifier.h>
 24 
 25 #include <asm/tlb.h>
 26 
 27 /*
 28  * Any behaviour which results in changes to the vma->vm_flags needs to
 29  * take mmap_sem for writing. Others, which simply traverse vmas, need
 30  * to only take it for reading.
 31  */
 32 static int madvise_need_mmap_write(int behavior)
 33 {
 34         switch (behavior) {
 35         case MADV_REMOVE:
 36         case MADV_WILLNEED:
 37         case MADV_DONTNEED:
 38         case MADV_FREE:
 39                 return 0;
 40         default:
 41                 /* be safe, default to 1. list exceptions explicitly */
 42                 return 1;
 43         }
 44 }
 45 
 46 /*
 47  * We can potentially split a vm area into separate
 48  * areas, each area with its own behavior.
 49  */
 50 static long madvise_behavior(struct vm_area_struct *vma,
 51                      struct vm_area_struct **prev,
 52                      unsigned long start, unsigned long end, int behavior)
 53 {
 54         struct mm_struct *mm = vma->vm_mm;
 55         int error = 0;
 56         pgoff_t pgoff;
 57         unsigned long new_flags = vma->vm_flags;
 58 
 59         switch (behavior) {
 60         case MADV_NORMAL:
 61                 new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
 62                 break;
 63         case MADV_SEQUENTIAL:
 64                 new_flags = (new_flags & ~VM_RAND_READ) | VM_SEQ_READ;
 65                 break;
 66         case MADV_RANDOM:
 67                 new_flags = (new_flags & ~VM_SEQ_READ) | VM_RAND_READ;
 68                 break;
 69         case MADV_DONTFORK:
 70                 new_flags |= VM_DONTCOPY;
 71                 break;
 72         case MADV_DOFORK:
 73                 if (vma->vm_flags & VM_IO) {
 74                         error = -EINVAL;
 75                         goto out;
 76                 }
 77                 new_flags &= ~VM_DONTCOPY;
 78                 break;
 79         case MADV_DONTDUMP:
 80                 new_flags |= VM_DONTDUMP;
 81                 break;
 82         case MADV_DODUMP:
 83                 if (new_flags & VM_SPECIAL) {
 84                         error = -EINVAL;
 85                         goto out;
 86                 }
 87                 new_flags &= ~VM_DONTDUMP;
 88                 break;
 89         case MADV_MERGEABLE:
 90         case MADV_UNMERGEABLE:
 91                 error = ksm_madvise(vma, start, end, behavior, &new_flags);
 92                 if (error)
 93                         goto out;
 94                 break;
 95         case MADV_HUGEPAGE:
 96         case MADV_NOHUGEPAGE:
 97                 error = hugepage_madvise(vma, &new_flags, behavior);
 98                 if (error)
 99                         goto out;
100                 break;
101         }
102 
103         if (new_flags == vma->vm_flags) {
104                 *prev = vma;
105                 goto out;
106         }
107 
108         pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
109         *prev = vma_merge(mm, *prev, start, end, new_flags, vma->anon_vma,
110                           vma->vm_file, pgoff, vma_policy(vma),
111                           vma->vm_userfaultfd_ctx);
112         if (*prev) {
113                 vma = *prev;
114                 goto success;
115         }
116 
117         *prev = vma;
118 
119         if (start != vma->vm_start) {
120                 error = split_vma(mm, vma, start, 1);
121                 if (error)
122                         goto out;
123         }
124 
125         if (end != vma->vm_end) {
126                 error = split_vma(mm, vma, end, 0);
127                 if (error)
128                         goto out;
129         }
130 
131 success:
132         /*
133          * vm_flags is protected by the mmap_sem held in write mode.
134          */
135         vma->vm_flags = new_flags;
136 
137 out:
138         if (error == -ENOMEM)
139                 error = -EAGAIN;
140         return error;
141 }
142 
143 #ifdef CONFIG_SWAP
144 static int swapin_walk_pmd_entry(pmd_t *pmd, unsigned long start,
145         unsigned long end, struct mm_walk *walk)
146 {
147         pte_t *orig_pte;
148         struct vm_area_struct *vma = walk->private;
149         unsigned long index;
150 
151         if (pmd_none_or_trans_huge_or_clear_bad(pmd))
152                 return 0;
153 
154         for (index = start; index != end; index += PAGE_SIZE) {
155                 pte_t pte;
156                 swp_entry_t entry;
157                 struct page *page;
158                 spinlock_t *ptl;
159 
160                 orig_pte = pte_offset_map_lock(vma->vm_mm, pmd, start, &ptl);
161                 pte = *(orig_pte + ((index - start) / PAGE_SIZE));
162                 pte_unmap_unlock(orig_pte, ptl);
163 
164                 if (pte_present(pte) || pte_none(pte))
165                         continue;
166                 entry = pte_to_swp_entry(pte);
167                 if (unlikely(non_swap_entry(entry)))
168                         continue;
169 
170                 page = read_swap_cache_async(entry, GFP_HIGHUSER_MOVABLE,
171                                                                 vma, index);
172                 if (page)
173                         put_page(page);
174         }
175 
176         return 0;
177 }
178 
179 static void force_swapin_readahead(struct vm_area_struct *vma,
180                 unsigned long start, unsigned long end)
181 {
182         struct mm_walk walk = {
183                 .mm = vma->vm_mm,
184                 .pmd_entry = swapin_walk_pmd_entry,
185                 .private = vma,
186         };
187 
188         walk_page_range(start, end, &walk);
189 
190         lru_add_drain();        /* Push any new pages onto the LRU now */
191 }
192 
193 static void force_shm_swapin_readahead(struct vm_area_struct *vma,
194                 unsigned long start, unsigned long end,
195                 struct address_space *mapping)
196 {
197         pgoff_t index;
198         struct page *page;
199         swp_entry_t swap;
200 
201         for (; start < end; start += PAGE_SIZE) {
202                 index = ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
203 
204                 page = find_get_entry(mapping, index);
205                 if (!radix_tree_exceptional_entry(page)) {
206                         if (page)
207                                 put_page(page);
208                         continue;
209                 }
210                 swap = radix_to_swp_entry(page);
211                 page = read_swap_cache_async(swap, GFP_HIGHUSER_MOVABLE,
212                                                                 NULL, 0);
213                 if (page)
214                         put_page(page);
215         }
216 
217         lru_add_drain();        /* Push any new pages onto the LRU now */
218 }
219 #endif          /* CONFIG_SWAP */
220 
221 /*
222  * Schedule all required I/O operations.  Do not wait for completion.
223  */
224 static long madvise_willneed(struct vm_area_struct *vma,
225                              struct vm_area_struct **prev,
226                              unsigned long start, unsigned long end)
227 {
228         struct file *file = vma->vm_file;
229 
230 #ifdef CONFIG_SWAP
231         if (!file) {
232                 *prev = vma;
233                 force_swapin_readahead(vma, start, end);
234                 return 0;
235         }
236 
237         if (shmem_mapping(file->f_mapping)) {
238                 *prev = vma;
239                 force_shm_swapin_readahead(vma, start, end,
240                                         file->f_mapping);
241                 return 0;
242         }
243 #else
244         if (!file)
245                 return -EBADF;
246 #endif
247 
248         if (IS_DAX(file_inode(file))) {
249                 /* no bad return value, but ignore advice */
250                 return 0;
251         }
252 
253         *prev = vma;
254         start = ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
255         if (end > vma->vm_end)
256                 end = vma->vm_end;
257         end = ((end - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
258 
259         force_page_cache_readahead(file->f_mapping, file, start, end - start);
260         return 0;
261 }
262 
263 static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr,
264                                 unsigned long end, struct mm_walk *walk)
265 
266 {
267         struct mmu_gather *tlb = walk->private;
268         struct mm_struct *mm = tlb->mm;
269         struct vm_area_struct *vma = walk->vma;
270         spinlock_t *ptl;
271         pte_t *orig_pte, *pte, ptent;
272         struct page *page;
273         int nr_swap = 0;
274         unsigned long next;
275 
276         next = pmd_addr_end(addr, end);
277         if (pmd_trans_huge(*pmd))
278                 if (madvise_free_huge_pmd(tlb, vma, pmd, addr, next))
279                         goto next;
280 
281         if (pmd_trans_unstable(pmd))
282                 return 0;
283 
284         tlb_remove_check_page_size_change(tlb, PAGE_SIZE);
285         orig_pte = pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
286         arch_enter_lazy_mmu_mode();
287         for (; addr != end; pte++, addr += PAGE_SIZE) {
288                 ptent = *pte;
289 
290                 if (pte_none(ptent))
291                         continue;
292                 /*
293                  * If the pte has swp_entry, just clear page table to
294                  * prevent swap-in which is more expensive rather than
295                  * (page allocation + zeroing).
296                  */
297                 if (!pte_present(ptent)) {
298                         swp_entry_t entry;
299 
300                         entry = pte_to_swp_entry(ptent);
301                         if (non_swap_entry(entry))
302                                 continue;
303                         nr_swap--;
304                         free_swap_and_cache(entry);
305                         pte_clear_not_present_full(mm, addr, pte, tlb->fullmm);
306                         continue;
307                 }
308 
309                 page = vm_normal_page(vma, addr, ptent);
310                 if (!page)
311                         continue;
312 
313                 /*
314                  * If pmd isn't transhuge but the page is THP and
315                  * is owned by only this process, split it and
316                  * deactivate all pages.
317                  */
318                 if (PageTransCompound(page)) {
319                         if (page_mapcount(page) != 1)
320                                 goto out;
321                         get_page(page);
322                         if (!trylock_page(page)) {
323                                 put_page(page);
324                                 goto out;
325                         }
326                         pte_unmap_unlock(orig_pte, ptl);
327                         if (split_huge_page(page)) {
328                                 unlock_page(page);
329                                 put_page(page);
330                                 pte_offset_map_lock(mm, pmd, addr, &ptl);
331                                 goto out;
332                         }
333                         put_page(page);
334                         unlock_page(page);
335                         pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
336                         pte--;
337                         addr -= PAGE_SIZE;
338                         continue;
339                 }
340 
341                 VM_BUG_ON_PAGE(PageTransCompound(page), page);
342 
343                 if (PageSwapCache(page) || PageDirty(page)) {
344                         if (!trylock_page(page))
345                                 continue;
346                         /*
347                          * If page is shared with others, we couldn't clear
348                          * PG_dirty of the page.
349                          */
350                         if (page_mapcount(page) != 1) {
351                                 unlock_page(page);
352                                 continue;
353                         }
354 
355                         if (PageSwapCache(page) && !try_to_free_swap(page)) {
356                                 unlock_page(page);
357                                 continue;
358                         }
359 
360                         ClearPageDirty(page);
361                         unlock_page(page);
362                 }
363 
364                 if (pte_young(ptent) || pte_dirty(ptent)) {
365                         /*
366                          * Some of architecture(ex, PPC) don't update TLB
367                          * with set_pte_at and tlb_remove_tlb_entry so for
368                          * the portability, remap the pte with old|clean
369                          * after pte clearing.
370                          */
371                         ptent = ptep_get_and_clear_full(mm, addr, pte,
372                                                         tlb->fullmm);
373 
374                         ptent = pte_mkold(ptent);
375                         ptent = pte_mkclean(ptent);
376                         set_pte_at(mm, addr, pte, ptent);
377                         if (PageActive(page))
378                                 deactivate_page(page);
379                         tlb_remove_tlb_entry(tlb, pte, addr);
380                 }
381         }
382 out:
383         if (nr_swap) {
384                 if (current->mm == mm)
385                         sync_mm_rss(mm);
386 
387                 add_mm_counter(mm, MM_SWAPENTS, nr_swap);
388         }
389         arch_leave_lazy_mmu_mode();
390         pte_unmap_unlock(orig_pte, ptl);
391         cond_resched();
392 next:
393         return 0;
394 }
395 
396 static void madvise_free_page_range(struct mmu_gather *tlb,
397                              struct vm_area_struct *vma,
398                              unsigned long addr, unsigned long end)
399 {
400         struct mm_walk free_walk = {
401                 .pmd_entry = madvise_free_pte_range,
402                 .mm = vma->vm_mm,
403                 .private = tlb,
404         };
405 
406         tlb_start_vma(tlb, vma);
407         walk_page_range(addr, end, &free_walk);
408         tlb_end_vma(tlb, vma);
409 }
410 
411 static int madvise_free_single_vma(struct vm_area_struct *vma,
412                         unsigned long start_addr, unsigned long end_addr)
413 {
414         unsigned long start, end;
415         struct mm_struct *mm = vma->vm_mm;
416         struct mmu_gather tlb;
417 
418         if (vma->vm_flags & (VM_LOCKED|VM_HUGETLB|VM_PFNMAP))
419                 return -EINVAL;
420 
421         /* MADV_FREE works for only anon vma at the moment */
422         if (!vma_is_anonymous(vma))
423                 return -EINVAL;
424 
425         start = max(vma->vm_start, start_addr);
426         if (start >= vma->vm_end)
427                 return -EINVAL;
428         end = min(vma->vm_end, end_addr);
429         if (end <= vma->vm_start)
430                 return -EINVAL;
431 
432         lru_add_drain();
433         tlb_gather_mmu(&tlb, mm, start, end);
434         update_hiwater_rss(mm);
435 
436         mmu_notifier_invalidate_range_start(mm, start, end);
437         madvise_free_page_range(&tlb, vma, start, end);
438         mmu_notifier_invalidate_range_end(mm, start, end);
439         tlb_finish_mmu(&tlb, start, end);
440 
441         return 0;
442 }
443 
444 static long madvise_free(struct vm_area_struct *vma,
445                              struct vm_area_struct **prev,
446                              unsigned long start, unsigned long end)
447 {
448         *prev = vma;
449         return madvise_free_single_vma(vma, start, end);
450 }
451 
452 /*
453  * Application no longer needs these pages.  If the pages are dirty,
454  * it's OK to just throw them away.  The app will be more careful about
455  * data it wants to keep.  Be sure to free swap resources too.  The
456  * zap_page_range call sets things up for shrink_active_list to actually free
457  * these pages later if no one else has touched them in the meantime,
458  * although we could add these pages to a global reuse list for
459  * shrink_active_list to pick up before reclaiming other pages.
460  *
461  * NB: This interface discards data rather than pushes it out to swap,
462  * as some implementations do.  This has performance implications for
463  * applications like large transactional databases which want to discard
464  * pages in anonymous maps after committing to backing store the data
465  * that was kept in them.  There is no reason to write this data out to
466  * the swap area if the application is discarding it.
467  *
468  * An interface that causes the system to free clean pages and flush
469  * dirty pages is already available as msync(MS_INVALIDATE).
470  */
471 static long madvise_dontneed(struct vm_area_struct *vma,
472                              struct vm_area_struct **prev,
473                              unsigned long start, unsigned long end)
474 {
475         *prev = vma;
476         if (vma->vm_flags & (VM_LOCKED|VM_HUGETLB|VM_PFNMAP))
477                 return -EINVAL;
478 
479         zap_page_range(vma, start, end - start, NULL);
480         return 0;
481 }
482 
483 /*
484  * Application wants to free up the pages and associated backing store.
485  * This is effectively punching a hole into the middle of a file.
486  */
487 static long madvise_remove(struct vm_area_struct *vma,
488                                 struct vm_area_struct **prev,
489                                 unsigned long start, unsigned long end)
490 {
491         loff_t offset;
492         int error;
493         struct file *f;
494 
495         *prev = NULL;   /* tell sys_madvise we drop mmap_sem */
496 
497         if (vma->vm_flags & VM_LOCKED)
498                 return -EINVAL;
499 
500         f = vma->vm_file;
501 
502         if (!f || !f->f_mapping || !f->f_mapping->host) {
503                         return -EINVAL;
504         }
505 
506         if ((vma->vm_flags & (VM_SHARED|VM_WRITE)) != (VM_SHARED|VM_WRITE))
507                 return -EACCES;
508 
509         offset = (loff_t)(start - vma->vm_start)
510                         + ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
511 
512         /*
513          * Filesystem's fallocate may need to take i_mutex.  We need to
514          * explicitly grab a reference because the vma (and hence the
515          * vma's reference to the file) can go away as soon as we drop
516          * mmap_sem.
517          */
518         get_file(f);
519         up_read(&current->mm->mmap_sem);
520         error = vfs_fallocate(f,
521                                 FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
522                                 offset, end - start);
523         fput(f);
524         down_read(&current->mm->mmap_sem);
525         return error;
526 }
527 
528 #ifdef CONFIG_MEMORY_FAILURE
529 /*
530  * Error injection support for memory error handling.
531  */
532 static int madvise_hwpoison(int bhv, unsigned long start, unsigned long end)
533 {
534         struct page *p;
535         if (!capable(CAP_SYS_ADMIN))
536                 return -EPERM;
537         for (; start < end; start += PAGE_SIZE <<
538                                 compound_order(compound_head(p))) {
539                 int ret;
540 
541                 ret = get_user_pages_fast(start, 1, 0, &p);
542                 if (ret != 1)
543                         return ret;
544 
545                 if (PageHWPoison(p)) {
546                         put_page(p);
547                         continue;
548                 }
549                 if (bhv == MADV_SOFT_OFFLINE) {
550                         pr_info("Soft offlining page %#lx at %#lx\n",
551                                 page_to_pfn(p), start);
552                         ret = soft_offline_page(p, MF_COUNT_INCREASED);
553                         if (ret)
554                                 return ret;
555                         continue;
556                 }
557                 pr_info("Injecting memory failure for page %#lx at %#lx\n",
558                        page_to_pfn(p), start);
559                 ret = memory_failure(page_to_pfn(p), 0, MF_COUNT_INCREASED);
560                 if (ret)
561                         return ret;
562         }
563         return 0;
564 }
565 #endif
566 
567 static long
568 madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev,
569                 unsigned long start, unsigned long end, int behavior)
570 {
571         switch (behavior) {
572         case MADV_REMOVE:
573                 return madvise_remove(vma, prev, start, end);
574         case MADV_WILLNEED:
575                 return madvise_willneed(vma, prev, start, end);
576         case MADV_FREE:
577                 /*
578                  * XXX: In this implementation, MADV_FREE works like
579                  * MADV_DONTNEED on swapless system or full swap.
580                  */
581                 if (get_nr_swap_pages() > 0)
582                         return madvise_free(vma, prev, start, end);
583                 /* passthrough */
584         case MADV_DONTNEED:
585                 return madvise_dontneed(vma, prev, start, end);
586         default:
587                 return madvise_behavior(vma, prev, start, end, behavior);
588         }
589 }
590 
591 static bool
592 madvise_behavior_valid(int behavior)
593 {
594         switch (behavior) {
595         case MADV_DOFORK:
596         case MADV_DONTFORK:
597         case MADV_NORMAL:
598         case MADV_SEQUENTIAL:
599         case MADV_RANDOM:
600         case MADV_REMOVE:
601         case MADV_WILLNEED:
602         case MADV_DONTNEED:
603         case MADV_FREE:
604 #ifdef CONFIG_KSM
605         case MADV_MERGEABLE:
606         case MADV_UNMERGEABLE:
607 #endif
608 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
609         case MADV_HUGEPAGE:
610         case MADV_NOHUGEPAGE:
611 #endif
612         case MADV_DONTDUMP:
613         case MADV_DODUMP:
614                 return true;
615 
616         default:
617                 return false;
618         }
619 }
620 
621 /*
622  * The madvise(2) system call.
623  *
624  * Applications can use madvise() to advise the kernel how it should
625  * handle paging I/O in this VM area.  The idea is to help the kernel
626  * use appropriate read-ahead and caching techniques.  The information
627  * provided is advisory only, and can be safely disregarded by the
628  * kernel without affecting the correct operation of the application.
629  *
630  * behavior values:
631  *  MADV_NORMAL - the default behavior is to read clusters.  This
632  *              results in some read-ahead and read-behind.
633  *  MADV_RANDOM - the system should read the minimum amount of data
634  *              on any access, since it is unlikely that the appli-
635  *              cation will need more than what it asks for.
636  *  MADV_SEQUENTIAL - pages in the given range will probably be accessed
637  *              once, so they can be aggressively read ahead, and
638  *              can be freed soon after they are accessed.
639  *  MADV_WILLNEED - the application is notifying the system to read
640  *              some pages ahead.
641  *  MADV_DONTNEED - the application is finished with the given range,
642  *              so the kernel can free resources associated with it.
643  *  MADV_FREE - the application marks pages in the given range as lazy free,
644  *              where actual purges are postponed until memory pressure happens.
645  *  MADV_REMOVE - the application wants to free up the given range of
646  *              pages and associated backing store.
647  *  MADV_DONTFORK - omit this area from child's address space when forking:
648  *              typically, to avoid COWing pages pinned by get_user_pages().
649  *  MADV_DOFORK - cancel MADV_DONTFORK: no longer omit this area when forking.
650  *  MADV_HWPOISON - trigger memory error handler as if the given memory range
651  *              were corrupted by unrecoverable hardware memory failure.
652  *  MADV_SOFT_OFFLINE - try to soft-offline the given range of memory.
653  *  MADV_MERGEABLE - the application recommends that KSM try to merge pages in
654  *              this area with pages of identical content from other such areas.
655  *  MADV_UNMERGEABLE- cancel MADV_MERGEABLE: no longer merge pages with others.
656  *  MADV_HUGEPAGE - the application wants to back the given range by transparent
657  *              huge pages in the future. Existing pages might be coalesced and
658  *              new pages might be allocated as THP.
659  *  MADV_NOHUGEPAGE - mark the given range as not worth being backed by
660  *              transparent huge pages so the existing pages will not be
661  *              coalesced into THP and new pages will not be allocated as THP.
662  *  MADV_DONTDUMP - the application wants to prevent pages in the given range
663  *              from being included in its core dump.
664  *  MADV_DODUMP - cancel MADV_DONTDUMP: no longer exclude from core dump.
665  *
666  * return values:
667  *  zero    - success
668  *  -EINVAL - start + len < 0, start is not page-aligned,
669  *              "behavior" is not a valid value, or application
670  *              is attempting to release locked or shared pages.
671  *  -ENOMEM - addresses in the specified range are not currently
672  *              mapped, or are outside the AS of the process.
673  *  -EIO    - an I/O error occurred while paging in data.
674  *  -EBADF  - map exists, but area maps something that isn't a file.
675  *  -EAGAIN - a kernel resource was temporarily unavailable.
676  */
677 SYSCALL_DEFINE3(madvise, unsigned long, start, size_t, len_in, int, behavior)
678 {
679         unsigned long end, tmp;
680         struct vm_area_struct *vma, *prev;
681         int unmapped_error = 0;
682         int error = -EINVAL;
683         int write;
684         size_t len;
685         struct blk_plug plug;
686 
687 #ifdef CONFIG_MEMORY_FAILURE
688         if (behavior == MADV_HWPOISON || behavior == MADV_SOFT_OFFLINE)
689                 return madvise_hwpoison(behavior, start, start+len_in);
690 #endif
691         if (!madvise_behavior_valid(behavior))
692                 return error;
693 
694         if (start & ~PAGE_MASK)
695                 return error;
696         len = (len_in + ~PAGE_MASK) & PAGE_MASK;
697 
698         /* Check to see whether len was rounded up from small -ve to zero */
699         if (len_in && !len)
700                 return error;
701 
702         end = start + len;
703         if (end < start)
704                 return error;
705 
706         error = 0;
707         if (end == start)
708                 return error;
709 
710         write = madvise_need_mmap_write(behavior);
711         if (write) {
712                 if (down_write_killable(&current->mm->mmap_sem))
713                         return -EINTR;
714         } else {
715                 down_read(&current->mm->mmap_sem);
716         }
717 
718         /*
719          * If the interval [start,end) covers some unmapped address
720          * ranges, just ignore them, but return -ENOMEM at the end.
721          * - different from the way of handling in mlock etc.
722          */
723         vma = find_vma_prev(current->mm, start, &prev);
724         if (vma && start > vma->vm_start)
725                 prev = vma;
726 
727         blk_start_plug(&plug);
728         for (;;) {
729                 /* Still start < end. */
730                 error = -ENOMEM;
731                 if (!vma)
732                         goto out;
733 
734                 /* Here start < (end|vma->vm_end). */
735                 if (start < vma->vm_start) {
736                         unmapped_error = -ENOMEM;
737                         start = vma->vm_start;
738                         if (start >= end)
739                                 goto out;
740                 }
741 
742                 /* Here vma->vm_start <= start < (end|vma->vm_end) */
743                 tmp = vma->vm_end;
744                 if (end < tmp)
745                         tmp = end;
746 
747                 /* Here vma->vm_start <= start < tmp <= (end|vma->vm_end). */
748                 error = madvise_vma(vma, &prev, start, tmp, behavior);
749                 if (error)
750                         goto out;
751                 start = tmp;
752                 if (prev && start < prev->vm_end)
753                         start = prev->vm_end;
754                 error = unmapped_error;
755                 if (start >= end)
756                         goto out;
757                 if (prev)
758                         vma = prev->vm_next;
759                 else    /* madvise_remove dropped mmap_sem */
760                         vma = find_vma(current->mm, start);
761         }
762 out:
763         blk_finish_plug(&plug);
764         if (write)
765                 up_write(&current->mm->mmap_sem);
766         else
767                 up_read(&current->mm->mmap_sem);
768 
769         return error;
770 }
771 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us