IT猫扑网:您身边最放心的安全下载站! 最新更新| 软件分类| 专题汇总| 手机版

您当前所在位置:IT猫扑网 > 操作系统 > LINUX > Linux Kernel内存分配方式

Linux Kernel内存分配方式

时间:2015-06-28 00:00 来源:IT猫扑网|http://www.itmop.com/ 作者:网管联盟 我要评论(0)

  这周BSP那边碰到一个蛮严重的issue:

  循环放电影,v4l2 output driver的 dma_alloc很容易就失败,kernel panic,dump出当前buddy系统的状态。

  初步分析是由于内存fragment导致没有足够大的连续内存分配给v4l output driver。开始debug

  首先通过/proc/buddyinfo 在播放电影时候不间断的dump buddy状态,发现大块内存块:256K - 4MB block

  减少的很迅速,1-2小时后,buddy中就不存在大块连续内存。这证明了初步分析是正确的,但是还不知道是谁导致了fragment,是应用层,还是v4l2 driver本身?

  接下来添加一个NORMAL zone(arm体系中就DMA一个zone,所以application和dma都使用一个buddy系统),让普通内存分配和dma隔开。继续测试,发现dma zone中的内存块状态在最初很正常,但NORMAL zone的内存却在急剧减少,最终NORMAL zone已经没有足够内存给application,kernel转而向DMA zone申请,最终issue重现。

  现在问题很清楚了,application发生内存leak,很严重的leak。但是dma_alloc这边会没有问题马?

  Fred在看了我描述的问题后,指出了dma_alloc中算法的一些问题:当向buddy申请完足够size的2^的内存块后,

  该函数会释放在申请块中多余的page,加速了fragment。后来我们做了一个实验,将dma_alloc里的释放多余页的功能去掉,fragment的速度大大减缓。

  经过上周对这个issue的研究,我开始重新总结kernel里对内存分配的方式和方法,总结如下:

  页分配

  unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order)

  直接从buddy系统中获得原始页。最原始的分配方式。

  slab分配器

  1. 通用 cache

  void *kmalloc(size_t size, gfp_t flags)

  kmalloc 基于以下几种size的mem cache:32, 64, 128, 256, 512, 1,024, 2,048, 4,096,

  8,192, 16,384, 32,768, 65,536 和 131,072 bytes。其本质也是调用kmem_cache_alloc来分配

  object。所以kmalloc一次最大可分配的size为128KB。kmalloc分配速度很快,在分配时需注意gfp flag

  参数:在不interrupt上下文(ISR, softirq, tasklet)及不可睡眠上下文使用GFP_ATOMIC。

  内核还增加了内存清零的分配函数:kzalloc。

  2. 专用 cache

  kmem_cache_create()

  void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags)

  如果你需要频繁的分配和释放某个结构,建议不要采用kmalloc,而是自己在slab系统中创建memory cache。

  指定该结构的object size。分配时使用kmem_cache_alloc。同样的slab object大小也有限制,一般情况下一个MAX_OBJ_ORDER是5,也就是32个页,128KB。

  非连续内存分配

  void *vmalloc(unsigned long size)

  超过128KB的内存显然不能使用slab分配,并且当申请的连续内存大小不能在buddy系统中得到满足,那么就需要使用vmalloc。vmalloc为了把物理的非连续页一个个映射,从而导致比直接内存映射大的多的后援缓冲区抖动。除非需要特别大的内存,否则尽量不要使用vmalloc。

  基于DMA 分配

  void * dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)

  在某些arch中,可以使用dma_alloc_coherent来分配DMA专用内存。列入在arch/arm/mm/consistent.c中,该函数先分配最小可满足size的2^order内存,然后释放2^order-size多余的页给buddy。而arch/i386/

  kernel/pci-dma.c中,则直接分配2^order块内存。

  直接映射分配

  ioremap(unsigned long phys_addr, size_t size)

  int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,

  unsigned long pfn, unsigned long size, pgprot_t prot)

  在某些体系结构中,我们可以保留memory map段上的某一个区域,作为dma或其他设备的专有内存。

  这段内存并不在kernel buddy的控制之下(没有被放入mem_maps),你也无法从以上几种分配方式中得到这些内存。这个时候,你可以用ioremap和remap_pfn_range将这段内存直接映射到vm上。

关键词标签:Linux,Kernel内存

相关阅读 安装红帽子RedHat Linux9.0操作系统教程 Tomcat9.0如何安装_Tomcat9.0环境变量配置方法 多种操作系统NTP客户端配置 Linux操作系统修改IP Linux实现SCSI硬盘热插拔及在线识别 Linux下用CDMA modem拨号上网

文章评论
发表评论

热门文章 安装红帽子RedHat Linux9.0操作系统教程 安装红帽子RedHat Linux9.0操作系统教程 Linux服务器:设计高性能网站架构-LLMP Linux服务器:设计高性能网站架构-LLMP 使用Clonezilla迁移到虚拟Linux环境 使用Clonezilla迁移到虚拟Linux环境 Linux上的MRTG流量监控中心 Linux上的MRTG流量监控中心 Linux 双网卡绑定一个IP原理及实现 Linux 双网卡绑定一个IP原理及实现 linux和windows等系统远程控制ubuntu桌面 linux和windows等系统远程控制ubuntu桌面

相关下载

人气排行 Linux下获取CPUID、硬盘序列号与MAC地址 dmidecode命令查看内存型号 linux tc实现ip流量限制 安装红帽子RedHat Linux9.0操作系统教程 linux下解压rar文件 lcx.exe、nc.exe、sc.exe入侵中的使用方法 Ubuntu linux 关机、重启、注销 命令 查看linux服务器硬盘IO读写负载 linux命令行浏览器的使用方法 Linux NFS服务固定端口及防火墙配置 U盘安装Ubuntu 10.04 Linux清除用户登录记录和命令历史方法