path: root/arch/s390/mm
diff options
authorCarsten Otte <cotte@de.ibm.com>2011-10-30 15:17:00 +0100
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2011-10-30 15:16:44 +0100
commita9162f238a84ee05b09ea4b0ebd97fb20448c28c (patch)
tree06364148f57e6833bf7c7e66fa69181e141792ba /arch/s390/mm
parent69ba97436647f3b793f8e0784d1cde63adf241ea (diff)
[S390] fix possible deadlock in gmap_map_segment
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>
Diffstat (limited to 'arch/s390/mm')
1 files changed, 3 insertions, 2 deletions
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index 529a08838376..e4a4cefb92b3 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -256,6 +256,9 @@ void gmap_disable(struct gmap *gmap)
+ * 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 |
} else
__free_pages(page, ALLOC_ORDER);
- up_read(&gmap->mm->mmap_sem);
return 0;