| From 09ea818c4030a62973b1aeb8ca3486994589434f Mon Sep 17 00:00:00 2001 |
| From: Laura Abbott <lauraa@codeaurora.org> |
| Date: Fri, 29 Jan 2016 22:07:30 -0800 |
| Subject: staging: ashmem: Avoid deadlock with mmap/shrink |
| |
| [ Upstream commit 18e77054de741ef3ed2a2489bc9bf82a318b2d5e ] |
| |
| Both ashmem_mmap and ashmem_shrink take the ashmem_lock. It may |
| be possible for ashmem_mmap to invoke ashmem_shrink: |
| |
| -000|mutex_lock(lock = 0x0) |
| -001|ashmem_shrink(?, sc = 0x0) <--- try to take ashmem_mutex again |
| -002|shrink_slab(shrink = 0xDA5F1CC0, nr_pages_scanned = 0, lru_pages |
| -002|= |
| -002|124) |
| -003|try_to_free_pages(zonelist = 0x0, ?, ?, ?) |
| -004|__alloc_pages_nodemask(gfp_mask = 21200, order = 1, zonelist = |
| -004|0xC11D0940, |
| -005|new_slab(s = 0xE4841E80, ?, node = -1) |
| -006|__slab_alloc.isra.43.constprop.50(s = 0xE4841E80, gfpflags = |
| -006|2148925462, ad |
| -007|kmem_cache_alloc(s = 0xE4841E80, gfpflags = 208) |
| -008|shmem_alloc_inode(?) |
| -009|alloc_inode(sb = 0xE480E800) |
| -010|new_inode_pseudo(?) |
| -011|new_inode(?) |
| -012|shmem_get_inode(sb = 0xE480E800, dir = 0x0, ?, dev = 0, flags = |
| -012|187) |
| -013|shmem_file_setup(?, ?, flags = 187) |
| -014|ashmem_mmap(?, vma = 0xC5D64210) <---- Acquire ashmem_mutex |
| -015|mmap_region(file = 0xDF8E2C00, addr = 1772974080, len = 233472, |
| -015|flags = 57, |
| -016|sys_mmap_pgoff(addr = 0, len = 230400, prot = 3, flags = 1, fd = |
| -016|157, pgoff |
| -017|ret_fast_syscall(asm) |
| -->|exception |
| -018|NUR:0x40097508(asm) |
| ---|end of frame |
| |
| Avoid this deadlock by using mutex_trylock in ashmem_shrink; if the mutex |
| is already held, do not attempt to shrink. |
| |
| Cc: Greg KH <gregkh@linuxfoundation.org> |
| Cc: Android Kernel Team <kernel-team@android.com> |
| Reported-by: Matt Wagantall <mattw@codeaurora.org> |
| Reported-by: Syed Rameez Mustafa <rameezmustafa@codeaurora.org> |
| Reported-by: Osvaldo Banuelos <osvaldob@codeaurora.org> |
| Reported-by: Subbaraman Narayanamurthy <subbaram@codeaurora.org> |
| Signed-off-by: Laura Abbott <lauraa@codeaurora.org> |
| [jstultz: Minor commit message tweaks] |
| Signed-off-by: John Stultz <john.stultz@linaro.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/staging/android/ashmem.c | 4 +++- |
| 1 file changed, 3 insertions(+), 1 deletion(-) |
| |
| diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c |
| index 22ddd4ce9dd6..5105fe5e6533 100644 |
| --- a/drivers/staging/android/ashmem.c |
| +++ b/drivers/staging/android/ashmem.c |
| @@ -447,7 +447,9 @@ ashmem_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) |
| if (!(sc->gfp_mask & __GFP_FS)) |
| return SHRINK_STOP; |
| |
| - mutex_lock(&ashmem_mutex); |
| + if (!mutex_trylock(&ashmem_mutex)) |
| + return -1; |
| + |
| list_for_each_entry_safe(range, next, &ashmem_lru_list, lru) { |
| loff_t start = range->pgstart * PAGE_SIZE; |
| loff_t end = (range->pgend + 1) * PAGE_SIZE; |
| -- |
| 2.19.1 |
| |