# HG changeset patch
# User Jan Beulich <jbeulich@xxxxxxxxxx>
# Date 1306940990 -3600
# Node ID 809d5d5d048559718c2bda2df7cd5bbe1d3c5dbc
# Parent 876a5aaac0264cf38cae6581e5714b93ec380aaa
xen/blktap: fix locking
blktap_read_ufe_ring() invalidating the mmap index of a request could
race with blktap_clear_pte() reading it. Move the invalidation into
the info->mm->mmap_sem protected region in fast_flush_area(), noting
that doing this on the failure path of dispatch_rw_block_io() is
benign.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
---
diff -r 876a5aaac026 -r 809d5d5d0485 drivers/xen/blktap/blktap.c
--- a/drivers/xen/blktap/blktap.c Thu May 26 12:33:41 2011 +0100
+++ b/drivers/xen/blktap/blktap.c Wed Jun 01 16:09:50 2011 +0100
@@ -1026,7 +1026,7 @@
}
static void fast_flush_area(pending_req_t *req, unsigned int k_idx,
- unsigned int u_idx, int tapidx)
+ unsigned int u_idx, tap_blkif_t *info)
{
struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST*2];
unsigned int i, mmap_idx, invcount = 0, locked = 0;
@@ -1034,23 +1034,14 @@
uint64_t ptep;
int ret;
unsigned long uvaddr;
- tap_blkif_t *info;
- struct mm_struct *mm;
-
-
- if ((tapidx < 0) || (tapidx >= MAX_TAP_DEV)
- || !(info = tapfds[tapidx])) {
- WPRINTK("fast_flush: Couldn't get info!\n");
- return;
- }
-
- mm = info->mm;
+ struct mm_struct *mm = info->mm;
if (mm != NULL && xen_feature(XENFEAT_auto_translated_physmap)) {
down_write(&mm->mmap_sem);
blktap_zap_page_range(mm,
MMAP_VADDR(info->user_vstart, u_idx, 0),
req->nr_pages);
+ info->idx_map[u_idx].mem = INVALID_MIDX;
up_write(&mm->mmap_sem);
return;
}
@@ -1108,7 +1099,10 @@
req->nr_pages);
}
- if (locked)
+ if (!locked && mm != NULL)
+ down_write(&mm->mmap_sem);
+ info->idx_map[u_idx].mem = INVALID_MIDX;
+ if (mm != NULL)
up_write(&mm->mmap_sem);
}
@@ -1243,8 +1237,7 @@
offset = (uvaddr - info->rings_vstart) >> PAGE_SHIFT;
info->foreign_map.map[offset] = NULL;
}
- fast_flush_area(pending_req, pending_idx, usr_idx, info->minor);
- info->idx_map[usr_idx].mem = INVALID_MIDX;
+ fast_flush_area(pending_req, pending_idx, usr_idx, info);
make_response(blkif, pending_req->id, res.operation,
res.status);
blkif_put(pending_req->blkif);
@@ -1619,7 +1612,7 @@
fail_flush:
WPRINTK("Reached Fail_flush\n");
- fast_flush_area(pending_req, pending_idx, usr_idx, blkif->dev_num);
+ fast_flush_area(pending_req, pending_idx, usr_idx, info);
fail_response:
make_response(blkif, req->id, req->operation, BLKIF_RSP_ERROR);
free_req(pending_req);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|