ANDROID: binder: change down_write to down_read
PATCH v4 1/1 ANDROID: binder: change down_write to down_read
binder_update_page_range needs down_write of mmap_sem because vm_insert_page need to change vma->vm_flags to VM_MIXEDMAP unless it is set. However, when I profile binder working, it seems every binder buffers should be mapped in advance by binder_mmap. It means we could set VM_MIXEDMAP in bider_mmap time which is already hold a mmap_sem as down_write so binder_update_page_range doesn't need to hold a mmap_sem as down_write.
Android suffers from mmap_sem contention so let's reduce mmap_sem down_write.
---
Quoted 1 line
From v3:
* Fix typoe
Quoted 1 line
From v2:
* Fix vma->flag setting - Arve
Quoted 1 line
From v1:
* remove WARN_ON_ONCE - Greg
* add reviewed-by - Martijn
Martijn, I took your LGTM of v1 as Reviewed-by. If you don't like it or want to change it to acked-by, please, tell me.
drivers/android/binder.c | 3 ++- drivers/android/binder_alloc.c | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-)
drivers/android/binder.c +2 -1
@@ -4722,7 +4722,8 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) failure_string ="bad vm_flags" ; goto err_bad_arg; } - vma->vm_flags = (vma->vm_flags |VM_DONTCOPY ) & ~VM_MAYWRITE ; + vma->vm_flags = (vma->vm_flags |VM_DONTCOPY |VM_MIXEDMAP ) & + ~VM_MAYWRITE ; vma->vm_ops = &binder_vm_ops; vma->vm_private_data = proc;
drivers/android/binder_alloc.c +3 -3
@@ -219,7 +219,7 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate, mm = alloc->vma_vm_mm;if (mm) { -down_write (&mm->mmap_sem); +down_read (&mm->mmap_sem); vma = alloc->vma; }
@@ -288,7 +288,7 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate,/* vm_insert_page does not seem to increment the refcount */ }if (mm) { -up_write (&mm->mmap_sem); +up_read (&mm->mmap_sem);mmput (mm); }return 0 ;
@@ -321,7 +321,7 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate, } err_no_vma:if (mm) { -up_write (&mm->mmap_sem); +up_read (&mm->mmap_sem);mmput (mm); }return vma ? -ENOMEM : -ESRCH ;
Signature · 1 line
2.17.0.rc1.321.gba9d0f2565-goog
Quoted 5 lines · Minchan Kim
binder_update_page_rangeneedsdown_writeofmmap_sembecausevm_insert_pageneed to changevma->vm_flagstoVM_MIXEDMAPunless it is set. However, when I profile binder working, it seems every binder buffers should be mapped in advance bybinder_mmap. It means we could setVM_MIXEDMAPinbider_mmaptime which is
typo trivia: binder_mmap
Quoted 2 lines
already hold a
mmap_semasdown_writesobinder_update_page_rangedoesn't need to hold ammap_semasdown_write.
and style trivia:
drivers/android/binder.c
Quoted 1 line
drivers/android/binder.c +0
-0
[]
drivers/android/binder.c static int binder_mmap(struct file *filp, struct vm_area_struct *vma) · line 4726
Quoted 7 lines
drivers/android/binder.c +2
-1@@ -4722,7 +4722,8 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) failure_string ="bad vm_flags" ; goto err_bad_arg; } - vma->vm_flags = (vma->vm_flags |VM_DONTCOPY ) & ~VM_MAYWRITE ; + vma->vm_flags = (vma->vm_flags |VM_DONTCOPY |VM_MIXEDMAP ) & + ~VM_MAYWRITE ;
Perhaps this is clearer as
vma->vm_flags |= VM_DONTCOPY | VM_MIXEDMAP; vma->vm_flags &= ~VM_MAYWRITE;