[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.