kmap映射高端内存

作者:唐浩然
链接:https://www.zhihu.com/question/30338816/answer/49056599
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • Kmalloc 分配的内存在上图的Direct Memory region区域,这区域的个大小为896M,且与物理内存的关系是直接的线性映射, 即0xC0000000-->C0000000+896M 对应真实物理内存的0G->896M
    1. kmalloc() 确保页在物理上是连续的 ,内存只有在要被DMA访问的时候才需要物理上连续
    2. kmalloc分配内存是可以调用__get_free_pages()
  • Kmap 分配的内存在高端内存区(或非直接映射区),内存描述符在上图的PKmap Region区域,即永久内存映射区域。
    1. 使用kmap的原因:对于高端物理内存(896M之后),并没有和内核地址空间建立一一对应的关系(即虚拟地址=物理地址+PAGE_OFFSET这样的关系),所以不能使用get_free_pages()这样的页分配器进行内存的分配,而必须使用alloc_pages()这样的伙伴系统算法的接口得到struct *page结构,然后将其映射到内核地址空间。
    2. Kmap每次只能分配一个页面。
  • l分配函数的选择:
    1. 连续的物理页:kmalloc或者低级页分配器
    2. 高端内存分配:alloc_pages指向page结构指针,不是逻辑地址指针。再通过kmap()把高端地址内存映射到内核的逻辑地址空间。

如果都是需要开大段内存的话,什么时候用kmalloc,什么时候用kmap呢?-----kmalloc以字节为单位,比较适合小片内存分配,它是基于slab,把物理内存分配、内核空间的虚拟内存分配、映射几个事情一起做了。 kmap以page为单位/且只能单页,用于手动地先分配物理page、再用kmap来分配虚拟地址/同时建立page和这个虚拟地址的映射关系。

另外,kmalloc开的内存不会落在高位地址吗?--会,根据传入的gfp标记,可以分配在高端内存。
为什么把内存开在高位地址作为kmap的一个特点?---应用上,主要是为了哪些临时使用的物理内存的场景,临时使用物理内存中的高端内存部分。

其实所有高端内存都是临时使用的。例如vmalloc也是临时分配内存,它分配的容量可以更大,一般100M以上,但速度慢; 而kmap临时分配内存不涉及虚拟内存页表映射等开销,所以快,但容量小,一般就几个M而已。


作者:jiaoguober
链接:https://www.zhihu.com/question/30338816/answer/93975397
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


1、  kmalloc()是内核中最常见的内存分配方式,它最终调用伙伴系统的__get_free_pages()函数分配,根据传递给这个函数的flags参数,决定这个函数的分配适合什么场合,如果标志是GFP_KERNEL则仅仅可以用于进程上下文中,如果标志GFP_ATOMIC则可以用于中断上下文或者持有锁的代码段中。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

kmalloc返回的线形地址是直接映射的,而且用连续物理页满足分配请求,且内置了最大请求数(2**5=32页)。

 

2、  kmap()是主要用在高端存储器页框的内核映射中,一般是这么使用的:
使用alloc_pages()在高端存储器区得到struct page结构,然后调用kmap(struct *page)在内核地址空间PAGE_OFFSET+896M之后的地址空间中(PKMAP_BASE到FIXADDR_STAR)建立永久映射(如果page结构对应的是低端物理内存的页,该函数仅仅返回该页对应的虚拟地址
)
kmap()也可能引起睡眠,所以不能用在中断和持有锁的代码中

不过kmap 只能对一个物理页进行分配,所以尽量少用。

 

3、  vmalloc优先使用高端物理内存,但性能上会打些折扣。

vmalloc分配的物理页不会被交换出去;
vmalloc返回的虚地址大于(PAGE_OFFSET + SIZEOF(phys memory) + GAP),为VMALLOC_START----VMALLOC_END之间的线形地址
;
vmalloc使用的是vmlist链表,与管理用户进程的vm_area_struct要区别,而后者会swapped;

 

4、  使用kmap的原因:
对于高端物理内存(896M之后),并没有和内核地址空间建立一一对应的关系(即虚拟地址=物理地址+PAGE_OFFSET这样的关系),所以不能使用get_free_pages()这样的页分配器进行内存的分配,而必须使用alloc_pages()这样的伙伴系统算法的接口得到struct *page结构,然后将其映射到内核地址空间,注意这个时候映射后的地址并非和物理地址相差PAGE_OFFSET.



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值