内核节点

numa

非numa结构

在mm/page_alloc.c中

#ifndef CONFIG_DISCONTIGMEM                                                     
static bootmem_data_t contig_bootmem_data;                                      
struct pglist_data contig_page_data = { .bdata = &contig_bootmem_data };

在include/linux/mmzone.h中:

#ifndef CONFIG_DISCONTIGMEM                                                                                                                                    extern struct pglist_data contig_page_data;                                     
#define NODE_DATA(nid)          (&contig_page_data)

说明:静态变量bootmem_data contig_bootmem_data首先初始化为0,contig_page_data就是保存节点内容的。
在mm/page_alloc.c中

struct pglist_data *pgdat_list;

首先初始化在mm/bootmem.c中:

 51 static unsigned long __init init_bootmem_core (pg_data_t *pgdat,                
 52         unsigned long mapstart, unsigned long start, unsigned long end)         
 53 {                                                                                                        
 54         bootmem_data_t *bdata = pgdat->bdata;                                   
 55         unsigned long mapsize = ((end - start)+7)/8;                                                     
 56                                                                                  
 57         pgdat->pgdat_next = pgdat_list;                                                                          
 58         pgdat_list = pgdat;                                                     
 59                                                                                                          
 60         mapsize = (mapsize + (sizeof(long) - 1UL)) & ~(sizeof(long) - 1UL);                              
 61         bdata->node_bootmem_map = phys_to_virt(mapstart << PAGE_SHIFT);                                  
 62         bdata->node_boot_start = (start << PAGE_SHIFT);                         
 63         bdata->node_low_pfn = end;                                              
 64                                                                                                          
 65         /*                                                                                               
 66          * Initially all pages are reserved - setup_arch() has to               
 67          * register free RAM areas explicitly.                                                           
 68          */                                                                     
 69         memset(bdata->node_bootmem_map, 0xff, mapsize);                                                  
 70                                                                                                          
 71         return mapsize;                                                         
 72 } 

pgdat->pgdat_next=pgdat_list=NULL;
pgdat_list=pgdat;

在arch/i386/kernel/setup.c中

start_pfn = PFN_UP(init_pg_tables_end);
find_max_pfn(); 
bootmap_size = init_bootmem(start_pfn, max_low_pfn);

PFN的定义

#define PAGE_SHIFT      12                                                      
#define PAGE_SIZE       (1UL << PAGE_SHIFT)                                                                                                      
#define PAGE_MASK       (~(PAGE_SIZE-1))
#define PFN_UP(x)       (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)                                                                                      
#define PFN_DOWN(x)     ((x) >> PAGE_SHIFT)                                     
#define PFN_PHYS(x)     ((x) << PAGE_SHIFT)
start_pfn = PFN_UP(init_pg_tables_end) //0x0

PFN是page frame number的缩写,所谓page frame,就是针对物理内存而言的,把物理内存分成一个个的page size的区域,并且给每一个page 编号,这个号码就是PFN。假设物理内存从0地址开始,那么PFN等于0的那个页帧就是0地址(物理地址)开始的那个page。假设物理内存从x地址开始,那么第一个页帧号码就是(x>>PAGE_SHIFT)。
PFN_UP和PFN_DOWN中的参数x是物理地址,x不是物理地址。
PFN_UP(x),如果物理地址第12位全为0,则是当前页帧;如果低12位不为0,则是下一个页帧。
PFN_DOWN(x)就是当前页帧
PFN_PHYS(x),x就是页帧,转换后就是物理地址。
说明:

1< <N   <======> 2^N
2^12-1  <======> 0xFFF

sanitize_e820_map

 446         /*                                                                      
 447                 Visually we're performing the following (1,2,3,4 = memory types)...

 448                                                                                 
 449                 Sample memory map (w/overlaps):                                 
 450                    ____22__________________                                     
 451                    ______________________4_                                     
 452                    ____1111________________                                     
 453                    _44_____________________                                     
 454                    11111111________________                                     
 455                    ____________________33__                                     
 456                    ___________44___________                                     
 457                    __________33333_________                                     
 458                    ______________22________                                     
 459                    ___________________2222_                                     
 455                    ____________________33__                                     
 456                    ___________44___________                                     
 457                    __________33333_________                                     
 458                    ______________22________                                     
 459                    ___________________2222_                                     
 460                    _________111111111______                                     
 461                    _____________________11_                                     
 462                    _________________4______                                     
 463                                                                                 
 464                 Sanitized equivalent (no overlap):                              
 465                    1_______________________                                     
 466                    _44_____________________                                     
 467                    ___1____________________                                     
 468                    ____22__________________                                     
 469                    ______11________________                                     
 470                    _________1______________                                     
 471                    __________3_____________                                     
 472                    ___________44___________                                     
 473                    _____________33_________                                     
 474                    _______________2________                                     
 475                    ________________1_______                                     
 476                    _________________4______                                     
 477                    ___________________2____                                     
 478                    ____________________33__                                     
 479                    ______________________4_                                     
 480         */   

说明:
1第一幅图怎么到第二幅图,每一列中选出一个数字,如果同一列中有不同的数字,选择最大的数字;第一列中只有1,然后把1放在第一行第一列,第二列和第三列最大的是4,然后把44放在第2行中的2,3列,紧挨着的两个数字放一行,然后依次顺下去。

猜你喜欢

转载自blog.csdn.net/chengbeng1745/article/details/81671139