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]
相关文章推荐
- binder内核缓冲区管理
- binder内核缓冲区管理
- binder内核缓冲区管理
- binder内核缓冲区管理
- binder内核缓冲区管理
- binder内核缓冲区管理
- 【存储管理】内核缓冲区的管理
- linux 内核缓冲区管理之slab机制
- 思考mysql内核之初级系列4--innodb缓冲区管理(摘自老杨)
- Binder进程间通信(五)----内核虚拟地址空间管理
- 内核缓冲区的管理
- 【存储管理】内核缓冲区的管理概述
- 内核缓冲区slab的管理
- linux内核参数调优,缓冲区调整,tcp/udp连接管理,保持,释放优化,gossary,terms
- nt内核里的对象管理[1]:HANDLE和对象头
- android中的Binder(android内核学习记录)
- 进程管理之内核抢占(一)
- 一个Linux内核利用init_task进行进程管理的简单例子
- C标准缓冲区和内核缓冲区
- 读深入理解Linux内核 (第8章 内存管理, 第一部分 --- 页的管理)