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     ,               。(  ,  )