binder内存管理
2019-05-30 11:07:29 0 举报
Android binder的内存管理
作者其他创作
大纲/内容
分配物理页面(allocate = 1)
计算has_page_addr和end_page_addr
释放物理页面,同时删除映射
N X PAGE_SIZE
(N+1) X PAGE_SIZE
binder_update_page_range(allocate = 0)
(N-1) X PAGE_SIZE
next-free == 1?
2、buffer在下一个binder_buffer所在的页面结束,此时end_page_addr has_page_end因为下一个binder_buffer所在的页面已经分配了物理页面,不能重复分配,因此只需要分配到前一个页面即可。即end_page_addr = has_page_addr
buffer
end_page_addr
找到比size大或者大小相等的binder_buffer
binder_buffer
next binder_buffer:data[0]
buffer size
prev-free == 1?
计算释放的start、end
将获取的binder_buffer从free_bufferss删除
调整颜色
添加到free_buffers红黑树中
yes
next_binder_buffer
binder_insert_free_buffer
计算实际需要分配的空间
binder_buffer_size
free_page_start = 1free_page_end = 1buffer_start_page(buffer)~buffer_end_page(buffer)+PAGE_SIZE两个页面没有其他binder_buffer的数据,可以释放掉
new_binder_buffer
当所申请的binder_buffer的结束刚好对齐页面,此时必然有end_page_addr =has_page_addr
binder_mmap
binder_buffer-free = 0
next binder_buffer
将用户空间和虚拟空间关联起来
插入节点
binder_free_buf
next_buffer
prev_binder_buffer
prev_buffer
buffer_end_page(prev) != buffer_end_page(buffer)
遍历红黑树,找到适合的节点位置
guard page
buffer_end_page(prev) != buffer_start_page(buffer)
proc-buffers指向的binder_buffer是根据虚拟地址递增的方式排列的,其地址是连续的,因此可以进行合并。
free_page_start = 1free_page_end = 0buffer_start_page(buffer)~buffer_start_page(buffer)+PAGE_SIZE那个页面没有其他binder_buffer的数据,可以释放掉
size非法检测
由于binder的buffer分配是以页面大小为单位进行分配,两者的关系如右图
list_add(&proc-buffers)
buffer_end_page(prev) == buffer_start_page(buffer)
free_page_start = 0free_page_end = 0此时buffer的头信息所在的两个页面都有其他binder_buffer的数据,不可以释放
has_page_addr
binder_update_page_range
sizeof binder_buffer-data
fix the rb_node
binder_delete_free_buffer
end_page_addr has_page_addr
free_page_start = 0free_page_end = 1此时buffer_end_page(buffer)~buffer_end_page(buffer)+PAGE_SIZE那个页面没有其他binder_buffer的数据,可以释放掉
将那块多出来的buffer置于free_buffers中进行管理
binder_update_page_range(allocate = 1)
buffer_end_page(buffer) == buffer_start_page(next)
binder_alloc_buf
vm_insert_page
buffer_size != size
alloc_page
mmap第一次只分配了一个页面大小的空间,实行按需分配
将新生成的binder_buffer插入到allocated_buffers红黑树中
释放物理页面,过程如右图
以上情况都是三个binder_buffer-free == 1,且buffer的binder_buffer头跨越了两个页面
binder_buffer:data[0]
(N+2) X PAGE_SIZE
buffer不是proc-buffers最后一个binder_buffer
内核虚拟地址与物理地址映射
binder_inset_allocated_buffer
get_vm_area
链表中下一个buffer是空闲的,则释放下一个buffer的物理页面,合并成一个binder_buffer
计算free_page_start和free_page_end
用户虚拟地址与物理地址映射
获取binder_buffer的大小
end_page_addr = has_page_addr
因为合并了,起始地址改变
如果所匹配出的binder_buffer的大小大于所要申请的大小,那么多出来的那部分只要大于一个struct binder_buffer结构的大小,就将它创建为一个新的空闲binder_bnuffer
buffer_end_page(buffer) != buffer_start_page(next)
分配页面
binder_buffer-free = 1
has_page_addr与end_page_addr都是页面对齐
set proc filed
has_page_addr:下一个binder_buffer所在的页面基址end_page_addr:本次分配的binder_buffer所在页面的结束地址
设置proc中buffer的相关字段信息
rb_insert_color
从用户控件拿到用户空间的虚拟地址,通过get_vm_area申请内核空间虚拟地址
size=ALIN(data_size)+ALIN(offsets_size)
buffer = prev
本流程按照linux-3.10进行分析
map_vm_area
遍历proc-free_buffers.rb_node
当所申请的binder_buffer的结束并没有页面对齐时就会有两种情况:1、buffer在下一个binder_buffer的前面的页面结束,此时end_page_addr = has_page_end
binder_buffer head
添加到proc-buffers中进行管理
rb_link_node
start = PAGE_ALIN(buffer-data),即从binder_buffer的头所在的下个页面开始申请
rb_erase(proc-allocated_buffers)
proc-user_buffer_offser
收藏
收藏
0 条评论
下一页