Chinaunix首页 | 论坛 | 博客
  • 博客访问: 234920
  • 博文数量: 31
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 296
  • 用 户 组: 普通用户
  • 注册时间: 2016-06-22 11:52
文章分类

全部博文(31)

文章存档

2018年(3)

2017年(11)

2016年(12)

2015年(5)

我的朋友

分类: LINUX

2016-10-11 19:46:19

最近在看《深入linux 内核架构》 内存管理的部分,写一下博客,做写总结,记录

3.1和3.2节的主要内容
1.UMA和NUMA 类型的计算机对内存的管理方式的影响

UMA,uniform memory access 一致性内存访问,在smp系统中,每个处理器访问各个内存区的速度是一样的
NUMA,non-uniform memory access 非一致性内存访问,每个cpu都有本地的内存,可以支持特别快速的访问,各个处理器之间用总线连起来,以支持对其他cpu的本地内存的访问,当然访问速度要比本地内存慢,下图可以很好的反映UMA 和NUMA 结构的区别:



内核对于UMA 和NUMA 类型的计算机都是以结点的方式来管理,对于UMA的计算机,其实就相当于只有一个NUMA节点的伪NUMA系统

2.linux 内核中表示内存三个数据结构,以及其关系
struct pglist_data:表示结点,每个结点关联到一个处理器,每个结点都会有三种类型的内存域,DMA,NORMAL,HIGHMEM,只有NORMAL的内存域会保证在每一个结点都有,其他两种类型的内存域有可能有,也有可能没有,pglist_data 数据结构是通过单链表来组织的

struct zone:表示内存域,就是一种类型的内存的集合,内存域会用一个数组来组织属于本域的页帧,page 表示的实例
struct page:页帧,内存管理的最小单元,在IA-32系统中标准页长度是4KiB,通过PAGE_SIZE 指定。PAGE_SIZE 宏定义如下:
#define PAGE_SHIFT 12
#define PAGE_SIZE (1 << PAGE_SHIFT)

三者的关系如下图所示:



3.三个数据结构的成员

点击(此处)折叠或打开

  1. typedef struct pglist_data {
  2.         struct zone node_zones[MAX_NR_ZONES];  /*本结点中各种内存域的数组,保存的都是真实的zone ,而不是zone的指针,不存在的域填0*/
  3.         struct zonelist node_zonelists[MAX_ZONELISTS];/*备用结点,如果当前结点没有可用空间的时候,可以使用备用结点的空间*/
  4.         int nr_zones;                                 /*结点不同内存域的数目,具体怎么记录的不清楚,到后面看到使用的是来补充*/
  5.         struct page *node_mem_map;                     /*指向page 实例的指针,包括结点所有内存域的页帧,就是pglist_data 中也有page*/
  6.         struct bootmem_data *bdata;/*指向自举内存分配器数据结构实例,在内存管理子系统初始化之前需要的内存,就通过自举内存分配器提供*/

  7.         unsigned long node_start_pfn;/*NUMA结点的第一个页帧的逻辑编号,所以结点的页帧是依次编号的,每个页帧的编号都是全局唯一的,不止是结点内唯一,在UMA 系统中,这个值总是0,因为只有一个结点,而且是从0开始编号的*/
  8.         unsigned long node_present_pages;  /*结点中页帧数目,包括所有内存域的 */
  9.         unsigned long node_spanned_pages; /* total size of physical page range, including holes */

  10.         int node_id; /*NUMA 结点编号*/
  11.         stuct pglist_data *pgdat_next; /*指向下一个内存结点的指针*/

  12. /*以下的三个成员都是与交换相关的,到时候看到在回来补充*/
  13.         wait_queue_head_t kswapd_wait;
  14.         struct task_struct *kswapd; /* Protected by lock_memory_hotplug() */
  15.         int kswapd_max_order;
  16.         
  17. } pg_data_t;

点击(此处)折叠或打开

  1. struct zone {
  2.     /*通常由页分配器访问的字段*/
  3.     unsigned long pages_min,pages_low,pages_high;/*是页换出时候的几个阈值*/
  4.     unsigned long lowmem_reserve[MAX_NR_ZONES];/*保留的各种内存域的若干页,留着给不允许分配失败的关键内存分配使用*/
  5.     struct per_cpu_pageset pageset[NR_CPUS]; /*记录每个cpu的冷/热页帧,在高速缓存的页帧称为热帧,反之称为冷帧*/

  6.     /*不同长度的空闲区域*/
  7.     spinlock_t lock;
  8.     struct free_area free_area[MAX_ORDER];/*伙伴系统使用的,每个元素表示某种固定长度的连续内存区域,这只是一个起点*/
  9.     ZONE_PADDING(_pad1_)

  10.    /*通常由页面回收扫描程序访问的字段*/
  11.     spinlock_t lru_lock;    
  12.     struct list_head active_list; /*活动页的集合,访问频繁称为活动,反之称为不活动*/
  13.     struct list_head inactive_list;
  14.     unsigned long nr_scan_active; /*内存回收的时候需要扫描的活动页的数目*/
  15.     unsigned long nr_scan_inactive;
  16.     unsigned long pages_scanned;
  17.     unsigned long flags;  /*内存域当前状态*/
  18.   
  19.     /*内存域统计量*/ 
  20.     atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS];/*内存域的统计信息*/
  21.     int prev_priority;
  22.     
  23.     ZONE_PADDING(_pad2_)

  24.     /*很少使用或者大多数情况下只读的字段*/
  25.     wait_queue_head_t *wait_table;
  26.     unsigned long wait_table_hash_nr_entries;
  27.     unsigned long wait_table_bits;

  28.     /*支持不连续内存模型的字段*/
  29.     struct pglist_data *zone_pgdat; 
  30.     unsigned long zone_start_pfn;   /*内存域的第一个页帧的索引,结点也有第一个页帧的索引*/
  31.     unsigned long spanned_pages;
  32.     unsigned long present_pages;
  33.     
  34.     char *name;
  35. } ____cacheline_maxaligned_in_smp;




点击(此处)折叠或打开

  1. struct page {
  2.         unsigned long flags; /*存储了体系结构无关的标志,描述页的属性,对于各种属性会有对应的接口进行操作*/
  3.         atomic_t _count;/*内核引用本页的次数*/
  4.         
  5.         union {
  6.             atomic_t _mapcount; /*映射的页表项计数,表示在页表中有多少项指向本页,不是很能理解,需要后面了解了页表项*/
  7.             unsigned int inuse; /* 本页用于slub分配器的对象数目 */                     
  8.         };
  9.     
  10.         union{
  11.             struct {
  12.                 unsigned long private ;
  13.                 struct address_space *mapping;/*页帧所在的地址空间,什么是地址空间?*/
  14.             };
  15.             ...........
  16.             struct kmem_cache *slab; /*指向slab指针*/
  17.             struct page *first_page;/*内核可以把多个毗连的也合并为较大的复合页,在这个复合页中,第一个页成为head page,其余的都成为tail page ,所有的tail page 中都会通过成员first_page记录自己所在的复合页的head page ,*/
  18.         };
  19.         
  20.         union {
  21.             pgoff_t index;
  22.             void *freelist ;
  23.         };
  24.         struct list_head lru;  /*链表头,用于把page 放到各种链表中的*/
  25. #if defined (WANT_PAGE_VIRTUAL)
  26.         void *virtual;  /*用于高端内存的区域的页*/
  27. #endif 
目前只是对这些数据结构成员有个大概的了解,通过后面的学习,才能深入了解各个成员的作用。



阅读(1769) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~