1 struct page { 2 unsigned long flags; /* Atomic flags, some possibly 3 * updated asynchronously */ 4 atomic_t _count; /* Usage count, see below. */ 5 union { 6 atomic_t _mapcount; /* Count of ptes mapped in mms, 7 * to show when page is mapped 8 * & limit reverse map searches. 9 */ 10 struct { /* SLUB */ 11 u16 inuse; 12 u16 objects; 13 }; 14 }; 15 union { 16 struct { 17 unsigned long private; /* Mapping-private opaque data: 18 * usually used for buffer_heads 19 * if PagePrivate set; used for 20 * swp_entry_t if PageSwapCache; 21 * indicates order in the buddy 22 * system if PG_buddy is set. 23 */ 24 struct address_space *mapping; /* If low bit clear, points to 25 * inode address_space, or NULL. 26 * If page mapped as anonymous 27 * memory, low bit is set, and 28 * it points to anon_vma object: 29 * see PAGE_MAPPING_ANON below. 30 */ 31 }; 32 #if USE_SPLIT_PTLOCKS 33 spinlock_t ptl; 34 #endif 35 struct kmem_cache *slab; /* SLUB: Pointer to slab */ 36 struct page *first_page; /* Compound tail pages */ 37 }; 38 union { 39 pgoff_t index; /* Our offset within mapping. */ 40 void *freelist; /* SLUB: freelist req. slab lock */ 41 }; 42 struct list_head lru; /* Pageout list, eg. active_list 43 * protected by zone->lru_lock ! 44 */ 45 /* 46 * On machines where all RAM is mapped into kernel address space, 47 * we can simply calculate the virtual address. On machines with 48 * highmem some memory is mapped into kernel virtual memory 49 * dynamically, so we need a place to store that address. 50 * Note that this field could be 16 bits on x86 ... ;) 51 * 52 * Architectures with slow multiplication can define 53 * WANT_PAGE_VIRTUAL in asm/page.h 54 */ 55 #if defined(WANT_PAGE_VIRTUAL) 56 void *virtual; /* Kernel virtual address (NULL if 57 not kmapped, ie. highmem) */ 58 #endif /* WANT_PAGE_VIRTUAL */ 59 #ifdef CONFIG_WANT_PAGE_DEBUG_FLAGS 60 unsigned long debug_flags; /* Use atomic bitops on this */ 61 #endif 62 63 #ifdef CONFIG_KMEMCHECK 64 /* 65 * kmemcheck wants to track the status of each byte in a page; this 66 * is a pointer to such a status block. NULL if not tracked. 67 */ 68 void *shadow; 69 #endif 70 }; 71 72 /* 73 * A region containing a mapping of a non-memory backed file under NOMMU 74 * conditions. These are held in a global tree and are pinned by the VMAs that 75 * map parts of them. 76 */ 77 struct vm_region { 78 struct rb_node vm_rb; /* link in global region tree */ 79 unsigned long vm_flags; /* VMA vm_flags */ 80 unsigned long vm_start; /* start address of region */ 81 unsigned long vm_end; /* region initialised to here */ 82 unsigned long vm_top; /* region allocated to here */ 83 unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */ 84 struct file *vm_file; /* the backing file or NULL */ 85 86 int vm_usage; /* region usage count (access under nommu_region_sem) */ 87 bool vm_icache_flushed : 1; /* true if the icache has been flushed for 88 * this region */ 89 };
1 unsigned long flags
1 unsigned long flags 2 //flags在page-flags.h文件夹中枚举 3 //paging_init()可设置PG_reserved做flags 4 //mem_init()可设置含PG_reserved的flags清除 5 //#define PG_reserved 11;表示页保留,无法被__free_page()回收
2 atomic_t _count和atumic_t _mapcount
1 atomic_t _count; //页引用计数器 2 atomic_t _mapcount; //页映射计数器 3 //paging_init()可以将它们初始化为-1 4 //mem_init()可以将所有位码为0的页的_count设置为0 5 //page_count和page_mapcount可以统计其实用者个数 6 //_count+1为页使用者个数,_mapcount+1为页共享者个数 7 // _count为-1时不可被__free_page()释放 8 //_mapcount为0表示该页未被共享
3 unsigned long private
1 unsigned long private; //私有数据指针 2 //设置为PG_private,则private字段指向struct buffer_head 3 //设置为PG_compound,则指向struct page 4 //设置为PG_swapcache,则private为swp_entry_t的成员变量val
4 struct address_space *mapping
1 struct address_space *mapping; //该页所在地址空间描述结构指针 2 /*page->mapping == 0 属于交换高速缓存页 3 *page->mapping != 0 且第0位为1,为匿名页,指向struct anon_vma 4 *page->mapping != 0 且第0位为0,指向struct address_space地址空间结构变量 5 */
5 pgoff_t index
pgoff_t index; //该页描述结构在地址空间radix树page_tree中的对象索引号即页号 //表示该页在vm_file中的便宜页数 //#define unsigned long pgoff_t
6 struct list_head lru
1 struct list_head lru; //最近、最久未使用struct slab结构指针变量 2 //设置PG_slab,则该页由slab分配器来管理,lru.next指向kmem_cache_t结构变量,lru.prev则指向struct slab结构
7 struct pagevec
1 struct pagevec { //页向量描述结构 2 unsigned long nr; //该页向量中的内存页数 3 unsigned long cold; //冷区标志,0表示热区,非0表示冷区 4 struct page *pages[PAGEVEC_SIZE]; 5 //该也想两种的页描述结构指针数组(PAGEVEC_SIZE=14) 6 };
8 struct page_address_map
1 struct page_address_map { //页地址映射 2 struct page *page; //页的描述结构 3 void *virtual; //页的虚拟地址 4 struct list_head list; //通过list字段链接到页表池全局链表page_address_pool中或page_address_htable[hash_ptr(page,PA_HASH_ORDER)].lh 5 };
9 struct page_address_slot
1 static struct page_address_slot { 2 struct list_head lh; /* List of page_address_maps */ 3 spinlock_t lock; /* Protect this bucket's list */ 4 } ____cacheline_aligned_in_smp page_address_htable[1<<PA_HASH_ORDER];