我对内存寻址和分散(sg)列表有疑问,请有人帮我解决以下问题:
,Q#1: 如果页面大小为4096,让我们假设一个如下所示的场景
page0 ---使用0-3096字节,1000字节是免费的 page1 ---使用0-3096字节,1000字节是免费的 page2 ---使用0-3096字节,1000字节是免费的 pageN ---使用0-3096字节,1000字节是免费的
所以如果我请求1010的内存可能正在使用malloc,它会失败,因为页面都没有超过1000个字节,或者它是通过从多个页面收集(累积)来分配内存,如page0(1000bytes)+ page1 (10)字节?
,Q#2: 如果页面大小为4096,那么对于给定的页面,从0-4096开始的虚拟地址保证在物理上是连续的吗?
如果我在页面大小内获得散点列表中的数据(可能是4096),它是否意味着并非真正分散在物理内存中,因为它小于或等于(< =)单个页面大小?
BR, &安培; Sanumala
答案 0 :(得分:1)
TL;博士:这取决于。
linux内核中有几个内存分配接口,它们具有不同的属性。
一个这样的接口是kmalloc
,它返回物理上连续的内存(另请参阅此答案:Linux kernel memory management, does it use consecutive memory pages all the time?)。
还有vmalloc
,它返回几乎连续的内存,可以扩展到多个非物理连续的页面。
还有许多其他内存分配变体允许您分配小块内存供您自己使用,或者代表用户进程使用大块,或者多个页面用于DMA与/或来自设备,或组合这些。
对于您的其他问题,IIUC,单个页面中的内存 在定义上始终是物理上连续的。 (例如,如果页面大小为4096 [0x1000]并且您分配0x100字节并以低位数字返回0xb00的地址,则它不可能在物理上连续。)对于可能跨越页边界的分配 - 也就是说,start_address & PAGE_MASK != end_address & PAGE_MASK
- 它取决于你使用的分配接口。
Scatter-gather是一个概念,用于描述与多个区域之间的I / O,这些区域并非确实是物理上连续的。这可能只是内核内(即struct scatterlist
专门用于管理多部分非物理连续内存),或者它可能意味着iovec
用于支持readv
/ writev
。在后一种情况下,用户有权请求分散 - 收集操作,该操作具有从XXXXX004开始的区域,长度为10个字节,加上YYYYY300的另一个区域,20个字节。 XXXXX和YYYYY可能相同或者可能不同。 如果它们是相同的,那么是的,您可以放心,它们位于同一物理页面内(同样, iff 长度不跨越页面边界)。< / p>
如果通过malloc
实际上意味着用户空间库函数,则只能假定该内存在物理上连续到长度不跨越页面边界的程度(事实上,它随时都可以改变 - 内核可以随时窃取页面,将其内容写入调页空间[&#34; swap&#34; partition],然后在其位置恢复不同的物理页面,阅读从调页空间返回的内容没有进程知道它。)