linux使用于广泛的体系结构,因此需要用一种与体系结构无关的方式来描述内存。linux用VM描述和管理内存。在VM中兽药的普遍概念就是非一致内存访问。对于大型机器而言,内存会分成许多簇,依据簇与处理器“距离”的不同,访问不同的簇会有不同的代价。 每个簇都被认为是一个节点(pg_data_t),每个节点被分成很多的成为管理区(zone)的块,用于表示内存中的某个范围。除了ZONE_DMA,ZONE_NORMAL,ZONE_HIGHMEM以外,linux2.6.32中引入了ZONE_MOVABLE,用于适应大块连续内存的分配。 每个物理页面由一个page结构体描述,所有的结构都存储在一个全局的mem_map数组中(非平板模式),该数组通常存放在ZONE_NORMAL的首部,或者就在校内存系统中为装入内核映像而预留的区域之后。 节点 内存的每个节点都有pg_data_t描述,在分配一个页面时,linux采用节点局部分配的策略,从最靠近运行中的CPU的节点分配内存。由于进程往往是在同一个CPU上运行,因此从当前节点得到的内存很可能被用到。 -
-
-
-
-
-
-
-
-
-
-
- struct bootmem_data;
- typedef struct pglist_data {
-
- struct zone node_zones[MAX_NR_ZONES];
-
- struct zonelist node_zonelists[MAX_ZONELISTS];
-
- int nr_zones;
- #ifdef CONFIG_FLAT_NODE_MEM_MAP /* means !SPARSEMEM */
-
- struct page *node_mem_map;
- #ifdef CONFIG_CGROUP_MEM_RES_CTLR
-
- struct page_cgroup *node_page_cgroup;
- #endif
- #endif
-
-
-
-
- struct bootmem_data *bdata;
- #ifdef CONFIG_MEMORY_HOTPLUG
-
-
-
-
-
-
-
-
-
-
- spinlock_t node_size_lock;
- #endif
-
-
- 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;
-
- int kswapd_max_order;
- } pg_data_t;
管理区每个管理区由一个zone结构体描述,对于管理区的类型描述如下 - enum zone_type {
- #ifdef CONFIG_ZONE_DMA
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ZONE_DMA,
- #endif
- #ifdef CONFIG_ZONE_DMA32
-
-
-
-
-
- ZONE_DMA32,
- #endif
-
-
-
-
-
- ZONE_NORMAL,
- #ifdef CONFIG_HIGHMEM
-
-
-
-
-
-
-
-
- ZONE_HIGHMEM,
- #endif
-
-
-
-
- ZONE_MOVABLE,
- __MAX_NR_ZONES
- };
里面的英文注释已经写的很详细了。管理区用于跟踪诸如页面使用情况统计数,空闲区域信息和锁信息等。
没有说明的地方,内核中的英文注释已经写得很清楚了。页面 系统中每个物理页面都有一个相关联的page用于记录该页面的状态。 -
-
-
-
-
-
-
- struct page {
- unsigned long flags;
-
- atomic_t _count;
- union {
- atomic_t _mapcount;
-
-
-
- struct {
- u16 inuse;
- u16 objects;
- };
- };
- union {
- struct {
- unsigned long private;
-
-
-
-
-
-
- struct address_space *mapping;
-
-
-
-
-
-
- };
- #if USE_SPLIT_PTLOCKS
- spinlock_t ptl;
- #endif
- struct kmem_cache *slab;
-
-
- struct page *first_page;
- };
- union {
- pgoff_t index;
- void *freelist;
- };
- struct list_head lru;
-
-
-
-
-
-
-
-
-
-
-
-
- #if defined(WANT_PAGE_VIRTUAL)
- void *virtual;
-
- #endif /* WANT_PAGE_VIRTUAL */
- #ifdef CONFIG_WANT_PAGE_DEBUG_FLAGS
- unsigned long debug_flags;
- #endif
-
- #ifdef CONFIG_KMEMCHECK
-
-
-
-
- void *shadow;
- #endif
- };
linux中主要的结构描述体现了linux物理内存管理的设计。后面会介绍linux内存管理的各个细节。
|