aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/mm.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/mm.h')
-rw-r--r--include/linux/mm.h142
1 files changed, 133 insertions, 9 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 721f451c3029..f6385fc17ad4 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -14,6 +14,7 @@
14#include <linux/mm_types.h> 14#include <linux/mm_types.h>
15#include <linux/range.h> 15#include <linux/range.h>
16#include <linux/pfn.h> 16#include <linux/pfn.h>
17#include <linux/bit_spinlock.h>
17 18
18struct mempolicy; 19struct mempolicy;
19struct anon_vma; 20struct anon_vma;
@@ -82,6 +83,7 @@ extern unsigned int kobjsize(const void *objp);
82#define VM_GROWSUP 0x00000200 83#define VM_GROWSUP 0x00000200
83#else 84#else
84#define VM_GROWSUP 0x00000000 85#define VM_GROWSUP 0x00000000
86#define VM_NOHUGEPAGE 0x00000200 /* MADV_NOHUGEPAGE marked this vma */
85#endif 87#endif
86#define VM_PFNMAP 0x00000400 /* Page-ranges managed without "struct page", just pure PFN */ 88#define VM_PFNMAP 0x00000400 /* Page-ranges managed without "struct page", just pure PFN */
87#define VM_DENYWRITE 0x00000800 /* ETXTBSY on write attempts.. */ 89#define VM_DENYWRITE 0x00000800 /* ETXTBSY on write attempts.. */
@@ -101,7 +103,11 @@ extern unsigned int kobjsize(const void *objp);
101#define VM_NORESERVE 0x00200000 /* should the VM suppress accounting */ 103#define VM_NORESERVE 0x00200000 /* should the VM suppress accounting */
102#define VM_HUGETLB 0x00400000 /* Huge TLB Page VM */ 104#define VM_HUGETLB 0x00400000 /* Huge TLB Page VM */
103#define VM_NONLINEAR 0x00800000 /* Is non-linear (remap_file_pages) */ 105#define VM_NONLINEAR 0x00800000 /* Is non-linear (remap_file_pages) */
106#ifndef CONFIG_TRANSPARENT_HUGEPAGE
104#define VM_MAPPED_COPY 0x01000000 /* T if mapped copy of data (nommu mmap) */ 107#define VM_MAPPED_COPY 0x01000000 /* T if mapped copy of data (nommu mmap) */
108#else
109#define VM_HUGEPAGE 0x01000000 /* MADV_HUGEPAGE marked this vma */
110#endif
105#define VM_INSERTPAGE 0x02000000 /* The vma has had "vm_insert_page()" done on it */ 111#define VM_INSERTPAGE 0x02000000 /* The vma has had "vm_insert_page()" done on it */
106#define VM_ALWAYSDUMP 0x04000000 /* Always include in core dumps */ 112#define VM_ALWAYSDUMP 0x04000000 /* Always include in core dumps */
107 113
@@ -242,6 +248,7 @@ struct inode;
242 * files which need it (119 of them) 248 * files which need it (119 of them)
243 */ 249 */
244#include <linux/page-flags.h> 250#include <linux/page-flags.h>
251#include <linux/huge_mm.h>
245 252
246/* 253/*
247 * Methods to modify the page usage count. 254 * Methods to modify the page usage count.
@@ -305,6 +312,39 @@ static inline int is_vmalloc_or_module_addr(const void *x)
305} 312}
306#endif 313#endif
307 314
315static inline void compound_lock(struct page *page)
316{
317#ifdef CONFIG_TRANSPARENT_HUGEPAGE
318 bit_spin_lock(PG_compound_lock, &page->flags);
319#endif
320}
321
322static inline void compound_unlock(struct page *page)
323{
324#ifdef CONFIG_TRANSPARENT_HUGEPAGE
325 bit_spin_unlock(PG_compound_lock, &page->flags);
326#endif
327}
328
329static inline unsigned long compound_lock_irqsave(struct page *page)
330{
331 unsigned long uninitialized_var(flags);
332#ifdef CONFIG_TRANSPARENT_HUGEPAGE
333 local_irq_save(flags);
334 compound_lock(page);
335#endif
336 return flags;
337}
338
339static inline void compound_unlock_irqrestore(struct page *page,
340 unsigned long flags)
341{
342#ifdef CONFIG_TRANSPARENT_HUGEPAGE
343 compound_unlock(page);
344 local_irq_restore(flags);
345#endif
346}
347
308static inline struct page *compound_head(struct page *page) 348static inline struct page *compound_head(struct page *page)
309{ 349{
310 if (unlikely(PageTail(page))) 350 if (unlikely(PageTail(page)))
@@ -319,9 +359,29 @@ static inline int page_count(struct page *page)
319 359
320static inline void get_page(struct page *page) 360static inline void get_page(struct page *page)
321{ 361{
322 page = compound_head(page); 362 /*
323 VM_BUG_ON(atomic_read(&page->_count) == 0); 363 * Getting a normal page or the head of a compound page
364 * requires to already have an elevated page->_count. Only if
365 * we're getting a tail page, the elevated page->_count is
366 * required only in the head page, so for tail pages the
367 * bugcheck only verifies that the page->_count isn't
368 * negative.
369 */
370 VM_BUG_ON(atomic_read(&page->_count) < !PageTail(page));
324 atomic_inc(&page->_count); 371 atomic_inc(&page->_count);
372 /*
373 * Getting a tail page will elevate both the head and tail
374 * page->_count(s).
375 */
376 if (unlikely(PageTail(page))) {
377 /*
378 * This is safe only because
379 * __split_huge_page_refcount can't run under
380 * get_page().
381 */
382 VM_BUG_ON(atomic_read(&page->first_page->_count) <= 0);
383 atomic_inc(&page->first_page->_count);
384 }
325} 385}
326 386
327static inline struct page *virt_to_head_page(const void *x) 387static inline struct page *virt_to_head_page(const void *x)
@@ -339,6 +399,27 @@ static inline void init_page_count(struct page *page)
339 atomic_set(&page->_count, 1); 399 atomic_set(&page->_count, 1);
340} 400}
341 401
402/*
403 * PageBuddy() indicate that the page is free and in the buddy system
404 * (see mm/page_alloc.c).
405 */
406static inline int PageBuddy(struct page *page)
407{
408 return atomic_read(&page->_mapcount) == -2;
409}
410
411static inline void __SetPageBuddy(struct page *page)
412{
413 VM_BUG_ON(atomic_read(&page->_mapcount) != -1);
414 atomic_set(&page->_mapcount, -2);
415}
416
417static inline void __ClearPageBuddy(struct page *page)
418{
419 VM_BUG_ON(!PageBuddy(page));
420 atomic_set(&page->_mapcount, -1);
421}
422
342void put_page(struct page *page); 423void put_page(struct page *page);
343void put_pages_list(struct list_head *pages); 424void put_pages_list(struct list_head *pages);
344 425
@@ -370,11 +451,40 @@ static inline int compound_order(struct page *page)
370 return (unsigned long)page[1].lru.prev; 451 return (unsigned long)page[1].lru.prev;
371} 452}
372 453
454static inline int compound_trans_order(struct page *page)
455{
456 int order;
457 unsigned long flags;
458
459 if (!PageHead(page))
460 return 0;
461
462 flags = compound_lock_irqsave(page);
463 order = compound_order(page);
464 compound_unlock_irqrestore(page, flags);
465 return order;
466}
467
373static inline void set_compound_order(struct page *page, unsigned long order) 468static inline void set_compound_order(struct page *page, unsigned long order)
374{ 469{
375 page[1].lru.prev = (void *)order; 470 page[1].lru.prev = (void *)order;
376} 471}
377 472
473#ifdef CONFIG_MMU
474/*
475 * Do pte_mkwrite, but only if the vma says VM_WRITE. We do this when
476 * servicing faults for write access. In the normal case, do always want
477 * pte_mkwrite. But get_user_pages can cause write faults for mappings
478 * that do not have writing enabled, when used by access_process_vm.
479 */
480static inline pte_t maybe_mkwrite(pte_t pte, struct vm_area_struct *vma)
481{
482 if (likely(vma->vm_flags & VM_WRITE))
483 pte = pte_mkwrite(pte);
484 return pte;
485}
486#endif
487
378/* 488/*
379 * Multiple processes may "see" the same page. E.g. for untouched 489 * Multiple processes may "see" the same page. E.g. for untouched
380 * mappings of /dev/null, all processes see the same page full of 490 * mappings of /dev/null, all processes see the same page full of
@@ -657,7 +767,7 @@ static inline struct address_space *page_mapping(struct page *page)
657 VM_BUG_ON(PageSlab(page)); 767 VM_BUG_ON(PageSlab(page));
658 if (unlikely(PageSwapCache(page))) 768 if (unlikely(PageSwapCache(page)))
659 mapping = &swapper_space; 769 mapping = &swapper_space;
660 else if (unlikely((unsigned long)mapping & PAGE_MAPPING_ANON)) 770 else if ((unsigned long)mapping & PAGE_MAPPING_ANON)
661 mapping = NULL; 771 mapping = NULL;
662 return mapping; 772 return mapping;
663} 773}
@@ -1064,7 +1174,8 @@ static inline int __pmd_alloc(struct mm_struct *mm, pud_t *pud,
1064int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address); 1174int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address);
1065#endif 1175#endif
1066 1176
1067int __pte_alloc(struct mm_struct *mm, pmd_t *pmd, unsigned long address); 1177int __pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
1178 pmd_t *pmd, unsigned long address);
1068int __pte_alloc_kernel(pmd_t *pmd, unsigned long address); 1179int __pte_alloc_kernel(pmd_t *pmd, unsigned long address);
1069 1180
1070/* 1181/*
@@ -1133,16 +1244,18 @@ static inline void pgtable_page_dtor(struct page *page)
1133 pte_unmap(pte); \ 1244 pte_unmap(pte); \
1134} while (0) 1245} while (0)
1135 1246
1136#define pte_alloc_map(mm, pmd, address) \ 1247#define pte_alloc_map(mm, vma, pmd, address) \
1137 ((unlikely(!pmd_present(*(pmd))) && __pte_alloc(mm, pmd, address))? \ 1248 ((unlikely(pmd_none(*(pmd))) && __pte_alloc(mm, vma, \
1138 NULL: pte_offset_map(pmd, address)) 1249 pmd, address))? \
1250 NULL: pte_offset_map(pmd, address))
1139 1251
1140#define pte_alloc_map_lock(mm, pmd, address, ptlp) \ 1252#define pte_alloc_map_lock(mm, pmd, address, ptlp) \
1141 ((unlikely(!pmd_present(*(pmd))) && __pte_alloc(mm, pmd, address))? \ 1253 ((unlikely(pmd_none(*(pmd))) && __pte_alloc(mm, NULL, \
1254 pmd, address))? \
1142 NULL: pte_offset_map_lock(mm, pmd, address, ptlp)) 1255 NULL: pte_offset_map_lock(mm, pmd, address, ptlp))
1143 1256
1144#define pte_alloc_kernel(pmd, address) \ 1257#define pte_alloc_kernel(pmd, address) \
1145 ((unlikely(!pmd_present(*(pmd))) && __pte_alloc_kernel(pmd, address))? \ 1258 ((unlikely(pmd_none(*(pmd))) && __pte_alloc_kernel(pmd, address))? \
1146 NULL: pte_offset_kernel(pmd, address)) 1259 NULL: pte_offset_kernel(pmd, address))
1147 1260
1148extern void free_area_init(unsigned long * zones_size); 1261extern void free_area_init(unsigned long * zones_size);
@@ -1415,6 +1528,8 @@ struct page *follow_page(struct vm_area_struct *, unsigned long address,
1415#define FOLL_GET 0x04 /* do get_page on page */ 1528#define FOLL_GET 0x04 /* do get_page on page */
1416#define FOLL_DUMP 0x08 /* give error on hole if it would be zero */ 1529#define FOLL_DUMP 0x08 /* give error on hole if it would be zero */
1417#define FOLL_FORCE 0x10 /* get_user_pages read/write w/o permission */ 1530#define FOLL_FORCE 0x10 /* get_user_pages read/write w/o permission */
1531#define FOLL_MLOCK 0x40 /* mark page as mlocked */
1532#define FOLL_SPLIT 0x80 /* don't return transhuge pages, split them */
1418 1533
1419typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr, 1534typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr,
1420 void *data); 1535 void *data);
@@ -1518,5 +1633,14 @@ static inline int is_hwpoison_address(unsigned long addr)
1518 1633
1519extern void dump_page(struct page *page); 1634extern void dump_page(struct page *page);
1520 1635
1636#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_HUGETLBFS)
1637extern void clear_huge_page(struct page *page,
1638 unsigned long addr,
1639 unsigned int pages_per_huge_page);
1640extern void copy_user_huge_page(struct page *dst, struct page *src,
1641 unsigned long addr, struct vm_area_struct *vma,
1642 unsigned int pages_per_huge_page);
1643#endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLBFS */
1644
1521#endif /* __KERNEL__ */ 1645#endif /* __KERNEL__ */
1522#endif /* _LINUX_MM_H */ 1646#endif /* _LINUX_MM_H */