内存管理-5-物理内存数据结构-1-struct pglist_data

基于msm-5.4

一、概述

物理内存组织关系如下图。非服务器的设备,一般只有一个内存node节点,使用 pglst_data 结构描述;一个内存节点下有较多分区,使用 zone 结构描述;每个分区中有不同大小的空闲内存块,通过 free_area 结构进行描述;物理内存管理的最小单位使用 page 结构进行描述。

 物理内存管理主要分两部分,一是权限管理,另外就是将其分成大小相同的内存块,叫做物理页(Frame Page),使用 struct page 表示。分区 struct zone 表示。

 

二、struct pglist_data

1. 简介

表示一个node里面的内存资源。在 NUMA 机器上,每个 NUMA 节点都会有一个 pg_data_t 来描述其内存布局。在 UMA 机器上,只有一个 pglist_data 来描述整个内存。 内存统计信息和页面替换数据结构按区域(zone)进行维护。

初始化函数:zone_sizes_init() 其调用路径:

start_kernel //main.c
    setup_arch //setup.c
        bootmem_init //init.c
            zone_sizes_init
            memblock_dump_all //dump所有的memory和reserved内存区间

2. 成员介绍

//include/linux/mmzone.h
typedef struct pglist_data {
    struct zone node_zones[MAX_NR_ZONES];
    struct zonelist node_zonelists[MAX_ZONELISTS];
    int nr_zones;
    spinlock_t node_size_lock;
    unsigned long node_start_pfn;
    unsigned long node_present_pages;
    unsigned long node_spanned_pages;
    int node_id;
    wait_queue_head_t kswapd_wait;
    wait_queue_head_t pfmemalloc_wait;
    struct task_struct *kswapd;
    struct task_struct *mkswapd[MAX_KSWAPD_THREADS]; //16
    int kswapd_order;
    enum zone_type kswapd_classzone_idx;
    int kswapd_failures;

    int kcompactd_max_order;
    enum zone_type kcompactd_classzone_idx;
    wait_queue_head_t kcompactd_wait;
    struct task_struct *kcompactd;

    unsigned long        totalreserve_pages;
    ZONE_PADDING(_pad1_) //cache line aligned,size=0
    spinlock_t        lru_lock;
    struct deferred_split deferred_split_queue;
    struct lruvec        lruvec;
    unsigned long        flags;

    ZONE_PADDING(_pad2_) //cache line aligned,size=0
    struct per_cpu_nodestat __percpu *per_cpu_nodestats;
    atomic_long_t        vm_stat[NR_VM_NODE_STAT_ITEMS];
} pg_data_t;

node_zones[]: 此node的zone描述,在 calculate_node_totalpages() 中初始化。

node_zonelists[]: 里面只有一个元素,在 build_zonelists() 中进行初始化。

node_start_pfn: 物理内存的最小页帧号, 在 free_area_init_node() 中赋值。

node_present_pages: node物理页的总个数,不包括hole, 在 calculate_node_totalpages() 中赋值。

node_spanned_pages: node跨越物理页面范围的总个数,包括空洞,在 calculate_node_totalpages() 中赋值。

node_id: 嵌入式中只有一个node, 这个node_id是0,在 free_area_init_node() 中赋值。

mkswapd[]: 显示最大可以有16个kswapd线程,被 mem_hotplug_begin/end() 保护。

kswapd_failures: 'reclaimed == 0'运行次数。

totalreserve_pages: 每个节点保留的页面数,不可用于用户空间分配。

_pad1_: 页面回收使用的写密集型字段

lruvec: 页面回收扫描器经常访问的字段

per_cpu_nodestats: 每node的vmstats,在 free_area_init_core() 中指向全局 boot_nodestats, 定义在 page_alloc.c 中, 是个数组,有 NR_VM_NODE_STAT_ITEMS 个元素,每个CPU都有这么多个元素

vm_stat: 统计信息

 

 

 

posted on 2024-06-18 21:41  Hello-World3  阅读(278)  评论(0)    收藏  举报

导航