]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
sparc64: DAX recursive lock removed
authorRob Gardner <rob.gardner@oracle.com>
Fri, 19 May 2017 01:14:06 +0000 (19:14 -0600)
committerShannon Nelson <shannon.nelson@oracle.com>
Wed, 31 May 2017 23:43:52 +0000 (16:43 -0700)
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 <rob.gardner@oracle.com>
Reviewed-by: Sanath Kumar <sanath.s.kumar@oracle.com>
Reviewed-by: Eric Saint-Etienne <eric.saint.etienne@oracle.com>
Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
arch/sparc/dax/dax_mm.c

index b6e945df1c267a28ce9bfc35145611dfd8cbb6eb..4ae67473820078b5e0f5e5f490b491551183d5c4 100644 (file)
@@ -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(&current->mm->mmap_sem);
                        ret = get_user_pages_fast(virtp, 1, 1, &page);
-                       up_read(&current->mm->mmap_sem);
 
                        if (ret == 1) {
                                dax_ctx->pages[at][idx] = page;