diff options
Diffstat (limited to 'drivers/android')
-rw-r--r-- | drivers/android/binder_alloc.c | 55 | ||||
-rw-r--r-- | drivers/android/binder_alloc.h | 12 | ||||
-rw-r--r-- | drivers/android/binderfs.c | 31 |
3 files changed, 39 insertions, 59 deletions
diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c index 9b1778c00610..1c39cfce32fa 100644 --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c @@ -208,8 +208,8 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate, } } - if (need_mm && mmget_not_zero(alloc->vma_vm_mm)) - mm = alloc->vma_vm_mm; + if (need_mm && mmget_not_zero(alloc->mm)) + mm = alloc->mm; if (mm) { mmap_read_lock(mm); @@ -309,34 +309,13 @@ err_no_vma: return vma ? -ENOMEM : -ESRCH; } - -static inline void binder_alloc_set_vma(struct binder_alloc *alloc, - struct vm_area_struct *vma) -{ - unsigned long vm_start = 0; - - /* - * Allow clearing the vma with holding just the read lock to allow - * munmapping downgrade of the write lock before freeing and closing the - * file using binder_alloc_vma_close(). - */ - if (vma) { - vm_start = vma->vm_start; - mmap_assert_write_locked(alloc->vma_vm_mm); - } else { - mmap_assert_locked(alloc->vma_vm_mm); - } - - alloc->vma_addr = vm_start; -} - static inline struct vm_area_struct *binder_alloc_get_vma( struct binder_alloc *alloc) { struct vm_area_struct *vma = NULL; if (alloc->vma_addr) - vma = vma_lookup(alloc->vma_vm_mm, alloc->vma_addr); + vma = vma_lookup(alloc->mm, alloc->vma_addr); return vma; } @@ -401,15 +380,15 @@ static struct binder_buffer *binder_alloc_new_buf_locked( size_t size, data_offsets_size; int ret; - mmap_read_lock(alloc->vma_vm_mm); + mmap_read_lock(alloc->mm); if (!binder_alloc_get_vma(alloc)) { - mmap_read_unlock(alloc->vma_vm_mm); + mmap_read_unlock(alloc->mm); binder_alloc_debug(BINDER_DEBUG_USER_ERROR, "%d: binder_alloc_buf, no vma\n", alloc->pid); return ERR_PTR(-ESRCH); } - mmap_read_unlock(alloc->vma_vm_mm); + mmap_read_unlock(alloc->mm); data_offsets_size = ALIGN(data_size, sizeof(void *)) + ALIGN(offsets_size, sizeof(void *)); @@ -793,7 +772,7 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc, buffer->free = 1; binder_insert_free_buffer(alloc, buffer); alloc->free_async_space = alloc->buffer_size / 2; - binder_alloc_set_vma(alloc, vma); + alloc->vma_addr = vma->vm_start; return 0; @@ -823,7 +802,7 @@ void binder_alloc_deferred_release(struct binder_alloc *alloc) buffers = 0; mutex_lock(&alloc->mutex); BUG_ON(alloc->vma_addr && - vma_lookup(alloc->vma_vm_mm, alloc->vma_addr)); + vma_lookup(alloc->mm, alloc->vma_addr)); while ((n = rb_first(&alloc->allocated_buffers))) { buffer = rb_entry(n, struct binder_buffer, rb_node); @@ -873,8 +852,8 @@ void binder_alloc_deferred_release(struct binder_alloc *alloc) kfree(alloc->pages); } mutex_unlock(&alloc->mutex); - if (alloc->vma_vm_mm) - mmdrop(alloc->vma_vm_mm); + if (alloc->mm) + mmdrop(alloc->mm); binder_alloc_debug(BINDER_DEBUG_OPEN_CLOSE, "%s: %d buffers %d, pages %d\n", @@ -931,13 +910,13 @@ void binder_alloc_print_pages(struct seq_file *m, * read inconsistent state. */ - mmap_read_lock(alloc->vma_vm_mm); + mmap_read_lock(alloc->mm); if (binder_alloc_get_vma(alloc) == NULL) { - mmap_read_unlock(alloc->vma_vm_mm); + mmap_read_unlock(alloc->mm); goto uninitialized; } - mmap_read_unlock(alloc->vma_vm_mm); + mmap_read_unlock(alloc->mm); for (i = 0; i < alloc->buffer_size / PAGE_SIZE; i++) { page = &alloc->pages[i]; if (!page->page_ptr) @@ -983,7 +962,7 @@ int binder_alloc_get_allocated_count(struct binder_alloc *alloc) */ void binder_alloc_vma_close(struct binder_alloc *alloc) { - binder_alloc_set_vma(alloc, NULL); + alloc->vma_addr = 0; } /** @@ -1020,7 +999,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item, index = page - alloc->pages; page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE; - mm = alloc->vma_vm_mm; + mm = alloc->mm; if (!mmget_not_zero(mm)) goto err_mmget; if (!mmap_read_trylock(mm)) @@ -1089,8 +1068,8 @@ static struct shrinker binder_shrinker = { void binder_alloc_init(struct binder_alloc *alloc) { alloc->pid = current->group_leader->pid; - alloc->vma_vm_mm = current->mm; - mmgrab(alloc->vma_vm_mm); + alloc->mm = current->mm; + mmgrab(alloc->mm); mutex_init(&alloc->mutex); INIT_LIST_HEAD(&alloc->buffers); } diff --git a/drivers/android/binder_alloc.h b/drivers/android/binder_alloc.h index 1e4fd37af5e0..0f811ac4bcff 100644 --- a/drivers/android/binder_alloc.h +++ b/drivers/android/binder_alloc.h @@ -74,11 +74,10 @@ struct binder_lru_page { /** * struct binder_alloc - per-binder proc state for binder allocator - * @vma: vm_area_struct passed to mmap_handler - * (invarient after mmap) - * @tsk: tid for task that called init for this proc - * (invariant after init) - * @vma_vm_mm: copy of vma->vm_mm (invarient after mmap) + * @mutex: protects binder_alloc fields + * @vma_addr: vm_area_struct->vm_start passed to mmap_handler + * (invariant after mmap) + * @mm: copy of task->mm (invariant after open) * @buffer: base of per-proc address space mapped via mmap * @buffers: list of all buffers for this proc * @free_buffers: rb tree of buffers available for allocation @@ -101,7 +100,7 @@ struct binder_lru_page { struct binder_alloc { struct mutex mutex; unsigned long vma_addr; - struct mm_struct *vma_vm_mm; + struct mm_struct *mm; void __user *buffer; struct list_head buffers; struct rb_root free_buffers; @@ -109,7 +108,6 @@ struct binder_alloc { size_t free_async_space; struct binder_lru_page *pages; size_t buffer_size; - uint32_t buffer_free; int pid; size_t pages_high; bool oneway_spam_detected; diff --git a/drivers/android/binderfs.c b/drivers/android/binderfs.c index 588d753a7a19..09b2ce7e4c34 100644 --- a/drivers/android/binderfs.c +++ b/drivers/android/binderfs.c @@ -39,7 +39,6 @@ #define FIRST_INODE 1 #define SECOND_INODE 2 #define INODE_OFFSET 3 -#define INTSTRLEN 21 #define BINDERFS_MAX_MINOR (1U << MINORBITS) /* Ensure that the initial ipc namespace always has devices available. */ #define BINDERFS_MAX_MINOR_CAPPED (BINDERFS_MAX_MINOR - 4) @@ -340,22 +339,10 @@ static int binderfs_show_options(struct seq_file *seq, struct dentry *root) return 0; } -static void binderfs_put_super(struct super_block *sb) -{ - struct binderfs_info *info = sb->s_fs_info; - - if (info && info->ipc_ns) - put_ipc_ns(info->ipc_ns); - - kfree(info); - sb->s_fs_info = NULL; -} - static const struct super_operations binderfs_super_ops = { .evict_inode = binderfs_evict_inode, .show_options = binderfs_show_options, .statfs = simple_statfs, - .put_super = binderfs_put_super, }; static inline bool is_binderfs_control_device(const struct dentry *dentry) @@ -785,11 +772,27 @@ static int binderfs_init_fs_context(struct fs_context *fc) return 0; } +static void binderfs_kill_super(struct super_block *sb) +{ + struct binderfs_info *info = sb->s_fs_info; + + /* + * During inode eviction struct binderfs_info is needed. + * So first wipe the super_block then free struct binderfs_info. + */ + kill_litter_super(sb); + + if (info && info->ipc_ns) + put_ipc_ns(info->ipc_ns); + + kfree(info); +} + static struct file_system_type binder_fs_type = { .name = "binder", .init_fs_context = binderfs_init_fs_context, .parameters = binderfs_fs_parameters, - .kill_sb = kill_litter_super, + .kill_sb = binderfs_kill_super, .fs_flags = FS_USERNS_MOUNT, }; |