From: Rob Gardner Date: Fri, 19 May 2017 01:14:06 +0000 (-0600) Subject: sparc64: DAX recursive lock removed X-Git-Tag: v4.1.12-102.0.20170530_1700~4 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=d44291164258dbbbc437b358de28298faf23f4e8;p=users%2Fjedix%2Flinux-maple.git sparc64: DAX recursive lock removed At some point in the past, the call to get_user_pages() was changed to get_user_pages_fast(). The former requires that mmap_sem be held when making the call, which the driver respected. But the latter requires that mmap_sem not be held, since it acquires it later. So mmap_sem was being acquired by the driver, then again in get_user_pages_fast(). In between these two acquisitions, another thread can come along and call mmap(), which will wait on the same semaphore, and deadlock with the subsequent get_user_pages_fast() attempt to get it again. Thread 1 Thread 2 -------- -------- acquire mmap_sem . call get_user_pages_fast() . . mmap() . acquire mmap_sem (blocks) acquire mmap_sem (blocks) Since get_user_pages_fast() acquires mmap_sem, the dax driver should not do so. Orabug: 26103487 Signed-off-by: Rob Gardner Reviewed-by: Sanath Kumar Reviewed-by: Eric Saint-Etienne Signed-off-by: Shannon Nelson --- diff --git a/arch/sparc/dax/dax_mm.c b/arch/sparc/dax/dax_mm.c index b6e945df1c267..4ae6747382007 100644 --- a/arch/sparc/dax/dax_mm.c +++ b/arch/sparc/dax/dax_mm.c @@ -197,9 +197,7 @@ int dax_map_segment_common(u32 *ccb_addr_type, enum dax_at at, dax_dbg("virtp=0x%lx backed by huge page. No need to lock", virtp); } else { - down_read(¤t->mm->mmap_sem); ret = get_user_pages_fast(virtp, 1, 1, &page); - up_read(¤t->mm->mmap_sem); if (ret == 1) { dax_ctx->pages[at][idx] = page;