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.h141
1 files changed, 123 insertions, 18 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 1813b162b0a8..82d7024f0765 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -395,19 +395,81 @@ static inline void put_page(struct page *page)
395/* 395/*
396 * The zone field is never updated after free_area_init_core() 396 * The zone field is never updated after free_area_init_core()
397 * sets it, so none of the operations on it need to be atomic. 397 * sets it, so none of the operations on it need to be atomic.
398 * We'll have up to (MAX_NUMNODES * MAX_NR_ZONES) zones total,
399 * so we use (MAX_NODES_SHIFT + MAX_ZONES_SHIFT) here to get enough bits.
400 */ 398 */
401#define NODEZONE_SHIFT (sizeof(page_flags_t)*8 - MAX_NODES_SHIFT - MAX_ZONES_SHIFT) 399
402#define NODEZONE(node, zone) ((node << ZONES_SHIFT) | zone) 400
401/*
402 * page->flags layout:
403 *
404 * There are three possibilities for how page->flags get
405 * laid out. The first is for the normal case, without
406 * sparsemem. The second is for sparsemem when there is
407 * plenty of space for node and section. The last is when
408 * we have run out of space and have to fall back to an
409 * alternate (slower) way of determining the node.
410 *
411 * No sparsemem: | NODE | ZONE | ... | FLAGS |
412 * with space for node: | SECTION | NODE | ZONE | ... | FLAGS |
413 * no space for node: | SECTION | ZONE | ... | FLAGS |
414 */
415#ifdef CONFIG_SPARSEMEM
416#define SECTIONS_WIDTH SECTIONS_SHIFT
417#else
418#define SECTIONS_WIDTH 0
419#endif
420
421#define ZONES_WIDTH ZONES_SHIFT
422
423#if SECTIONS_WIDTH+ZONES_WIDTH+NODES_SHIFT <= FLAGS_RESERVED
424#define NODES_WIDTH NODES_SHIFT
425#else
426#define NODES_WIDTH 0
427#endif
428
429/* Page flags: | [SECTION] | [NODE] | ZONE | ... | FLAGS | */
430#define SECTIONS_PGOFF ((sizeof(page_flags_t)*8) - SECTIONS_WIDTH)
431#define NODES_PGOFF (SECTIONS_PGOFF - NODES_WIDTH)
432#define ZONES_PGOFF (NODES_PGOFF - ZONES_WIDTH)
433
434/*
435 * We are going to use the flags for the page to node mapping if its in
436 * there. This includes the case where there is no node, so it is implicit.
437 */
438#define FLAGS_HAS_NODE (NODES_WIDTH > 0 || NODES_SHIFT == 0)
439
440#ifndef PFN_SECTION_SHIFT
441#define PFN_SECTION_SHIFT 0
442#endif
443
444/*
445 * Define the bit shifts to access each section. For non-existant
446 * sections we define the shift as 0; that plus a 0 mask ensures
447 * the compiler will optimise away reference to them.
448 */
449#define SECTIONS_PGSHIFT (SECTIONS_PGOFF * (SECTIONS_WIDTH != 0))
450#define NODES_PGSHIFT (NODES_PGOFF * (NODES_WIDTH != 0))
451#define ZONES_PGSHIFT (ZONES_PGOFF * (ZONES_WIDTH != 0))
452
453/* NODE:ZONE or SECTION:ZONE is used to lookup the zone from a page. */
454#if FLAGS_HAS_NODE
455#define ZONETABLE_SHIFT (NODES_SHIFT + ZONES_SHIFT)
456#else
457#define ZONETABLE_SHIFT (SECTIONS_SHIFT + ZONES_SHIFT)
458#endif
459#define ZONETABLE_PGSHIFT ZONES_PGSHIFT
460
461#if SECTIONS_WIDTH+NODES_WIDTH+ZONES_WIDTH > FLAGS_RESERVED
462#error SECTIONS_WIDTH+NODES_WIDTH+ZONES_WIDTH > FLAGS_RESERVED
463#endif
464
465#define ZONES_MASK ((1UL << ZONES_WIDTH) - 1)
466#define NODES_MASK ((1UL << NODES_WIDTH) - 1)
467#define SECTIONS_MASK ((1UL << SECTIONS_WIDTH) - 1)
468#define ZONETABLE_MASK ((1UL << ZONETABLE_SHIFT) - 1)
403 469
404static inline unsigned long page_zonenum(struct page *page) 470static inline unsigned long page_zonenum(struct page *page)
405{ 471{
406 return (page->flags >> NODEZONE_SHIFT) & (~(~0UL << ZONES_SHIFT)); 472 return (page->flags >> ZONES_PGSHIFT) & ZONES_MASK;
407}
408static inline unsigned long page_to_nid(struct page *page)
409{
410 return (page->flags >> (NODEZONE_SHIFT + ZONES_SHIFT));
411} 473}
412 474
413struct zone; 475struct zone;
@@ -415,13 +477,44 @@ extern struct zone *zone_table[];
415 477
416static inline struct zone *page_zone(struct page *page) 478static inline struct zone *page_zone(struct page *page)
417{ 479{
418 return zone_table[page->flags >> NODEZONE_SHIFT]; 480 return zone_table[(page->flags >> ZONETABLE_PGSHIFT) &
481 ZONETABLE_MASK];
482}
483
484static inline unsigned long page_to_nid(struct page *page)
485{
486 if (FLAGS_HAS_NODE)
487 return (page->flags >> NODES_PGSHIFT) & NODES_MASK;
488 else
489 return page_zone(page)->zone_pgdat->node_id;
490}
491static inline unsigned long page_to_section(struct page *page)
492{
493 return (page->flags >> SECTIONS_PGSHIFT) & SECTIONS_MASK;
419} 494}
420 495
421static inline void set_page_zone(struct page *page, unsigned long nodezone_num) 496static inline void set_page_zone(struct page *page, unsigned long zone)
422{ 497{
423 page->flags &= ~(~0UL << NODEZONE_SHIFT); 498 page->flags &= ~(ZONES_MASK << ZONES_PGSHIFT);
424 page->flags |= nodezone_num << NODEZONE_SHIFT; 499 page->flags |= (zone & ZONES_MASK) << ZONES_PGSHIFT;
500}
501static inline void set_page_node(struct page *page, unsigned long node)
502{
503 page->flags &= ~(NODES_MASK << NODES_PGSHIFT);
504 page->flags |= (node & NODES_MASK) << NODES_PGSHIFT;
505}
506static inline void set_page_section(struct page *page, unsigned long section)
507{
508 page->flags &= ~(SECTIONS_MASK << SECTIONS_PGSHIFT);
509 page->flags |= (section & SECTIONS_MASK) << SECTIONS_PGSHIFT;
510}
511
512static inline void set_page_links(struct page *page, unsigned long zone,
513 unsigned long node, unsigned long pfn)
514{
515 set_page_zone(page, zone);
516 set_page_node(page, node);
517 set_page_section(page, pfn_to_section_nr(pfn));
425} 518}
426 519
427#ifndef CONFIG_DISCONTIGMEM 520#ifndef CONFIG_DISCONTIGMEM
@@ -532,10 +625,16 @@ static inline int page_mapped(struct page *page)
532 * Used to decide whether a process gets delivered SIGBUS or 625 * Used to decide whether a process gets delivered SIGBUS or
533 * just gets major/minor fault counters bumped up. 626 * just gets major/minor fault counters bumped up.
534 */ 627 */
535#define VM_FAULT_OOM (-1) 628#define VM_FAULT_OOM 0x00
536#define VM_FAULT_SIGBUS 0 629#define VM_FAULT_SIGBUS 0x01
537#define VM_FAULT_MINOR 1 630#define VM_FAULT_MINOR 0x02
538#define VM_FAULT_MAJOR 2 631#define VM_FAULT_MAJOR 0x03
632
633/*
634 * Special case for get_user_pages.
635 * Must be in a distinct bit from the above VM_FAULT_ flags.
636 */
637#define VM_FAULT_WRITE 0x10
539 638
540#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK) 639#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
541 640
@@ -611,7 +710,13 @@ extern pte_t *FASTCALL(pte_alloc_kernel(struct mm_struct *mm, pmd_t *pmd, unsign
611extern pte_t *FASTCALL(pte_alloc_map(struct mm_struct *mm, pmd_t *pmd, unsigned long address)); 710extern pte_t *FASTCALL(pte_alloc_map(struct mm_struct *mm, pmd_t *pmd, unsigned long address));
612extern int install_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, struct page *page, pgprot_t prot); 711extern int install_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, struct page *page, pgprot_t prot);
613extern int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, unsigned long pgoff, pgprot_t prot); 712extern int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, unsigned long pgoff, pgprot_t prot);
614extern int handle_mm_fault(struct mm_struct *mm,struct vm_area_struct *vma, unsigned long address, int write_access); 713extern int __handle_mm_fault(struct mm_struct *mm,struct vm_area_struct *vma, unsigned long address, int write_access);
714
715static inline int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, int write_access)
716{
717 return __handle_mm_fault(mm, vma, address, write_access) & (~VM_FAULT_WRITE);
718}
719
615extern int make_pages_present(unsigned long addr, unsigned long end); 720extern int make_pages_present(unsigned long addr, unsigned long end);
616extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write); 721extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
617void install_arg_page(struct vm_area_struct *, struct page *, unsigned long); 722void install_arg_page(struct vm_area_struct *, struct page *, unsigned long);