android binder駆動ソース分析(二)
6521 ワード
。
binder buffer proc( ) buffer , 。 , , , buffer , free_buffers 。 binder_alloc_buf :
static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc,
size_t data_size, size_t offsets_size, int is_async)
{
struct rb_node *n = proc->free_buffers.rb_node;
struct binder_buffer *buffer;
size_t buffer_size;
struct rb_node *best_fit = NULL;
void *has_page_addr;
void *end_page_addr;
size_t size;
if (proc->vma == NULL) {
printk(KERN_ERR "binder: %d: binder_alloc_buf, no vma
",
proc->pid);
return NULL;
}
size = ALIGN(data_size, sizeof(void *)) +
ALIGN(offsets_size, sizeof(void *));
if (size < data_size || size < offsets_size) {
binder_user_error("binder: %d: got transaction with invalid "
"size %zd-%zd
", proc->pid, data_size, offsets_size);
return NULL;
}
if (is_async &&
proc->free_async_space < size + sizeof(struct binder_buffer)) {
if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC)
printk(KERN_ERR "binder: %d: binder_alloc_buf size %zd f"
"ailed, no async space left
", proc->pid, size);
return NULL;
}
/* , rb size buffer,size=data_size+offsets_size */
while (n) {
buffer = rb_entry(n, struct binder_buffer, rb_node);
BUG_ON(!buffer->free);
buffer_size = binder_buffer_size(proc, buffer);
if (size < buffer_size) {
best_fit = n;
n = n->rb_left;
} else if (size > buffer_size)
n = n->rb_right;
else {
best_fit = n;
break;
}
}
if (best_fit == NULL) {
printk(KERN_ERR "binder: %d: binder_alloc_buf size %zd failed, "
"no address space
", proc->pid, size);
return NULL;
}
/* , n=NULL, ,buffer , */
if (n == NULL) {buffer = rb_entry(best_fit, struct binder_buffer, rb_node);buffer_size = binder_buffer_size(proc, buffer);}/*buffer , page , buffer data+buffer_size , */has_page_addr =(void *)(((uintptr_t)buffer->data + buffer_size) & PAGE_MASK);
/* size , , 。size + sizeof(struct binder_buffer)+4 , buffer size
binder_buffer , , , binder_buffer , , ,buffer , 。 。
*/
if (n == NULL) {
if (size + sizeof(struct binder_buffer) + 4 >= buffer_size)
buffer_size = size; /* no room for other buffers */
else
buffer_size = size + sizeof(struct binder_buffer);
}
/* , */
end_page_addr =
(void *)PAGE_ALIGN((uintptr_t)buffer->data + buffer_size);
if (end_page_addr > has_page_addr)
end_page_addr = has_page_addr;// end ,
/* , , , vma( ) vm( ) */
if (binder_update_page_range(proc, 1,
(void *)PAGE_ALIGN((uintptr_t)buffer->data), end_page_addr, NULL)
)
return NULL;
rb_erase(best_fit, &proc->free_buffers);// free
buffer->free = 0;
binder_insert_allocated_buffer(proc, buffer);
if (buffer_size != size) {/* buffer 。 buffer, 44B , 44B 。 buffer buffer free */
struct binder_buffer *new_buffer = (void *)buffer->data + size;
list_add(&new_buffer->entry, &buffer->entry);
new_buffer->free = 1;
binder_insert_free_buffer(proc, new_buffer);
}
buffer->data_size = data_size;
buffer->offsets_size = offsets_size;
buffer->async_transaction = is_async;
if (is_async) {
proc->free_async_space -= size + sizeof(struct binder_buffer);
if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC_ASYNC)
printk(KERN_INFO "binder: %d: binder_alloc_buf size %zd "
"async free %zd
", proc->pid, size,
proc->free_async_space);
}
return buffer;
}
log :
binder_open: 31:31,name=servicemanager
[ binder_mmap ] vonnyfly(lfeng^-^)~~~~~~~~~~~binder_buffer size=40
binder_mmap: 31 40009000-40029000 (128 K) vma 75 pagep 30f vma
[ binder_mmap ] vonnyfly(lfeng^-^)~~~~~~~~~~~vma->vm_start=0x40009000,proc->buffer=0xc6840000
binder: 31: allocate pages c6840000-c6841000 ,
binder: 31: add free buffer, size 131032, at c6840000 free
binder: 31: buffer_size 1ffd8---buffer->data=c6840028,(uintptr_t)buffer->data + buffer_size=c6860000,has_page_addr=c6860000
binder: 31: binder_alloc_buf size 128 got buffer c6840000 buffer_size 168--data_size=124,offsets_size=4---buffer->data=c6840028,has_page_addr=c6860000,end_page_addr=c6841000
binder: 31: allocate pages c6841000-c6841000 binder_free_buf , log , size=128B, , mmap
binder: 31: add free buffer, size 130864, at c68400a8 130864B=131032 - 128 -40( )。 0xc6840000+128=0xc68400a8 free 。 :
binder: 31: binder_free_buf c6840000 size 128 buffer_size 128
binder: 31: free pages c6841000-c6840000
binder: 31: merge free, buffer c68400a8 share page with c6840000
binder: 31: add free buffer, size 131032, at c6840000
binder: 31: buffer_size 1ffd8---buffer->data=c6840028,(uintptr_t)buffer->data + buffer_size=c6860000,has_page_addr=c6860000
binder: 31: binder_alloc_buf size 116 got buffer c6840000 buffer_size 156--data_size=112,offsets_size=4---buffer->data=c6840028,has_page_addr=c6860000,end_page_addr=c6841000
binder: 31: allocate pages c6841000-c6841000
binder: 31: add free buffer, size 130876, at c684009c
binder: 31: binder_free_buf c6840000 size 116 buffer_size 116
binder: 31: free pages c6841000-c6840000
binder: 31: merge free, buffer c684009c share page with c6840000
binder: 31: add free buffer, size 131032, at c6840000
, binder_ioctl , 。( , )