博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
物理内存相关的三个数据结构
阅读量:7066 次
发布时间:2019-06-28

本文共 5231 字,大约阅读时间需要 17 分钟。

物理内存相关的三个数据结构

基于linux-4.9介绍linux内存管理中跟物理内存相关的三个数据结构pglist_data、zone、page。

pg_data_t

typedef struct pglist_data {    /* 跟zone相关的成员 */    struct zone node_zones[MAX_NR_ZONES];    struct zonelist node_zonelists[MAX_ZONELISTS];    int nr_zones;    /* 内存节点的信息 */    unsigned long node_start_pfn;     //内存节点起始的页帧号    unsigned long node_present_pages; //总共的物理页面数    unsigned long node_spanned_pages; //总共的物理地址所占的页面数,包括内存空洞    /* 内存回收相关的数据结构 */    wait_queue_head_t kswapd_wait;      wait_queue_head_t pfmemalloc_wait;    struct task_struct *kswapd;       //内存回收专门的线程kswapd    int kswapd_order;     enum zone_type kswapd_classzone_idx; }pg_data_t;

zone

[include/linux/mmzone.h]struct zone {    /* zone的水位,用来内存回收时使用 */    unsigned long watermark[NR_WMARK];    /* 记录紧急内存的大小 */    unsigned long nr_reserved_highatomic;    /* 每一个zone的最少保留内存,比如来自high zone     * 的内存分配时,如果high zone空闲内存不够用,     * 这个时候就会到normal zone取内存,     * 而这个lowmem_reserve的意义就是为了,     * 让high zone在normal zone取内存时不能无限制的取,     * 最少要保留一些给normal zone。     */    long lowmem_reserve[MAX_NR_ZONES];     /* 其所在的pglist_data */    struct pglist_data      *zone_pgdat;    /* 每一个cpu都维护一个page列表用来提高速度 */    struct per_cpu_pageset __percpu *pageset;    /* 第一个页的索引 */    unsigned long           zone_start_pfn;    /* spanned_pages 是这个zone跨越的所有物理内存的page数目     * 包括内存空洞,它的计算方式:     *  spanned_pages = zone_end_pfn - zone_start_pfn     */    unsigned long           spanned_pages;    /* present_pages 是这个zone在物理内存真实存在的所有page数目,     * 它的计算方式:     *  present_pages = spanned_pages - absent_pages     *  其中absent_pages指的是内存空洞的page数目     */    unsigned long           present_pages;    /* managed_pages 是这个zone被Buddy管理的所有的page数目,     * 计算的方式:     *  managed_pages = present_pages - reserved_pages     * 其中reserved_pages包括被Bootmem分配走的内存     */    unsigned long           managed_pages;    /* 这个zone的名字 */    const char              *name;    /* ZONE_PADDING是为了cache line对齐,用空间换时间。     * 防止cache line 中有多个不同的数据结构而同时影响多个     * cpu     */    ZONE_PADDING(_pad1_)    /* 包含所有的空闲页面的列表 */    struct free_area        free_area[MAX_ORDER];    /* zone flags, see below */    unsigned long           flags;    /* 用来保护free_area的锁 */    spinlock_t              lock;    ZONE_PADDING(_pad2_)    /* 内存规整和CMA相关的成员 */    #if defined CONFIG_COMPACTION || defined CONFIG_CMA            unsigned long           compact_cached_free_pfn;            unsigned long           compact_cached_migrate_pfn[2];    #endif    #ifdef CONFIG_COMPACTION            unsigned int            compact_considered;            unsigned int            compact_defer_shift;            int                     compact_order_failed;    #endif    #if defined CONFIG_COMPACTION || defined CONFIG_CMA            bool                    compact_blockskip_flush;    #endif    ZONE_PADDING(_pad3_)    /* zone统计信息 */    atomic_long_t           vm_stat[NR_VM_ZONE_STAT_ITEMS];}____cacheline_internodealigned_in_smp;

zone中的一些成员的作用

包含所有空闲页面的free_area数组

[include/linux/mmzone.h]struct free_area {    struct list_head free_list[MIGRATE_TYPES];    unsigned long    nr_free;};

MIGRATE_TYPES的定义如下:

enum migratetype {        MIGRATE_UNMOVABLE,   //不可迁移        MIGRATE_MOVABLE,     //可迁移        MIGRATE_RECLAIMABLE, //可被回收        MIGRATE_PCPTYPES,    //跟per_cpu_pageset有关的迁移类型的个数        MIGRATE_HIGHATOMIC = MIGRATE_PCPTYPES,#ifdef CONFIG_CMA        MIGRATE_CMA,#endif#ifdef CONFIG_MEMORY_ISOLATION        MIGRATE_ISOLATE,#endif        MIGRATE_TYPES};

migratetype定义了一个page的迁移类型。free_area为每一个迁移类型都单独设一个链表,以方便维护。

所以free_area这个数组包含了这个zone的所有空闲页面,并按照不通的迁移类型把这些页面放在不通的链表中方便管理。

每一个core维护的本地页链表per_cpu_pageset

struct per_cpu_pageset {        struct per_cpu_pages pcp;#ifdef CONFIG_NUMA        s8 expire;        u16 vm_numa_stat_diff[NR_VM_NUMA_STAT_ITEMS];#endif#ifdef CONFIG_SMP        s8 stat_threshold;        s8 vm_stat_diff[NR_VM_ZONE_STAT_ITEMS];#endif};struct per_cpu_pages {        int count;        int high;        int batch;        /* 3个不同的迁移类型的链表 */        struct list_head lists[MIGRATE_PCPTYPES];};

每个cpu core都维护一个per_cpu_pageset,用来加速只分配一个page的情况。当只申请一个页的时候,可以直接从per_cpu_pageset中获取,per_cpu_pages->high记录了这个cpu core维护的per_cpu_pageset的最度的个数,如果超过了这个个数,就把其中的per_cpu_pages->batch个还给buddy系统。如果发现per_cpu_pageset中没有可分配的页,就从buddy中获取batch个。

MMU管理内存的最小单位–页page

struct page {    /* 描述这个页面的状态:脏页、被上锁、正在写回?等等 */    unsigned long flags;    union {        /* 如果是有文件背景的page,指向这个文件相关的信息,低bit为0(为0时也可能是NULL);         * 如果是匿名页,指向一个anon_vma结构体,低Bit为1。*/        struct address_space *mapping;        void *s_mem;        atomic_t compound_mapcount;    };    union {        struct {            union {                atomic_t _mapcount; //这个页面被映射的次数 - 1            };            atomic_t _refcount;        //这个页面被引用的次数        };    };    union {        struct list_head lru;        //lru算法页面回收时使用    };    struct rcu_head rcu_head;    union {        unsigned long private;    };#ifdef CONFIG_MEMCG        struct mem_cgroup *mem_cgroup;#endif}

存储所有page的数组mem_map

mem_map的定义在:

[mm/memory.c]struct page *mem_map;

有两个宏就是利用mem_map来将page和pfn进行转换的:

[include/asm-generic/memory_model.h]#define __pfn_to_page(pfn)  (mem_map + ((pfn) - ARCH_PFN_OFFSET))#define __page_to_pfn(page) ((unsigned long)((page) - mem_map) + ARCH_PFN_OFFSET)

转载于:https://www.cnblogs.com/muahao/p/10299725.html

你可能感兴趣的文章
JQ_简单瀑布流
查看>>
测试管理-测试问题监控
查看>>
thinkphp的taglib的使用方法
查看>>
tecplot批量导出图片_Fluent 后处理软件Tecplot宏批量处理cas,dat为图片
查看>>
锂电池放空后充不进电_充电锂电池,只几个月不用,为什么就再也充不进电了?...
查看>>
golang mutex 初始化_Golang连接池的几种实现案例
查看>>
docker可以把应用及其相关的_等离子表面处理机相关应用及其特点
查看>>
发电厂电气部分第三版pdf_喜讯、大唐锡林浩特发电厂660mw机组投产运行
查看>>
mysql 数据库操作通用类_mysql 数据库操作通用类
查看>>
mysql多数据库多实例配置_MySQL多实例配置方案
查看>>
python创建线段_在绘图图中添加线段的简洁方法(使用python/jupyter笔记本)?
查看>>
wkhtmltoimage 卡住了_用rails做一个简单的长微博生成工具
查看>>
什么叫组网_组网是什么意思
查看>>
如何使用mysql数据库做网站_php小型数据库(不用mysql做网站)
查看>>
mysql date to javascript_Convert MySql DateTime stamp into JavaScript's Date format
查看>>
mysql临时表仅对当前用户_mysql临时表问题
查看>>
mysql报错文档_mysql报错小记-Can't create test file xxx lower-test
查看>>
mysql数据库基础简介_MySQL数据库命令的基础简介
查看>>
java arraylist方法_Java的ArrayList方法及示例
查看>>
java语言新特性_Java语言的新特性
查看>>