android: binder: fixes for memory allocator change
v2 cover android: binder: fixes for memory allocator change
This patchset resolves a potential deadlock between lru lock, task lock and dentry lock reported by lockdep. It also fixes the null pointer dereference in kernel debug message in binder_alloc.c.
Unused vma argument is removed, and binder shrinker is made static.
android: binder: Don't get mm from task
android: binder: Fix null ptr dereference in debug msg
android: binder: Remove unused vma argument
android: binder: Change binder_shrinker to static
v2: combines the version 1 of two separate patches and reorder the commits so that the first two can be applied to 4.14.
drivers/android/binder_alloc.c | 40 +++++++++++++++++----------------------- drivers/android/binder_alloc.h | 1 -
2 files changed, 17 insertions(+), 24 deletions(-)
PATCH v2 1/4 android: binder: Don't get mm from task
Use binder_alloc struct's mm_struct rather than getting a reference to the mm struct through get_task_mm to avoid a potential deadlock between lru lock, task lock and dentry lock, since a thread can be holding the task lock and the dentry lock while trying to acquire the lru lock.
--- drivers/android/binder_alloc.c | 22 +++++++++------------- drivers/android/binder_alloc.h | 1 - 2 files changed, 9 insertions(+), 14 deletions(-)
drivers/android/binder_alloc.c +9 -13
@@ -215,17 +215,12 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate, } } -if (!vma && need_mm) - mm =get_task_mm (alloc->tsk); +if (!vma && need_mm &&mmget_not_zero (alloc->vma_vm_mm)) + mm = alloc->vma_vm_mm;if (mm) {down_write (&mm->mmap_sem); vma = alloc->vma; -if (vma && mm != alloc->vma_vm_mm) { -pr_err ("%d: vma mm and task mm mismatch\n" , - alloc->pid); - vma =NULL ; - } }if (!vma && need_mm) {
@@ -720,6 +715,7 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc,barrier (); alloc->vma = vma; alloc->vma_vm_mm = vma->vm_mm; +mmgrab (alloc->vma_vm_mm);return 0 ;
@@ -795,6 +791,8 @@ void binder_alloc_deferred_release(struct binder_alloc *alloc)vfree (alloc->buffer); }mutex_unlock (&alloc->mutex); +if (alloc->vma_vm_mm) +mmdrop (alloc->vma_vm_mm); binder_alloc_debug(BINDER_DEBUG_OPEN_CLOSE, "%s: %d buffers %d, pages %d\n",
@@ -889,7 +887,6 @@ int binder_alloc_get_allocated_count(struct binder_alloc *alloc)void binder_alloc_vma_close (struct binder_alloc *alloc) {WRITE_ONCE (alloc->vma,NULL ); -WRITE_ONCE (alloc->vma_vm_mm,NULL ); }/**
@@ -926,9 +923,9 @@ enum lru_status binder_alloc_free_page(struct list_head *item, page_addr = (uintptr_t )alloc->buffer + index *PAGE_SIZE ; vma = alloc->vma;if (vma) { - mm =get_task_mm (alloc->tsk); -if (!mm) - goto err_get_task_mm_failed; +if (!mmget_not_zero (alloc->vma_vm_mm)) + goto err_mmget; + mm = alloc->vma_vm_mm;if (!down_write_trylock (&mm->mmap_sem)) goto err_down_write_mmap_sem_failed; }
@@ -963,7 +960,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item, err_down_write_mmap_sem_failed:mmput_async (mm); -err_get_task_mm_failed: +err_mmget: err_page_already_freed:mutex_unlock (&alloc->mutex); err_get_alloc_mutex_failed:
@@ -1002,7 +999,6 @@ struct shrinker binder_shrinker = {*/ void binder_alloc_init (struct binder_alloc *alloc) { - alloc->tsk = current->group_leader; alloc->pid = current->group_leader->pid;mutex_init (&alloc->mutex);INIT_LIST_HEAD (&alloc->buffers);
drivers/android/binder_alloc.h +0 -1
@@ -100,7 +100,6 @@ struct binder_lru_page {*/ struct binder_alloc {struct mutex mutex; -struct task_struct *tsk;struct vm_area_struct *vma;struct mm_struct *vma_vm_mm;void *buffer;
Signature · 1 line
2.11.0 (Apple Git-81)
Greg Kroah-Hartman
maintainerRe: [PATCH v2 1/4] android: binder: Don't get mm from task
Quoted 6 lines · Sherry Yang
Use
binder_allocstruct'smm_structrather than getting a reference to the mm struct throughget_task_mmto avoid a potential deadlock between lru lock, task lock and dentry lock, since a thread can be holding the task lock and the dentry lock while trying to acquire the lru lock.
Quoted 6 lines
Acked-by Arve Hjønnevåg <[email protected]>Signed-off-by Sherry Yang <[email protected]>--- drivers/android/binder_alloc.c | 22 +++++++++------------- drivers/android/binder_alloc.h | 1 - 2 files changed, 9 insertions(+), 14 deletions(-)
I've applied these first 2 patches, but patches 3 and 4 I have already applied to my char-misc-next tree, right?
thanks,
greg k-h
Arve Hjønnevåg
maintainerRe: [PATCH v2 1/4] android: binder: Don't get mm from task
Quoted 14 lines · Greg Kroah-Hartman
Quoted 6 lines · Sherry Yang
Use
binder_allocstruct'smm_structrather than getting a reference to the mm struct throughget_task_mmto avoid a potential deadlock between lru lock, task lock and dentry lock, since a thread can be holding the task lock and the dentry lock while trying to acquire the lru lock.Quoted 6 lines
Acked-by Arve Hjønnevåg <[email protected]>Signed-off-by Sherry Yang <[email protected]>--- drivers/android/binder_alloc.c | 22 +++++++++------------- drivers/android/binder_alloc.h | 1 - 2 files changed, 9 insertions(+), 14 deletions(-)
Quoted 6 lines
I've applied these first 2 patches, but patches 3 and 4 I have already applied to my char-misc-next tree, right?
thanks,
greg k-h
I would expect you got a merge conflict from one of those. Using patch 3 and 4 in from this patchset should avoid that conflict if your eventual 4.15 branch is not based on your current char-misc-next branch.
Signature · 1 line
Arve Hjønnevåg
Greg Kroah-Hartman
maintainerRe: [PATCH v2 1/4] android: binder: Don't get mm from task
Quoted 19 lines · Arve Hjønnevåg
Quoted 17 lines · Greg Kroah-Hartman
Quoted 6 lines · Sherry Yang
Use
binder_allocstruct'smm_structrather than getting a reference to the mm struct throughget_task_mmto avoid a potential deadlock between lru lock, task lock and dentry lock, since a thread can be holding the task lock and the dentry lock while trying to acquire the lru lock.Quoted 6 lines
Acked-by Arve Hjønnevåg <[email protected]>Signed-off-by Sherry Yang <[email protected]>--- drivers/android/binder_alloc.c | 22 +++++++++------------- drivers/android/binder_alloc.h | 1 - 2 files changed, 9 insertions(+), 14 deletions(-)I've applied these first 2 patches, but patches 3 and 4 I have already applied to my char-misc-next tree, right?
Quoted 8 lines
Quoted 3 lines
thanks,
greg k-h
I would expect you got a merge conflict from one of those. Using patch 3 and 4 in from this patchset should avoid that conflict if your eventual 4.15 branch is not based on your current char-misc-next branch.
I've resolved the merge conflict so my char-misc-next branch should be all caught up now. It would be wonderful if you could verify this.
thanks,
greg k-h
Arve Hjønnevåg
maintainerRe: [PATCH v2 1/4] android: binder: Don't get mm from task
Quoted 29 lines · Greg Kroah-Hartman
Quoted 19 lines · Arve Hjønnevåg
Quoted 17 lines · Greg Kroah-Hartman
Quoted 6 lines · Sherry Yang
Use
binder_allocstruct'smm_structrather than getting a reference to the mm struct throughget_task_mmto avoid a potential deadlock between lru lock, task lock and dentry lock, since a thread can be holding the task lock and the dentry lock while trying to acquire the lru lock.Quoted 6 lines
Acked-by Arve Hjønnevåg <[email protected]>Signed-off-by Sherry Yang <[email protected]>--- drivers/android/binder_alloc.c | 22 +++++++++------------- drivers/android/binder_alloc.h | 1 - 2 files changed, 9 insertions(+), 14 deletions(-)I've applied these first 2 patches, but patches 3 and 4 I have already applied to my char-misc-next tree, right?
Quoted 8 lines
Quoted 3 lines
thanks,
greg k-h
I would expect you got a merge conflict from one of those. Using patch 3 and 4 in from this patchset should avoid that conflict if your eventual 4.15 branch is not based on your current char-misc-next branch.
Quoted 6 lines
I've resolved the merge conflict so my char-misc-next branch should be all caught up now. It would be wonderful if you could verify this.
thanks,
greg k-h
I have not tested your branch directly, but the relevant code in char-misc-next is now identical to the code I tested.
Signature · 1 line
Arve Hjønnevåg
Greg Kroah-Hartman
maintainerRe: [PATCH v2 1/4] android: binder: Don't get mm from task
Quoted 34 lines · Arve Hjønnevåg
Quoted 32 lines · Greg Kroah-Hartman
Quoted 19 lines · Arve Hjønnevåg
Quoted 17 lines · Greg Kroah-Hartman
Quoted 6 lines · Sherry Yang
Use
binder_allocstruct'smm_structrather than getting a reference to the mm struct throughget_task_mmto avoid a potential deadlock between lru lock, task lock and dentry lock, since a thread can be holding the task lock and the dentry lock while trying to acquire the lru lock.Quoted 6 lines
Acked-by Arve Hjønnevåg <[email protected]>Signed-off-by Sherry Yang <[email protected]>--- drivers/android/binder_alloc.c | 22 +++++++++------------- drivers/android/binder_alloc.h | 1 - 2 files changed, 9 insertions(+), 14 deletions(-)I've applied these first 2 patches, but patches 3 and 4 I have already applied to my char-misc-next tree, right?
Quoted 8 lines
Quoted 3 lines
thanks,
greg k-h
I would expect you got a merge conflict from one of those. Using patch 3 and 4 in from this patchset should avoid that conflict if your eventual 4.15 branch is not based on your current char-misc-next branch.
I've resolved the merge conflict so my char-misc-next branch should be all caught up now. It would be wonderful if you could verify this.
Quoted 6 lines
Quoted 3 lines
thanks,
greg k-h
I have not tested your branch directly, but the relevant code in char-misc-next is now identical to the code I tested.
Wonderful, thanks for verifying.
greg k-h
PATCH v2 2/4 android: binder: Fix null ptr dereference in debug msg
In reply to Sherry YangDon't access next->data in kernel debug message when the next buffer is null.
--- drivers/android/binder_alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/android/binder_alloc.c +1 -1
@@ -560,7 +560,7 @@ static void binder_delete_free_buffer(struct binder_alloc *alloc,binder_alloc_debug (BINDER_DEBUG_BUFFER_ALLOC ,"%d: merge free, buffer %pK do not share page with %pK or %pK\n" , alloc->pid, buffer->data, - prev->data, next->data); + prev->data, next ? next->data :NULL );binder_update_page_range (alloc,0 ,buffer_start_page (buffer),buffer_start_page (buffer) +PAGE_SIZE ,NULL );
Signature · 1 line
2.11.0 (Apple Git-81)
PATCH v2 3/4 android: binder: Remove unused vma argument
In reply to Sherry YangThe vma argument in update_page_range is no longer used after 74310e06 ("android: binder: Move buffer out of area shared with user space"), since mmap_handler no longer calls update_page_range with a vma.
--- drivers/android/binder_alloc.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-)
drivers/android/binder_alloc.c +7 -9
@@ -186,12 +186,12 @@ struct binder_buffer *binder_alloc_prepare_to_free(struct binder_alloc *alloc, }static int binder_update_page_range (struct binder_alloc *alloc,int allocate, -void *start,void *end, -struct vm_area_struct *vma) +void *start,void *end) {void *page_addr;unsigned long user_page_addr;struct binder_lru_page *page; +struct vm_area_struct *vma =NULL ;struct mm_struct *mm =NULL ;bool need_mm = false;
@@ -215,7 +215,7 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate, } } -if (!vma && need_mm &&mmget_not_zero (alloc->vma_vm_mm)) +if (need_mm &&mmget_not_zero (alloc->vma_vm_mm)) mm = alloc->vma_vm_mm;if (mm) {
@@ -437,7 +437,7 @@ struct binder_buffer *binder_alloc_new_buf_locked(struct binder_alloc *alloc,if (end_page_addr > has_page_addr) end_page_addr = has_page_addr; ret =binder_update_page_range (alloc,1 , - (void *)PAGE_ALIGN ((uintptr_t )buffer->data), end_page_addr,NULL ); + (void *)PAGE_ALIGN ((uintptr_t )buffer->data), end_page_addr);if (ret)return ERR_PTR (ret);
@@ -478,7 +478,7 @@ struct binder_buffer *binder_alloc_new_buf_locked(struct binder_alloc *alloc, err_alloc_buf_struct_failed:binder_update_page_range (alloc,0 , (void *)PAGE_ALIGN ((uintptr_t )buffer->data), - end_page_addr,NULL ); + end_page_addr);return ERR_PTR (-ENOMEM ); }
@@ -562,8 +562,7 @@ static void binder_delete_free_buffer(struct binder_alloc *alloc, alloc->pid, buffer->data, prev->data, next ? next->data : NULL);binder_update_page_range (alloc,0 ,buffer_start_page (buffer), -buffer_start_page (buffer) +PAGE_SIZE , -NULL ); +buffer_start_page (buffer) +PAGE_SIZE ); }list_del (&buffer->entry);kfree (buffer);
@@ -600,8 +599,7 @@ static void binder_free_buf_locked(struct binder_alloc *alloc,binder_update_page_range (alloc,0 , (void *)PAGE_ALIGN ((uintptr_t )buffer->data), - (void *)(((uintptr_t )buffer->data + buffer_size) &PAGE_MASK ), -NULL ); + (void *)(((uintptr_t )buffer->data + buffer_size) &PAGE_MASK ));rb_erase (&buffer->rb_node, &alloc->allocated_buffers); buffer->free =1 ;
Signature · 1 line
2.11.0 (Apple Git-81)
PATCH v2 4/4 android: binder: Change binder_shrinker to static
In reply to Sherry Yangbinder_shrinker struct is not used anywhere outside of binder_alloc.c and should be static.
--- drivers/android/binder_alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/android/binder_alloc.c +1 -1
@@ -982,7 +982,7 @@ binder_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)return ret; } -struct shrinker binder_shrinker = { +static struct shrinker binder_shrinker = { .count_objects = binder_shrink_count, .scan_objects = binder_shrink_scan, .seeks =DEFAULT_SEEKS ,
Signature · 1 line
2.11.0 (Apple Git-81)