Linux当中的物理内存管理

1330阅读 0评论2020-08-24 stolennnxb
分类:LINUX

有两种类型的计算机,分别以不同的方法管理物理内存:
1. UMA计算机,将可用内存以连续方式组织起来。SMP系统中的每个处理器访问各个内存区都是同样快
2. NUMA计算机,总是多处理器计算机。系统的每个CPU都有本地内存,可支持特别快速的访问,各个处理器之间用总线连接起来,以支持对其他CPU的本地内存访问
在NUMA当中,内存被划分为节点,单个节点的结构如下所示:


点击(此处)折叠或打开

  1. typedef struct pglist_data {
  2.         struct zone node_zones[MAX_NR_ZONES];// 当前节点上的各个区域的数组
  3.         struct zonelist node_zonelists[MAX_ZONELISTS];// 备用节点列表
  4.         int nr_zones;// 节点当中不同区域的个数
  5.     ..
  6.         unsigned long node_start_pfn;//NUMA节点第一个页帧逻辑编号,所有节点页帧依次编号,页帧号全局唯一
  7.         unsigned long node_present_pages; /* total number of physical pages */
  8.         unsigned long node_spanned_pages; /* total size of physical page
  9.                          range, including holes */
  10.         int node_id;// 全局节点id
  11.         wait_queue_head_t kswapd_wait; // 交换守护进程等待队列
  12.         wait_queue_head_t pfmemalloc_wait;
  13.         struct task_struct *kswapd; /* Protected by
  14.                          mem_hotplug_begin/end() */
  15.         int kswapd_order;
  16.         enum zone_type kswapd_classzone_idx;

  17.         int kswapd_failures; /* Number of 'reclaimed == 0' runs */
  18.     ...
  19.         /* Write-intensive fields used by page reclaim */
  20.         ZONE_PADDING(_pad1_)
  21.         spinlock_t lru_lock;
  22.         /* Fields commonly accessed by the page reclaim scanner */
  23.         /*
  24.          * NOTE: THIS IS UNUSED IF MEMCG IS ENABLED.
  25.          *
  26.          * Use mem_cgroup_lruvec() to look up lruvecs.
  27.          */
  28.         struct lruvec __lruvec;
  29.         unsigned long flags;
  30.         ZONE_PADDING(_pad2_)
  31.         /* Per-node vmstats */
  32.         struct per_cpu_nodestat __percpu *per_cpu_nodestats;
  33.         atomic_long_t vm_stat[NR_VM_NODE_STAT_ITEMS];
  34.     } pg_data_t;


这样的话,物理内存的管理,实际上就是这个节点的管理了,各个节点上又分了不同的区域,其中区域的定义如下:


点击(此处)折叠或打开

  1. enum zone_type {
  2. #ifdef CONFIG_ZONE_DMA
  3.         ZONE_DMA,
  4. #endif
  5. #ifdef CONFIG_ZONE_DMA32
  6.         ZONE_DMA32,// 两个DMA区域,
  7. #endif
  8.         ZONE_NORMAL,// 内核态虚拟内存地址减掉固定常数,直接映射的部分,
  9. #ifdef CONFIG_HIGHMEM
  10.         ZONE_HIGHMEM,// 高于上面直接映射的部分
  11. #endif
  12.         ZONE_MOVABLE,// 划分为可移动与否,可以避免内存碎片
  13. #ifdef CONFIG_ZONE_DEVICE
  14.         ZONE_DEVICE,
  15. #endif
  16.         __MAX_NR_ZONES

  17. };

每个区域分为多个页,内部使用伙伴系统来进行分配,其中每个区域的定义如下:

点击(此处)折叠或打开

  1. struct zone {
  2.         /* Read-mostly fields */

  3.         /* 区域当中的水印,与内存交换有关,min,low,high等 */
  4.         unsigned long _watermark[NR_WMARK];
  5.         unsigned long watermark_boost;
  6.         unsigned long nr_reserved_highatomic;
  7.         long lowmem_reserve[MAX_NR_ZONES];// 各个区域保留,给无论如何都不能失败的调用使用

  8. ...
  9.         struct pglist_data *zone_pgdat;
  10.         struct per_cpu_pageset __percpu *pageset;// cpu的冷暖数据,用两条链表表示

  11. ...

  12.         /* zone_start_pfn == zone_start_paddr >> PAGE_SHIFT */
  13.         unsigned long zone_start_pfn;
  14. ...
  15.         atomic_long_t managed_pages;
  16.         unsigned long spanned_pages;
  17.         unsigned long present_pages;

  18.         const char *name;

  19. ...
  20.         /* Zone 相关统计信息 */
  21.         atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
  22.         atomic_long_t vm_numa_stat[NR_VM_NUMA_STAT_ITEMS];
  23. } ____cacheline_internodealigned_in_smp;
上一篇:stl之各种iterator
下一篇:Linux当中的物理内存管理——伙伴系统以及slab分配器