IT貓撲網(wǎng):您身邊最放心的安全下載站! 最新更新|軟件分類|軟件專題|手機版|論壇轉(zhuǎn)貼|軟件發(fā)布

您當前所在位置: 首頁操作系統(tǒng)LINUX → Linux Kernel內(nèi)存分配方式

Linux Kernel內(nèi)存分配方式

時間:2015-06-28 00:00:00 來源:IT貓撲網(wǎng) 作者:網(wǎng)管聯(lián)盟 我要評論(1)

  這周BSP那邊碰到一個蠻嚴重的issue:

  循環(huán)放電影,v4l2 output driver的 dma_alloc很容易就失敗,kernel panic,dump出當前buddy系統(tǒng)的狀態(tài)。

  初步分析是由于內(nèi)存fragment導致沒有足夠大的連續(xù)內(nèi)存分配給v4l output driver。開始debug

  首先通過/proc/buddyinfo 在播放電影時候不間斷的dump buddy狀態(tài),發(fā)現(xiàn)大塊內(nèi)存塊:256K - 4MB block

  減少的很迅速,1-2小時后,buddy中就不存在大塊連續(xù)內(nèi)存。這證明了初步分析是正確的,但是還不知道是誰導致了fragment,是應用層,還是v4l2 driver本身?

  接下來添加一個NORMAL zone(arm體系中就DMA一個zone,所以application和dma都使用一個buddy系統(tǒng)),讓普通內(nèi)存分配和dma隔開。繼續(xù)測試,發(fā)現(xiàn)dma zone中的內(nèi)存塊狀態(tài)在最初很正常,但NORMAL zone的內(nèi)存卻在急劇減少,最終NORMAL zone已經(jīng)沒有足夠內(nèi)存給application,kernel轉(zhuǎn)而向DMA zone申請,最終issue重現(xiàn)。

  現(xiàn)在問題很清楚了,application發(fā)生內(nèi)存leak,很嚴重的leak。但是dma_alloc這邊會沒有問題馬?

  Fred在看了我描述的問題后,指出了dma_alloc中算法的一些問題:當向buddy申請完足夠size的2^的內(nèi)存塊后,

  該函數(shù)會釋放在申請塊中多余的page,加速了fragment。后來我們做了一個實驗,將dma_alloc里的釋放多余頁的功能去掉,fragment的速度大大減緩。

  經(jīng)過上周對這個issue的研究,我開始重新總結(jié)kernel里對內(nèi)存分配的方式和方法,總結(jié)如下:

  頁分配

  unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order)

  直接從buddy系統(tǒng)中獲得原始頁。最原始的分配方式。

  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。其本質(zhì)也是調(diào)用kmem_cache_alloc來分配

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

  參數(shù):在不interrupt上下文(ISR, softirq, tasklet)及不可睡眠上下文使用GFP_ATOMIC。

  內(nèi)核還增加了內(nèi)存清零的分配函數(shù):kzalloc。

  2. 專用 cache

  kmem_cache_create()

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

  如果你需要頻繁的分配和釋放某個結(jié)構(gòu),建議不要采用kmalloc,而是自己在slab系統(tǒng)中創(chuàng)建memory cache。

  指定該結(jié)構(gòu)的object size。分配時使用kmem_cache_alloc。同樣的slab object大小也有限制,一般情況下一個MAX_OBJ_ORDER是5,也就是32個頁,128KB。

  非連續(xù)內(nèi)存分配

  void *vmalloc(unsigned long size)

  超過128KB的內(nèi)存顯然不能使用slab分配,并且當申請的連續(xù)內(nèi)存大小不能在buddy系統(tǒng)中得到滿足,那么就需要使用vmalloc。vmalloc為了把物理的非連續(xù)頁一個個映射,從而導致比直接內(nèi)存映射大的多的后援緩沖區(qū)抖動。除非需要特別大的內(nèi)存,否則盡量不要使用vmalloc。

  基于DMA 分配

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

  在某些arch中,可以使用dma_alloc_coherent來分配DMA專用內(nèi)存。列入在arch/arm/mm/consistent.c中,該函數(shù)先分配最小可滿足size的2^order內(nèi)存,然后釋放2^order-size多余的頁給buddy。而arch/i386/

  kernel/pci-dma.c中,則直接分配2^order塊內(nèi)存。

  直接映射分配

  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)

  在某些體系結(jié)構(gòu)中,我們可以保留memory map段上的某一個區(qū)域,作為dma或其他設備的專有內(nèi)存。

  這段內(nèi)存并不在kernel buddy的控制之下(沒有被放入mem_maps),你也無法從以上幾種分配方式中得到這些內(nèi)存。這個時候,你可以用ioremap和remap_pfn_range將這段內(nèi)存直接映射到vm上。

關(guān)鍵詞標簽:Linux,Kernel內(nèi)存

相關(guān)閱讀

文章評論
發(fā)表評論

熱門文章 安裝紅帽子RedHat Linux9.0操作系統(tǒng)教程 安裝紅帽子RedHat Linux9.0操作系統(tǒng)教程 Tomcat9.0如何安裝_Tomcat9.0環(huán)境變量配置方法 Tomcat9.0如何安裝_Tomcat9.0環(huán)境變量配置方法 多種操作系統(tǒng)NTP客戶端配置 多種操作系統(tǒng)NTP客戶端配置 Linux操作系統(tǒng)修改IP Linux操作系統(tǒng)修改IP

相關(guān)下載

    人氣排行 Linux下獲取CPUID、硬盤序列號與MAC地址 dmidecode命令查看內(nèi)存型號 linux tc實現(xiàn)ip流量限制 安裝紅帽子RedHat Linux9.0操作系統(tǒng)教程 linux下解壓rar文件 lcx.exe、nc.exe、sc.exe入侵中的使用方法 Ubuntu linux 關(guān)機、重啟、注銷 命令 查看linux服務器硬盤IO讀寫負載