内存管理五

此部分内容多且杂,其实完全可以合并到前四篇文章中。但考虑前四篇总结已经完成,章节插入不方便,所以还是多写一篇。

         本文分成两部分来论述

1、 DMA与Cache一致性问题。

2、  常用的命令接口和文件接口简要说明。

 

DMA与Cache一致性问题

         关于这一部分,宋老师的文章已经讲解的非常细致,我在写也无非是画蛇添足,所以此处只做简单总结。附上文章连接,http://mp.weixin.qq.com/s/5K7rlPXo2yIcoIXXgqqLfQ

         而实际上,如果你不是在IC公司,大部分时候你只需要在驱动程序中轻松敲下dma_alloc_coherent来获取一片能确保DMA和cache一致性的内存就可以了,具体实现细节对你来说可能并不重要。请看下图:

A.DMA的内存分配区域

不论是应用程序还是驱动程序,在获取内存时都需要获得一片连续地址的内存,但是由

于DMA设备访问内存不经过MMU,所以也无法把不连续的物理地址映射为连续的虚拟地址,解决这个问题有两种方式:

a.      在CMA区域申请DMA内存,因为CMA本身是一片连续的物理内存,CMA通常被分配在高端内存,这个时候这片内存会被映射到vmalloc映射区,如果CMA在低端内存,则不需要重新映射,因为低端内存在开机时已经与low Memory映射区建立了一一映射关系。

b.      如果设备存在IOMMU,那么做DMA内存分配时则不需要关心具体的内存分配区域,IOMMU会让设备看到一片连续的地址范围,它的功能类似MMU,只不过MMU是把物理地址转换为连续的虚拟地址供CPU使用,而IOMMU是把物理地址转换为连续的总线地址供设备使用。

 

B. 确保DMA和cache一致性的手段

确保DMA和cache一致性的手段有以下三种:

a.      页表设置uncache

要保证DMA和cache一致性最简单办法,在申请到内存后,修改对应的页表,将页表的cache属性改为uncache,这样,当CPU在访问该片内存时就不会从cache取数据。

b.      硬件确保一致性

有的设备提供了确保一致性的硬件机制,这时我们申请内存后则不需要修改页表的cache属性,一致性由硬件来保证。

c.      代码手动同步

如果对应的内存区域已经申请好了,设备直接使用,那么驱动就无法更改对应页表的cache属性,这时解决一致性的手段时在每次访问这篇内存前手动同步cache内容到内存,同时禁止CPU对这片内存的访问,直到设备访问完成。实际上下面提到的DMA streaming mapping就是通过这种方式实现的。

 

C. API接口

当我们的驱动自己获取内存,可以使用一致性DMA缓冲区API接口,就是

dam_alloc_coherent();如果对应的内存已经被成功分配,我们在使用前需要调用DMA流映射API接口,确保cache的内容被成功flush到内存,对应的函数有dma_map_sg()和dma_map_single(),他们两个的区别是,sg映射的内存是分散/聚集的,分散在不同的位置,single映射的内存是连续的一片内存,通常是CMA。

 

常用的命令接口和文件接口简要说明

 

A.      文件Dirty数据写回配置接口

/proc/sys/vm/dirty_expire_centisecs:设置Dirty数据的写回时间期限,超过这个时间,在flusher线程下次唤醒后,写回这部分数据,单位是百分之一秒,厘秒。

/proc/sys/vm/dirty_writeback_centisecs:flusher线程周期性唤醒的时间,单位是厘秒,设置为0,表示禁止定期写回。Flusher线程唤醒后会把超过期限的脏页和进程超过dirty_background_ratio值的脏页写回。

/proc/sys/vm/dirty_background_ratio:进程持有的脏页的个数阀值,单位是页,超过这个值,flusher线程在下次唤醒后会对脏页进行写回。

/proc/sys/vm/dirty_ ratio:进程持有的脏页的个数阀值,单位是页,超过这个值,进程delay,无法在进行任何的写操作,并且进程自行完成脏页的回写。

B.      Memory Cgroup的使用

控制group的最大使用内存示例如下:

$:cd /sys/fs/cgroup/memory

$:mkdir A                                                                                   //创建一个分组

$:cd A/

$echo $((200*1024*1024)) >memory.limit_in_bytes    //设置该组最大可使用内存200M

$:cgexec –g memory:A ./a.out                                                //将a.out添加到组A并执行

C.       内存回收接口说明

内存管理四章节中提到内存回收有三个水位,min,low和hight,当内存的水位达到low,说明内存紧张,这时kswapd开始工作,在后台慢慢回收内存,直到水位达到high,当系统内存异常紧张时,达到min水位,程序被堵住,Direct reclaim被触发。具体相关接口如下:

/proc/zoneinfo  //该文件可以查看到各个zone的情况,包括各个zone的三个水位设置

/proc/sys/vm/min_free_kbytes  //可用于查看和设置min水位的值

其中low水位和high水位没有对应的设置接口,是通过计算得来的。

Low = min*5/4

High = min*6/4

各个zone的水位标准是按总的水位标准等比例划分的,比如normal zone是800M,内存一共1G,min_free_kbytes被设置为30720,即30M,那么,normal zone的min水位就等于,800/1024 * 30720,就是24000

D.      Swappiness接口

Swappiness越大,越倾向于回收匿名页;swappiness越小,越倾向于回收file-backed的页面。当然,它们的回收方法都是一样的LRU算法。Swappiness的接口有两个,一个是cgroup里的swappiness,一个是/proc/sys/vm下的swappiness,他们的区别是作用域不同,cgroup里的swappiness只控制组内程序的回收倾向,而/proc/sys/vm/swappiness控制当前整个系统,除了在cgroup被重新定义的程序。

E.       Getdelays工具

要使用该工具需要打开内核选项CONFIG_TASK_DELAY_ACCT和CONFIG_TASKSTATS。该工具的源文件在LinuxKernelSource/Documentation/accounting下。使用getdelays可以查看当前系统或者某个进程调度的延时,IO的delay情况,swap和内存回收的delay情况,帮助用户查看程序的耗时情况。

F.       Vmstat命令

该命令可周期性的查看swap in/out和block in/out的情况。


更多系统参数接口请查看我另一篇博客:linux系统为用户提供的文件接口

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值