⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 014_mm_numa_c.html

📁 重读linux 2.4.2o所写的笔记
💻 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: &amp;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-&gt;bdata, size,<br>						align, goal)))<br>			return(ptr);<br>		pgdat = pgdat-&gt;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-&gt;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 + -