📄 014_mm_numa_c.html
字号:
<html lang="zh-CN" xmlns:gdoc=""> <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> <style type="text/css">/* default css */table { font-size: 1em; line-height: inherit;}div, address, ol, ul, li, option, select { margin-top: 0px; margin-bottom: 0px;}p { margin: 0px;}body { margin: 0px; padding: 0px; font-family: Verdana, sans-serif; font-size: 10pt; background-color: #ffffff;}h6 { font-size: 10pt }h5 { font-size: 11pt }h4 { font-size: 12pt }h3 { font-size: 13pt }h2 { font-size: 14pt }h1 { font-size: 16pt }blockquote {padding: 10px; border: 1px #DDD dashed }a img {border: 0}div.google_header, div.google_footer { position: relative; margin-top: 1em; margin-bottom: 1em;}/* end default css */ /* default print css */ @media print { body { padding: 0; margin: 0; } div.google_header, div.google_footer { display: block; min-height: 0; border: none; } div.google_header { flow: static(header); } /* used to insert page numbers */ div.google_header::before, div.google_footer::before { position: absolute; top: 0; } div.google_footer { flow: static(footer); } /* always consider this element at the start of the doc */ div#google_footer { flow: static(footer, start); } span.google_pagenumber { content: counter(page); } span.google_pagecount { content: counter(pages); } } @page { @top { content: flow(header); } @bottom { content: flow(footer); } } /* end default print css */ /* custom css *//* end custom css */ /* ui edited css */ body { font-family: Verdana; font-size: 10.0pt; line-height: normal; background-color: #ffffff; } .documentBG { background-color: #ffffff; } /* end ui edited css */</style> </head> <body revision="dcbsxfpf_55fcnhx6fz:5"> <table align=center cellpadding=0 cellspacing=0 height=5716 width=768>
<tbody>
<tr>
<td height=5716 valign=top width=100%>
<pre>2006-5-26 <br>mm/numa.c<br> numa的话题已经多次涉及了。并且这个文件中的内容已经全部都有接触。很重要<br>的一个参考文档就是 Documentation/vm/numa。<br><br> What is NUMA? <br> NUMA指的是这样一种体系结构,对于指定的cpu,访问不同区域的内存耗时不等<br>取决于cpu到内存的"距离"。一个node指的是一个区域的内存,某个cpu(fix me)访<br>问此段内存耗时相等。<br> What about discontiguous physical memory?<br> NUMA已支持那种不连续物理内存的体系架构。这种系统在物理地址空间中存在比<br>较大的空洞。专门支持此种架构的代码使用条件宏CONFIG_DISCONTIGMEM加以界定.<br><br> 内核与此相关的处理:<br> 首先是将bootmem NUMA化。将所有信息封装到bootmem_data_t.增加基于Node的分<br>配函数。<br> 然后对node的page allocation相关数据进行封装,就是pg_data_t.内核设计人员<br>努力使NUMA和UMA系统统一起来。(2.4做的还不够好)<br> NUMA aware 的page allocation现在在不同node之间采用轮转调度的方式。<br> 增加接口:alloc_pages_node,同时兼容NUMA 和UMA,对于驱动开发有好处,你不<br>用考虑到底运行于那种系统。<br><br> 本模块为了兼容UMA定义了两个专用于UMA的数据结构。<br>static bootmem_data_t contig_bootmem_data;<br>pg_data_t contig_page_data = { bdata: &contig_bootmem_data };<br> 如果linux一开始就是支持NUMA的,或许代码比现在要干净许多。开始的时候只支持<br>UMA后来加入了NUMA,就要考虑在支持NUMA的同时让现存代码尽可能的能够工作。这两<br>个变量就是这个目的。另外我们曾经分析过bootmem.c/.h,现在从NUMA的角度考察一下<br>bootmem在NUMA化中的变化:看bootmem.h,首先是bootmem_data_t中出现了node相关的<br>变量。接口函数分成两类:node aware/node unaware(对于使用者)。<br> 对于现存的NUMA代码,接口:<br> init_bootmem<br> reserve_bootmem<br> free_bootmem<br> alloc_bootmem<br> 保持不变,以__alloc_bootmem为例:<br>void * __init __alloc_bootmem (unsigned long size, unsigned long align, unsigned long goal)<br>{<br> pg_data_t *pgdat = pgdat_list;<br> void *ptr;<br><br> while (pgdat) {<br> if ((ptr = __alloc_bootmem_core(pgdat->bdata, size,<br> align, goal)))<br> return(ptr);<br> pgdat = pgdat->node_next;<br> }<br> /*<br> * Whoops, we cannot satisfy the allocation request.<br> */<br> BUG();<br> return NULL;<br>}<br> 其实是在node之间遍历(一般,UMA只有一个pgdat,即便是NUMA使用此函数也是可<br>以的).这一点做到增加node相关的数据结构后,UMA得到很好的兼容.<br> <br> 另外一个受到冲击的模块是page页面的buddy系统.UMA下,可以只以为只有一个<br>node,分成三个zone:NOMAL,DMA,HIGH.现在要支持多个node,增加了机构pg_data_t.<br>同时受到严重影响的是极为重要的全局变量:<br> mem_map_t * mem_map;<br> NUMA化以后,这些都变成了node(pgdata)的私有数据.其中,最难以处理的是mem_map<br>参考.<br> 现在立刻去看看曾经分析过的mm/memory.c, i386下的mem_map那段分析:NUMA化<br>后,free_area_init中分配了pgdata中的node_mem_map后将此值复制给全局指针<br>mem_map.在UMA下此两者等效。<br> 在mm/memory.c紧接着分析了NUMA下的mem_map,并以ia64为例:mem_map退化成一<br>个常数,只有pgdata->node_mem_map才拥有实际的意义。但是为了兼容大量的UMA的<br>现存代码,使用了复杂的宏运算来兼容。原没有kernel2.6简洁清楚。<br><br> 另外请参考对bootmem和mem init的相关分析,以对NUMA有完整的印象。<br> <br> 此模块几乎没有其他要说的东西,看看函数alloc_pages_node,free_area_init<br>_node,alloc_pages_pgdat,是增加给认知NUMA的模块使用的接口函数。<br> alloc_pages被重新设计,和bootmem类似在node之间"遍历"分配pages.(UMA的<br>alloc_pages在文件include/linux/mm.h中).<br><br> 有了这么多的兼容设计,难怪内存分配的函数有__alloc_pages这样的双下划线<br>函数命名方式,这个东西是原来UMA下的alloc_pages啊。(不要太认真这句话)<br><br><br><br> <br> <br><br> <br></pre>
</td>
</tr>
</tbody>
</table></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -