您的位置:首页 > 其它

binder内核缓冲区管理

2016-12-31 13:57 155 查看
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\n",

       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\n", 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\n", proc->pid, size);

return NULL;

}

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\n", proc->pid, size);

return NULL;

}

if (n == NULL) {

buffer = rb_entry(best_fit, struct binder_buffer, rb_node);

buffer_size = binder_buffer_size(proc, buffer);

}

if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC)

printk(KERN_INFO "binder: %d: binder_alloc_buf size %zd got buff"

       "er %p size %zd\n", proc->pid, size, buffer, buffer_size);

    /*

    #define PAGE_SHIFT   12

    #define PAGE_SIZE   (1UL << PAGE_SHIFT)

    #define PAGE_MASK   (~(PAGE_SIZE-1))

    */

    

has_page_addr =

(void *)(((uintptr_t)buffer->data + buffer_size) & PAGE_MASK);

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;

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);

buffer->free = 0;

binder_insert_allocated_buffer(proc, buffer);

if (buffer_size != size) {

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);

}

if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC)

printk(KERN_INFO "binder: %d: binder_alloc_buf size %zd got "

       "%p\n", proc->pid, size, 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\n", proc->pid, size,

       proc->free_async_space);

}

return buffer;

}


[size=16px]在分配内核缓冲区里面用,裁剪后新的内核缓冲区部分或者全部是不是有可能位于无效物理内存呢?

       假设裁剪后的buffer->data + buffer_size恰好对齐到页面边界,则此时内核缓冲区的结束地址也等于end_page_addr,那么此时binder_update_page_range(proc, 1, (void *)PAGE_ALIGN((uintptr_t)buffer->data), end_page_addr, NULL)分配物理内存时,裁剪后新的内核缓冲区结构体不就没有分配物理内存么?[/size]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: