pg_data_t:
typedef struct pglist_data {
/*描述zone*/
struct zone node_zones[MAX_NR_ZONES];//zone 数组 一共有MAX_NR_ZONES个成员
struct zonelist node_zonelists[MAX_ZONELISTS];//zonelist 数组
int nr_zones;
/*内存节点的信息*/
unsigned long node_start_pfn;//node节点开始的页表项
unsigned long node_present_pages; /* total number of physical pages 物理页面总数*/
unsigned long node_spanned_pages; /* total size of physical page 物理页面的总的大小
range, including holes */
int node_id;//节点ID
/*页面回收相关*/
wait_queue_head_t kswapd_wait;//kswaped 等待队列
wait_queue_head_t pfmemalloc_wait;//页帧分配需要使用到的等待队列
struct task_struct *kswapd;//内存回收,任务
int kswapd_order;
enum zone_type kswapd_classzone_idx;
} pg_data_t;
zone
struct zone {
/* Read-mostly fields */
/*读敏感域*/
/* zone watermarks, access with *_wmark_pages(zone) macros */
unsigned long _watermark[NR_WMARK];//水位管理 high low mini
unsigned long watermark_boost;
unsigned long nr_reserved_highatomic;
long lowmem_reserve[MAX_NR_ZONES];
/*管理zone 常用信息*/
struct pglist_data *zone_pgdat;
struct per_cpu_pageset __percpu *pageset;
/* zone_start_pfn == zone_start_paddr >> PAGE_SHIFT */
unsigned long zone_start_pfn;
atomic_long_t managed_pages;
unsigned long spanned_pages;
unsigned long present_pages;
const char *name;
int initialized;
/* Write-intensive fields used from the page allocator */
ZONE_PADDING(_pad1_)
/* free areas of different sizes */
struct free_area free_area[MAX_ORDER];//伙伴系统需要使
/* zone flags, see below */
unsigned long flags;
/* Primarily protects free_area */
spinlock_t lock;//自旋锁
/* Write-intensive fields used by compaction and vmstats. */
ZONE_PADDING(_pad2_)//填充空白区域,让上下两端内容分配到不同的cache line里面,
unsigned long percpu_drift_mark;
ZONE_PADDING(_pad3_)
/* Zone statistics */
atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
atomic_long_t vm_numa_stat[NR_VM_NUMA_STAT_ITEMS];
} ____cacheline_internodealigned_in_smp;//zone 与L1 cache line对齐
页到页帧号
#define __page_to_pfn(page) ((unsigned long)((page) - mem_map) + ARCH_PFN_OFFSET)
页帧号(pfn page frame number )到页(page)
#define __pfn_to_page(pfn) (mem_map + ((pfn) - ARCH_PFN_OFFSET))
迁移类型
迁移类型的最小单位是pageblock!!
set_pageblock_migratetype:设置页块(pageblock)的迁移类型
void set_pageblock_migratetype(struct page *page, int migratetype)
{
if (unlikely(page_group_by_mobility_disabled &&
migratetype < MIGRATE_PCPTYPES))
migratetype = MIGRATE_UNMOVABLE;
set_pageblock_flags_group(page, (unsigned long)migratetype,
PB_migrate, PB_migrate_end);
}
get_pageblock_migratetype:获取页块(pageblock)迁移类型
#define get_pageblock_migratetype(page) \
get_pfnblock_flags_mask(page, page_to_pfn(page), \
PB_migrate_end, MIGRATETYPE_MASK)
mem_map
mem_map 存放的是struct page本身,所以需要花费大量的页来存储
创建mem_map:
static void __ref alloc_node_mem_map(struct pglist_data *pgdat)
内存初始化后的例子:
DDR是在uboot或者bios里面进行硬件的初始化的.
表示在 node 0 上面初始化了262144个页262144*4k = 1048576k = 1024M = 1G
memmap 使用的页:
虚拟地址内核布局:
内核本身使用的空间:
查看page类型信息
cat /proc/pagetypeinfo
Page block order: 9
Pages per block: 512
Free pages count per migrate type at order 0 1 2 3 4 5 6 7 8 9 10
Node 0, zone DMA32, type Unmovable 0 8 0 0 1 0 1 0 1 1 0
Node 0, zone DMA32, type Movable 11 2 2 1 1 0 0 0 4 3 97
Node 0, zone DMA32, type Reclaimable 2 10 2 2 1 1 0 0 1 1 0
Node 0, zone DMA32, type HighAtomic 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone DMA32, type CMA 1 1 1 0 1 1 0 1 1 1 15
Node 0, zone DMA32, type Isolate 0 0 0 0 0 0 0 0 0 0 0
Number of blocks type Unmovable Movable Reclaimable HighAtomic CMA Isolate
Node 0, zone DMA32 24 446 10 0 32 0