diff options
| author | Sherry Yang <sherryy@android.com> | 2017-10-03 19:15:00 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-10-03 20:54:24 -0400 |
| commit | a1b2289cef92ef0e9a92afcd2e1ea71d5bcaaf64 (patch) | |
| tree | c3d9ab6e1ff17de869d3497dd44be5d70340c97f /drivers/android | |
| parent | 3f2eb0287ebd62ec8d6d544f830285302279e6bf (diff) | |
android: binder: drop lru lock in isolate callback
Drop the global lru lock in isolate callback before calling
zap_page_range which calls cond_resched, and re-acquire the global lru
lock before returning. Also change return code to LRU_REMOVED_RETRY.
Use mmput_async when fail to acquire mmap sem in an atomic context.
Fix "BUG: sleeping function called from invalid context"
errors when CONFIG_DEBUG_ATOMIC_SLEEP is enabled.
Also restore mmput_async, which was initially introduced in commit
ec8d7c14ea14 ("mm, oom_reaper: do not mmput synchronously from the oom
reaper context"), and was removed in commit 212925802454 ("mm: oom: let
oom_reap_task and exit_mmap run concurrently").
Link: http://lkml.kernel.org/r/20170914182231.90908-1-sherryy@android.com
Fixes: f2517eb76f1f2 ("android: binder: Add global lru shrinker to binder")
Signed-off-by: Sherry Yang <sherryy@android.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reported-by: Kyle Yan <kyan@codeaurora.org>
Acked-by: Arve Hjønnevåg <arve@android.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Cc: Martijn Coenen <maco@google.com>
Cc: Todd Kjos <tkjos@google.com>
Cc: Riley Andrews <riandrews@android.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Hillf Danton <hdanton@sina.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Hoeun Ryu <hoeun.ryu@gmail.com>
Cc: Christopher Lameter <cl@linux.com>
Cc: Vegard Nossum <vegard.nossum@oracle.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/android')
| -rw-r--r-- | drivers/android/binder_alloc.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c index 8fe165844e47..064f5e31ec55 100644 --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c | |||
| @@ -913,6 +913,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item, | |||
| 913 | struct binder_alloc *alloc; | 913 | struct binder_alloc *alloc; |
| 914 | uintptr_t page_addr; | 914 | uintptr_t page_addr; |
| 915 | size_t index; | 915 | size_t index; |
| 916 | struct vm_area_struct *vma; | ||
| 916 | 917 | ||
| 917 | alloc = page->alloc; | 918 | alloc = page->alloc; |
| 918 | if (!mutex_trylock(&alloc->mutex)) | 919 | if (!mutex_trylock(&alloc->mutex)) |
| @@ -923,16 +924,22 @@ enum lru_status binder_alloc_free_page(struct list_head *item, | |||
| 923 | 924 | ||
| 924 | index = page - alloc->pages; | 925 | index = page - alloc->pages; |
| 925 | page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE; | 926 | page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE; |
| 926 | if (alloc->vma) { | 927 | vma = alloc->vma; |
| 928 | if (vma) { | ||
| 927 | mm = get_task_mm(alloc->tsk); | 929 | mm = get_task_mm(alloc->tsk); |
| 928 | if (!mm) | 930 | if (!mm) |
| 929 | goto err_get_task_mm_failed; | 931 | goto err_get_task_mm_failed; |
| 930 | if (!down_write_trylock(&mm->mmap_sem)) | 932 | if (!down_write_trylock(&mm->mmap_sem)) |
| 931 | goto err_down_write_mmap_sem_failed; | 933 | goto err_down_write_mmap_sem_failed; |
| 934 | } | ||
| 935 | |||
| 936 | list_lru_isolate(lru, item); | ||
| 937 | spin_unlock(lock); | ||
| 932 | 938 | ||
| 939 | if (vma) { | ||
| 933 | trace_binder_unmap_user_start(alloc, index); | 940 | trace_binder_unmap_user_start(alloc, index); |
| 934 | 941 | ||
| 935 | zap_page_range(alloc->vma, | 942 | zap_page_range(vma, |
| 936 | page_addr + alloc->user_buffer_offset, | 943 | page_addr + alloc->user_buffer_offset, |
| 937 | PAGE_SIZE); | 944 | PAGE_SIZE); |
| 938 | 945 | ||
| @@ -950,13 +957,12 @@ enum lru_status binder_alloc_free_page(struct list_head *item, | |||
| 950 | 957 | ||
| 951 | trace_binder_unmap_kernel_end(alloc, index); | 958 | trace_binder_unmap_kernel_end(alloc, index); |
| 952 | 959 | ||
| 953 | list_lru_isolate(lru, item); | 960 | spin_lock(lock); |
| 954 | |||
| 955 | mutex_unlock(&alloc->mutex); | 961 | mutex_unlock(&alloc->mutex); |
| 956 | return LRU_REMOVED; | 962 | return LRU_REMOVED_RETRY; |
| 957 | 963 | ||
| 958 | err_down_write_mmap_sem_failed: | 964 | err_down_write_mmap_sem_failed: |
| 959 | mmput(mm); | 965 | mmput_async(mm); |
| 960 | err_get_task_mm_failed: | 966 | err_get_task_mm_failed: |
| 961 | err_page_already_freed: | 967 | err_page_already_freed: |
| 962 | mutex_unlock(&alloc->mutex); | 968 | mutex_unlock(&alloc->mutex); |
