From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932650AbcA3GIu (ORCPT ); Sat, 30 Jan 2016 01:08:50 -0500 Received: from mail-pa0-f52.google.com ([209.85.220.52]:34667 "EHLO mail-pa0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751151AbcA3GHn (ORCPT ); Sat, 30 Jan 2016 01:07:43 -0500 From: John Stultz To: lkml Cc: Laura Abbott , Greg KH , Android Kernel Team , John Stultz Subject: [PATCH 1/9] staging: ashmem: Avoid deadlock with mmap/shrink Date: Fri, 29 Jan 2016 22:07:30 -0800 Message-Id: <1454134058-16466-2-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1454134058-16466-1-git-send-email-john.stultz@linaro.org> References: <1454134058-16466-1-git-send-email-john.stultz@linaro.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Laura Abbott 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 Cc: Android Kernel Team Reported-by: Matt Wagantall Reported-by: Syed Rameez Mustafa Reported-by: Osvaldo Banuelos Reported-by: Subbaraman Narayanamurthy Signed-off-by: Laura Abbott [jstultz: Minor commit message tweaks] Signed-off-by: John Stultz --- 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 5bb1283..8ae1308 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -441,7 +441,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; -- 1.9.1