ION内存管理Word下载.docx
- 文档编号:18521209
- 上传时间:2022-12-18
- 格式:DOCX
- 页数:31
- 大小:43.10KB
ION内存管理Word下载.docx
《ION内存管理Word下载.docx》由会员分享,可在线阅读,更多相关《ION内存管理Word下载.docx(31页珍藏版)》请在冰豆网上搜索。
IONAPIs
用户空间API
定义了6种ioctl接口,可以与用户应用程序交互。
∙ION_IOC_ALLOC:
分配存
∙ION_IOC_FREE:
释放存
∙ION_IOC_MAP:
获取文件描述符进展mmap
("
在code中未使用这个定义)
∙ION_IOC_SHARE:
创立文件描述符来实现共享存
∙ION_IOC_IMPORT:
获取文件描述符
∙ION_IOC_CUSTOM:
调用用户自定义的ioctl
ION_IOC_SHARE及ION_IOC_IMPORT是基于DMABUF实现的,所以当共享进程获取文件描述符后,可以直接调用mmap来操作共享存。
mmap实现由DMABUF子系统调用ION子系统中mmap回调函数完成。
核空间API
核驱动也可以注册为一个ION的客户端〔client〕,可以选择使用哪种类型的heap来申请存。
∙ion_client_create:
分配一个客户端。
∙ion_client_destroy:
释放一个客户端及绑定在它上面的所有ionhandle.
ionhandle:
这里每个ionhandle映射到一个buffer中,每个buffer关联一个heap。
也就是说一个客户端可以操作多块buffer。
Buffer申请及释放函数:
∙ion_alloc:
申请ion存,返回ionhandle
∙ion_free:
释放ionhandle
ION通过handle来管理buffer,驱动需要可以访问到buffer的地址。
ION通过下面的函数来到达这个目的
∙ion_phys:
返回buffer的物理地址(address)及大小(size)
∙ion_map_kernel:
给指定的buffer创立核存映射
∙ion_unmap_kernel:
销毁指定buffer的核存映射
∙ion_map_dma:
为指定buffer创立dma映射,返回sglist〔scatter/gatherlist〕
∙ion_unmap_dma:
销毁指定buffer的dma映射
ION是通过handle而非buffer地址来实现驱动间共享存,用户空间共享存也是利用同样原理。
∙ion_share:
givenahandle,obtainabuffertopasstootherclients
∙ion_import:
givenanbufferinanotherclient,importit
∙ion_import_fd:
givenanfdobtainedviaION_IOC_SHAREioctl,importit
HeapAPI
Heap接口定义[drivers/gpu/ion/ion_priv.h]
这些接口不是暴露给驱动或者用户应用程序的。
/**
*struction_heap_ops-opstooperateonagivenheap
*allocate:
allocatememory
*free:
freememory
*physgetphysicaladdressofabuffer(onlydefineonphysicallycontiguousheaps)
*map_dmamapthememoryfordmatoascatterlist
*unmap_dmaunmapthememoryfordma
*map_kernelmapmemorytothekernel
*unmap_kernelunmapmemorytothekernel
*map_usermapmemorytouserspace
*/
struction_heap_ops{
int(*allocate)(struction_heap*heap,struction_buffer*buffer,unsignedlonglen,unsignedlongalign,unsignedlongflags);
void(*free)(struction_buffer*buffer);
int(*phys)(struction_heap*heap,struction_buffer*buffer,ion_phys_addr_t*addr,size_t*len);
structscatterlist*(*map_dma)(struction_heap*heap,struction_buffer*buffer);
void(*unmap_dma)(struction_heap*heap,struction_buffer*buffer);
void*(*map_kernel)(struction_heap*heap,struction_buffer*buffer);
void(*unmap_kernel)(struction_heap*heap,struction_buffer*buffer);
int(*map_user)(struction_heap*mapper,struction_buffer*buffer,structvm_area_struct*vma);
};
IONdebug
ION在/sys/kernel/debug/ion/提供一个debugfs接口。
每个heap都有自己的debugfs目录,client存使用状况显示在/sys/kernel/debug/ion/<
<
heapname>
>
$cat/sys/kernel/debug/ion/ion-heap-1
clientpidsize
test_ion289016384
每个由pid标识的client也有一个debugfs目录/sys/kernel/debug/ion/<
pid>
$cat/sys/kernel/debug/ion/2890
heap_name:
size_in_bytes
ion-heap-1:
4096011
参考文献
1.
2.android之ION存管理器〔2〕--cache
ION如实现buffer共享的思路倒是很清晰的,但是深入代码研究,发现ION是依赖于DMAMapping的,而DMAmapping模块对我而言还是挺复杂的,看这个模块遇到的第一个问题就是cache。
既然是DMAmapping,直接将申请的buffer设置为non-cacheable不就行了.这样就可以保证CPU通过DMA读写缓冲区的一致性了。
为什么还有ConsistentDMAmappings和StreamingDMAmappings一说呢.下面先介绍一下Cache的概念。
Cache
Cache写机制:
Write-through与Write-back[5]
Cache写机制分为writethrough和writeback两种。
∙Write-through-Writeisdonesynchronouslybothtothecacheandtothebackingstore.
∙Write-back(orWrite-behind)–Writingisdoneonlytothecache.Amodifiedcacheblockiswrittenbacktothestore,justbeforeitisreplaced.
Write-through〔直写模式〕在数据更新时,同时写入缓存Cache和后端存储。
此模式的优点是操作简单;
缺点是因为数据修改需要同时写入存储,数据写入速度较慢。
Write-back〔回写模式〕在数据更新时只写入缓存Cache。
只在数据被替换出缓存时,被修改的缓存数据才会被写到后端存储。
此模式的优点是数据写入速度快,因为不需要写存储;
缺点是一旦更新后的数据未被写入存储时出现系统掉电的情况,数据将无法找回。
Write-misses写缺失的处理式
对于写操作,存在写入缓存缺失数据的情况,这时有两种处理式:
∙Writeallocate(akaFetchonwrite)–Datumatthemissed-writelocationisloadedtocache,followedbyawrite-hitoperation.Inthisapproach,writemissesaresimilartoread-misses.
∙No-writeallocate(akaWrite-no-allocate,Writearound)–Datumatthemissed-writelocationisnotloadedtocache,andiswrittendirectlytothebackingstore.Inthisapproach,actuallyonlysystemreadsarebeingcached.
Writeallocate式将写入位置读入缓存,然后采用write-hit〔缓存命中写入〕操作。
写缺失操作与读缺失操作类似。
No-writeallocate式并不将写入位置读入缓存,而是直接将数据写入存储。
这种式下,只有读操作会被缓存。
无论是Write-through还是Write-back都可以使用写缺失的两种式之一。
只是通常Write-back采用Writeallocate式,而Write-through采用No-writeallocate式;
因为屡次写入同一缓存时,Writeallocate配合Write-back可以提升性能;
而对于Write-through则没有帮助。
Cache的两个函数
--Flush把Cache容写回Memory,当Cache为Writethrough,不需要Flush
--Invalidate把Cache容直接丢掉不要。
Cache的使用场合
当有DMA在使用memory的时候,一般要用到cache的处理。
因为DMA在访问memory时是不经过cache的。
比拟典型的比方在Ethernet,wireless,USB等driver里,DMA会操作descriptors和packetbuffers,Driver要做这些处理
--如果driver使用descripter和packetbuffer的地址都是cache的地址,则
a).Driver在读descripter里一些状态,有没有收到包时,要对descripter当前构造里的容做cacheinvalidate,收到packet后,也要对packetbuffer做cacheinvalidate
b).Driver在写descripter里一些状态,要发送包时,要对descripter当前构造里的容做cacheflush,发送packet时,也要对packetbuffer做cacheflush
--有些driver会对descripter使用uncache地址,则上面两种情况里invalidate/flush就不用做了。
一般很少会对packetbuffer也用uncache地址的,因为对packet容的处理将会很频繁,使用uncache会很慢。
而descripter一般由于构造比拟小,如果也使用cache地址的话,做invalidate/flush的时间消耗可能会比uncache的还要多。
下面文字采自于[6]
CB位的具体含义
00无cache,无写缓冲(strongly-ordered);
任对memory的读写都反映到总线上。
对memory的操作过程中CPU需要等待。
01无cache,有写缓冲(shareabledevice);
读操作直接反映到总线上;
写操作,CPU将数据写入到写缓冲后继续运行,由写缓冲进展写回操作。
10有cache,写通模式(write-through);
读操作首先考虑cachehit;
写操作时直接将数据写入写缓冲,如果同时出现cachehit,则也更新cache。
11有cache,写回模式(write-back);
写操作也首先考虑cachehit。
处理流程图
Write-through模式处理流程:
AWrite-ThroughcachewithNo-WriteAllocation
Write-back模式处理流程:
4."
linu*设备驱动程序"
第三版JONATHANCORBET
5.witma*./cache-writing-policies.html
6.ARMArchitectureReferenceManual,ARMv7-AandARMv7-Redition
DDI0406C
3.linu*之DMAAPI--通用设备的动态DMA映射
文描述DMAAPI。
更详细的介绍请参看Documentation/DMA-API-HOWTO.t*t。
API分为两局部,第一局部描述API,第二局部描述可以支持非一致性存机器的扩展API。
你应该使用第一局部所描述的API,除非你知道你的驱动必须要支持非一致性平台。
第一局部DMAAPI
为了可以引用DMAAPI,你必须*include<
linu*/dma-mapping.h>
1-1使用大块DMA一致性缓冲区〔dma-coherentbuffers〕
void*dma_alloc_coherent(structdevice*dev,size_tsize,
dma_addr_t*dma_handle,gfp_tflag)
一致性存:
设备对一块存进展写操作,处理器可以立即进展读操作,而无需担忧处理器高速缓存(cache)的影响。
同样的,处理器对一块存进展些操作,设备可以立即进展读操作。
〔在告诉设备读存时,你可能需要确定刷新处理器的写缓存。
〕
此函数申请一段大小为size字节的一致性存,返回两个参数。
一个是dma_handle,它可以用作这段存的物理地址。
另一个是指向被分配存的指针〔处理器的虚拟地址〕。
注意:
由于在*些平台上,使用一致性存代价很高,比方最小的分配长度为一个页。
因此你应该尽可能合并申请一致性存的请求。
最简单的方法是使用dma_pool函数调用〔详见下文〕。
参数flag〔仅存在于dma_alloc_coherent中〕运行调用者定义申请存时的GFP_flags〔详见kmalloc〕。
void*dma_zalloc_coherent(structdevice*dev,size_tsize,
对dma_alloc_coherent()的封装,如果存分配成功,则返回清零的存。
voiddma_free_coherent(structdevice*dev,size_tsize,void*cpu_addr,
dma_addr_tdma_handle)
释放之前申请的一致性存。
dev,size及dma_handle必须和申请一致性存的函数参数一样。
cpu_addr必须为申请一致性存函数的返回虚拟地址。
和其他存分配函数不同,这些函数必须要在中断使能的情况下使用。
1-2使用小块DMA一致性缓冲区
如果要使用这局部DMAAPI,必须*include<
linu*/dmapool.h>
。
多驱动程序需要为DMA描述符或者I/O存申请大量小块DMA一致性存。
你可以使用DMA存池,而不是申请以页为单位的存块或者调用dma_alloc_coherent()。
这种机制有点像structkmem_cache,只是它利用了DMA一致性存分配器,而不是调用__get_free_pages()。
同样地,DMA存池知道通用硬件的对齐限制,比方队列头需要N字节对齐。
structdma_pool*dma_pool_create(constchar*name,structdevice*dev,
size_tsize,size_talign,size_talloc);
create()函数为设备初始化DMA一致性存的存池。
它必须要在可睡眠上下文调用。
name为存池的名字〔就像structkmem_cachename一样〕。
dev及size就如dma_alloc_coherent()参数一样。
align为设备硬件需要的对齐大小〔单位为字节,必须为2的幂次〕。
如果设备没有边界限制,可以设置该参数为0。
如果设置为4096,则表示从存池分配的存不能超过4K字节的边界。
void*dma_pool_alloc(structdma_pool*pool,gfp_tgfp_flags,
dma_addr_t*dma_handle);
从存池中分配存。
返回的存同时满足申请的大小及对齐要求。
设置GFP_ATOMIC可以确保存分配被block,设置GFP_KERNEL〔不能再中断上下文,不会保持SMP锁〕允存分配被block。
和dma_alloc_coherent()一样,这个函数会返回两个值:
一个值是cpu可以使用的虚拟地址,另一个值是存池设备可以使用的dma物理地址。
voiddma_pool_free(structdma_pool*pool,void*vaddr,
dma_addr_taddr);
返回存给存池。
参数pool为传递给dma_pool_alloc()的pool,参数vaddr及addr为dma_pool_alloc()的返回值。
voiddma_pool_destroy(structdma_pool*pool);
存池析构函数用于释放存池的资源。
这个函数在可睡眠上下文调用。
请确认在调用此函数时,所有从该存池申请的存必须都要归还给存池。
1-3DMA寻址限制
intdma_supported(structdevice*dev,u64mask)
用来检测该设备是否支持掩码所表示的DMA寻址能力。
比方mask为0*0FFFFFF,则检测该设备是否支持24位寻址。
返回1表示支持,0表示不支持。
该函数很少用于检测是否掩码为可用的,它不会改变当前掩码设置。
它是一个部API而非供驱动者使用的外部API。
intdma_set_mask(structdevice*dev,u64mask)
检测该掩码是否合法,如果合法,则更新设备参数。
即更新设备的寻址能力。
返回0表示成功,返回负值表示失败。
intdma_set_coherent_mask(structdevice*dev,u64mask)
u64dma_get_required_mask(structdevice*dev)
该函数返回平台可以高效工作的掩码。
通常这意味着返回掩码是可以寻址到所有存的最小值。
检查该值可以让DMA描述符的大小尽量的小。
请求平台需要的掩码并不会改变当前掩码。
如果你想利用这点,可以利用改返回值通过dma_set_mask()设置当前掩码。
1-4流式DMA映射
dma_addr_tdma_map_single(structdevice*dev,void*cpu_addr,size_tsize,
enumdma_data_directiondirection)
映射一块处理器的虚拟地址,这样可以让外设访问。
该函数返回存的物理地址。
在dma_API中强烈建议使用表示DMA传输向的枚举类型。
DMA_NONE
仅用于调试目的
DMA_TO_DEVICE
数据从存传输到设备,可认为是写操作。
DMA_FROM_DEVICE
数据从设备传输到存,可认为是读操作。
DMA_BIDIRECTIONAL
不清楚传输向则可用该类型。
请注意:
并非一台机器上所有的存区域都可以用这个API映射。
进一步说,对于核连续虚拟地址空间所对应的物理地址并不一定连续〔比方这段地址空间由vmalloc申请〕。
因为这种函数并未提供任分散/聚集能力,因此用户在企图映射一块非物理连续的存时,会返回失败。
基于此原因,如果想使用该函数,则必须确保缓冲区的物理存连续〔比方使用kmalloc〕。
更进一步,所申请存的物理地址必须要在设备的dma_mask寻址围〔dma_mask表示与设备寻址能力对应的位〕。
为了确保由kmalloc申请的存在dma_mas
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ION 内存 管理