尘 2012-11-19 21:07 #ifdef CONFIG_FLAT_NODE_MEM_MAP /* means !SPARSEMEM */ struct page *node_mem_map;指向页结构的数组,该数组包含了节点中所有域的页 ...... #ifndef CONFIG_NO_BOOTMEM 系统启动时会启用一套临时内存管理机制,struct bootmem_data就是该机制的管理结构 struct bootmem_data *bdata; #endif ...... node_start_pfn表示节点中第一个页帧编号。页帧的编号是全局统一的,在UMA系统中只有一个节点所以node_start_pfn为0. unsigned long node_start_pfn; unsigned long node_present_pages;结点中页帧的总数 unsigned long node_spanned_pages; 结点中包括空洞在内的页帧总数 int node_id;结点的编号 wait_queue_head_t kswapd_wait;交换进程的等待队列 struct task_struct *kswapd; 指向负责该结点的交换进程的task_struct 结构 int kswapd_max_order; 由页交换子系统使用,定义要释放的区域大小。 enum zone_type classzone_idx; } pg_data_t; 1.2 内存域 系统中所有内存域类型由一个枚举结构来管理: include/linux/mmzone.h enum zone_type { #ifdef CONFIG_ZONE_DMA ZONE_DMA, 适用于DMA的内存域 #endif #ifdef CONFIG_ZONE_DMA32 使用32位寻址的适用于DMA的内存域,只有在64为系统中才与ZONE_DMA有差别 ZONE_DMA32, #endif ZONE_NORMAL,可直接映射到内核段的普通内存域 #ifdef CONFIG_HIGHMEM ZONE_HIGHMEM,超出了内核段的物理内存 #endif ZONE_MOVABLE,伪内存域,防止物理内存碎片机制中要使用该内存域 __MAX_NR_ZONES 可能有的内存域的总数 }; 内存域管理结构struct zone在文件include/linux/mmzone.h中定义,如下: struct zone { 数组watermark管理该内存域的三个水线值: WMARK_HIGH:空闲页多余该值表示内存域的状态是理想的 WMARK_LOW:空闲页低于该值,内核开始将页换出到磁盘 WMARK_MIN:空闲页低于该值,急需空闲页,内存紧张 unsigned long watermark[NR_WMARK]; 当空闲页低于该值,采取一些方法计算空闲页的总数,避免内存漂移导致水线值失效 unsigned long percpu_drift_mark; 保留一些空闲页,用于一些无论如何都不会失败的关键性分配 unsigned long lowmem_reserve[MAX_NR_ZONES]; unsigned long dirty_balance_reserve; #ifdef CONFIG_NUMA int node; 所属的NUMA节点 当可回收的页超过此值时,将进行页面回收。 unsigned long min_unmapped_pages;当 内存管理区中,用于slab的可回收页大于此值时,将回收slab中的缓存页。 unsigned long min_slab_pages; #endif 每CPU的页面缓存, 当分配单个页面时,首先从该缓存中分配页面,可提高效率 struct per_cpu_pageset __percpu *pageset; 该锁用于保护伙伴系统数据结构。即保护free_area相关数据。 spinlock_t lock; 当管理区中的所有页面都不可回收时设置此标志 int all_unreclaimable; ...... 用于实现伙伴系统。这个数组定义了11个队列,每个队列中的元素都是大小为2^n的页面块。 struct free_area free_area[MAX_ORDER]; ...... #ifdef CONFIG_COMPACTION 下面字段用于内存紧缩。 unsigned int compact_considered; unsigned int compact_defer_shift; int compact_order_failed; #endif ZONE_PADDING(_pad1_)确保后面的字段是缓存行对齐的 下面几个字段都跟页面回收相关 spinlock_t lru_lock; struct lruvec lruvec; unsigned long pages_scanned; /* since last reclaim */ unsigned long flags; /* zone flags, see below */ 该内存区域中的各种统计信息, atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS]; unsigned int inactive_ratio; ZONE_PADDING(_pad2_) 等待队列,用于等待该区域内存的进程 wait_queue_head_t * wait_table; unsigned long wait_table_hash_nr_entries; unsigned long wait_table_bits; struct pglist_data *zone_pgdat;指向该区域所属的结点 unsigned long zone_start_pfn;该区域的起始页帧号 unsigned long spanned_pages; 该区中包含空洞在内,总的页帧数 unsigned long present_pages; 总的页帧数,不包含空洞 const char *name;该区域的名字,如Normal、DMA、Highmem等 } ____cacheline_internodealigned_in_smp; 1.3 页面 系统中每个物理页面都有一个相关联的page结构用于记录该页面的状态 include/linux/mm_types.h struct page { 页面标志,也包含了一些其他信息,比如页面所处的管理区编号等 unsigned long flags; 如果最低位为0,则指向inode 的address_space,或则为NULL。如果页映射为匿名内存,最低位置位,而且该指针指向anon_vma对象 struct address_space *mapping; ...... struct { union { 表示在也表中有多少项指向该页 atomic_t _mapcount; 用于slub struct { unsigned inuse:16; unsigned objects:15; unsigned frozen:1; }; }; 页的使用计数 atomic_t _count; }; }; }; ...... union { 指向私有数据的指针,虚拟内存管理会忽略该数据。根据页的用途,可以用不同的方式使用该指针。 unsigned long private; ...... 用于SLUB分配器,指向slab的指针 struct kmem_cache *slab; 用于复合页,指向首页 struct page *first_page; }; 用于高端内存区中的页,即无法直接映射到内核内存中的页。Virtual用于存储该页的虚拟地址。 void *virtual; ...... |
|