[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [linux-2.6.18-xen] blktap: ensure vma->vm_mm's mmap_sem is being held whenever it is being modified
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1225894117 0 # Node ID be9555ea5512d801a50f075037806a37ce17c209 # Parent 2fb13b8cbe134fdb3f18ee21e641e52655066c62 blktap: ensure vma->vm_mm's mmap_sem is being held whenever it is being modified Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx> --- drivers/xen/blktap/blktap.c | 43 +++++++++++++++++++++++++++++++++---------- 1 files changed, 33 insertions(+), 10 deletions(-) diff -r 2fb13b8cbe13 -r be9555ea5512 drivers/xen/blktap/blktap.c --- a/drivers/xen/blktap/blktap.c Thu Oct 30 13:34:43 2008 +0000 +++ b/drivers/xen/blktap/blktap.c Wed Nov 05 14:08:37 2008 +0000 @@ -611,9 +611,13 @@ static int blktap_release(struct inode * /* Clear any active mappings and free foreign map table */ if (info->vma) { + struct mm_struct *mm = info->vma->vm_mm; + + down_write(&mm->mmap_sem); zap_page_range( info->vma, info->vma->vm_start, info->vma->vm_end - info->vma->vm_start, NULL); + up_write(&mm->mmap_sem); kfree(info->vma->vm_private_data); @@ -992,12 +996,13 @@ static void fast_flush_area(pending_req_ int tapidx) { struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST*2]; - unsigned int i, invcount = 0; + unsigned int i, invcount = 0, locked = 0; struct grant_handle_pair *khandle; uint64_t ptep; int ret, mmap_idx; unsigned long kvaddr, uvaddr; tap_blkif_t *info; + struct mm_struct *mm; info = tapfds[tapidx]; @@ -1007,13 +1012,15 @@ static void fast_flush_area(pending_req_ return; } + mm = info->vma ? info->vma->vm_mm : NULL; + if (info->vma != NULL && xen_feature(XENFEAT_auto_translated_physmap)) { - down_write(&info->vma->vm_mm->mmap_sem); + down_write(&mm->mmap_sem); zap_page_range(info->vma, MMAP_VADDR(info->user_vstart, u_idx, 0), req->nr_pages << PAGE_SHIFT, NULL); - up_write(&info->vma->vm_mm->mmap_sem); + up_write(&mm->mmap_sem); return; } @@ -1038,10 +1045,13 @@ static void fast_flush_area(pending_req_ if (khandle->user != INVALID_GRANT_HANDLE) { BUG_ON(xen_feature(XENFEAT_auto_translated_physmap)); + if (!locked++) + down_write(&mm->mmap_sem); if (create_lookup_pte_addr( - info->vma->vm_mm, + mm, MMAP_VADDR(info->user_vstart, u_idx, i), &ptep) !=0) { + up_write(&mm->mmap_sem); WPRINTK("Couldn't get a pte addr!\n"); return; } @@ -1060,10 +1070,17 @@ static void fast_flush_area(pending_req_ GNTTABOP_unmap_grant_ref, unmap, invcount); BUG_ON(ret); - if (info->vma != NULL && !xen_feature(XENFEAT_auto_translated_physmap)) + if (info->vma != NULL && + !xen_feature(XENFEAT_auto_translated_physmap)) { + if (!locked++) + down_write(&mm->mmap_sem); zap_page_range(info->vma, MMAP_VADDR(info->user_vstart, u_idx, 0), req->nr_pages << PAGE_SHIFT, NULL); + } + + if (locked) + up_write(&mm->mmap_sem); } /****************************************************************** @@ -1346,6 +1363,7 @@ static void dispatch_rw_block_io(blkif_t int pending_idx = RTN_PEND_IDX(pending_req,pending_req->mem_idx); int usr_idx; uint16_t mmap_idx = pending_req->mem_idx; + struct mm_struct *mm; if (blkif->dev_num < 0 || blkif->dev_num > MAX_TAP_DEV) goto fail_response; @@ -1389,6 +1407,9 @@ static void dispatch_rw_block_io(blkif_t pending_req->status = BLKIF_RSP_OKAY; pending_req->nr_pages = nseg; op = 0; + mm = info->vma->vm_mm; + if (!xen_feature(XENFEAT_auto_translated_physmap)) + down_write(&mm->mmap_sem); for (i = 0; i < nseg; i++) { unsigned long uvaddr; unsigned long kvaddr; @@ -1407,9 +1428,9 @@ static void dispatch_rw_block_io(blkif_t if (!xen_feature(XENFEAT_auto_translated_physmap)) { /* Now map it to user. */ - ret = create_lookup_pte_addr(info->vma->vm_mm, - uvaddr, &ptep); + ret = create_lookup_pte_addr(mm, uvaddr, &ptep); if (ret) { + up_write(&mm->mmap_sem); WPRINTK("Couldn't get a pte addr!\n"); goto fail_flush; } @@ -1431,6 +1452,8 @@ static void dispatch_rw_block_io(blkif_t BUG_ON(ret); if (!xen_feature(XENFEAT_auto_translated_physmap)) { + up_write(&mm->mmap_sem); + for (i = 0; i < (nseg*2); i+=2) { unsigned long uvaddr; unsigned long kvaddr; @@ -1504,7 +1527,7 @@ static void dispatch_rw_block_io(blkif_t goto fail_flush; if (xen_feature(XENFEAT_auto_translated_physmap)) - down_write(&info->vma->vm_mm->mmap_sem); + down_write(&mm->mmap_sem); /* Mark mapped pages as reserved: */ for (i = 0; i < req->nr_segments; i++) { unsigned long kvaddr; @@ -1518,13 +1541,13 @@ static void dispatch_rw_block_io(blkif_t MMAP_VADDR(info->user_vstart, usr_idx, i), pg); if (ret) { - up_write(&info->vma->vm_mm->mmap_sem); + up_write(&mm->mmap_sem); goto fail_flush; } } } if (xen_feature(XENFEAT_auto_translated_physmap)) - up_write(&info->vma->vm_mm->mmap_sem); + up_write(&mm->mmap_sem); /*record [mmap_idx,pending_idx] to [usr_idx] mapping*/ info->idx_map[usr_idx] = MAKE_ID(mmap_idx, pending_idx); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |