]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
[S390] fix possible deadlock in gmap_map_segment
authorCarsten Otte <cotte@de.ibm.com>
Sun, 30 Oct 2011 14:17:00 +0000 (15:17 +0100)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Sun, 30 Oct 2011 14:16:44 +0000 (15:16 +0100)
Fix possible deadlock reported by lockdep:
qemu-system-s39/2963 is trying to acquire lock:
(&mm->mmap_sem){++++++}, at: gmap_alloc_table+0x9c/0x120
but task is already holding lock:
(&mm->mmap_sem){++++++}, at: gmap_map_segment+0xa6/0x27c

Actually gmap_alloc_table is the only called in gmap_map_segment with
mmap_sem held, thus it's safe to simply remove the inner lock.

Signed-off-by: Carsten Otte <cotte@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/mm/pgtable.c

index 529a08838376a5383e6a0973c12b00cde8639920..e4a4cefb92b36cfd2dd8f123a5e0e6b8d2d4d59a 100644 (file)
@@ -256,6 +256,9 @@ void gmap_disable(struct gmap *gmap)
 }
 EXPORT_SYMBOL_GPL(gmap_disable);
 
+/*
+ * gmap_alloc_table is assumed to be called with mmap_sem held
+ */
 static int gmap_alloc_table(struct gmap *gmap,
                               unsigned long *table, unsigned long init)
 {
@@ -267,14 +270,12 @@ static int gmap_alloc_table(struct gmap *gmap,
                return -ENOMEM;
        new = (unsigned long *) page_to_phys(page);
        crst_table_init(new, init);
-       down_read(&gmap->mm->mmap_sem);
        if (*table & _REGION_ENTRY_INV) {
                list_add(&page->lru, &gmap->crst_list);
                *table = (unsigned long) new | _REGION_ENTRY_LENGTH |
                        (*table & _REGION_ENTRY_TYPE_MASK);
        } else
                __free_pages(page, ALLOC_ORDER);
-       up_read(&gmap->mm->mmap_sem);
        return 0;
 }