ia64/xen-unstable

changeset 12284:3cc7e419b949

[BLKTAP] avoid race between tapdisk and xvd daemon with ufe_ring.
- Tapdisk updates rsp_cons by ioctl(). on the other hand xvd daemon
reads rsp_cons in do_block_io_op() with RING_FULL().
Copy request and memory barrier before updating rsp_cons.
- Tapdisk access req_prod_pvt with select(). on the other hand xvd
daemon updates it in do_block_io_op().

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author kfraser@localhost.localdomain
date Tue Nov 07 11:14:52 2006 +0000 (2006-11-07)
parents 862aca401601
children f56b7ade7068
files linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c	Tue Nov 07 11:01:35 2006 +0000
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c	Tue Nov 07 11:14:52 2006 +0000
     1.3 @@ -538,8 +538,10 @@ static int blktap_release(struct inode *
     1.4  	}
     1.5  	
     1.6  	if ( (info->status != CLEANSHUTDOWN) && (info->blkif != NULL) ) {
     1.7 -		kthread_stop(info->blkif->xenblkd);
     1.8 -		info->blkif->xenblkd = NULL;
     1.9 +		if (info->blkif->xenblkd != NULL) {
    1.10 +			kthread_stop(info->blkif->xenblkd);
    1.11 +			info->blkif->xenblkd = NULL;
    1.12 +		}
    1.13  		info->status = CLEANSHUTDOWN;
    1.14  	}	
    1.15  	return 0;
    1.16 @@ -1007,11 +1009,14 @@ static int blktap_read_ufe_ring(tap_blki
    1.17  	rmb();
    1.18          
    1.19  	for (i = info->ufe_ring.rsp_cons; i != rp; i++) {
    1.20 +		blkif_response_t res;
    1.21  		resp = RING_GET_RESPONSE(&info->ufe_ring, i);
    1.22 +		memcpy(&res, resp, sizeof(res));
    1.23 +		mb(); /* rsp_cons read by RING_FULL() in do_block_io_op(). */
    1.24  		++info->ufe_ring.rsp_cons;
    1.25  
    1.26  		/*retrieve [usr_idx] to [mmap_idx,pending_idx] mapping*/
    1.27 -		usr_idx = (int)resp->id;
    1.28 +		usr_idx = (int)res.id;
    1.29  		pending_idx = MASK_PEND_IDX(ID_TO_IDX(info->idx_map[usr_idx]));
    1.30  		mmap_idx = ID_TO_MIDX(info->idx_map[usr_idx]);
    1.31  
    1.32 @@ -1044,8 +1049,8 @@ static int blktap_read_ufe_ring(tap_blki
    1.33  			map[offset] = NULL;
    1.34  		}
    1.35  		fast_flush_area(pending_req, pending_idx, usr_idx, info->minor);
    1.36 -		make_response(blkif, pending_req->id, resp->operation,
    1.37 -			      resp->status);
    1.38 +		make_response(blkif, pending_req->id, res.operation,
    1.39 +			      res.status);
    1.40  		info->idx_map[usr_idx] = INVALID_REQ;
    1.41  		blkif_put(pending_req->blkif);
    1.42  		free_req(pending_req);
    1.43 @@ -1330,6 +1335,7 @@ static void dispatch_rw_block_io(blkif_t
    1.44  				  info->ufe_ring.req_prod_pvt);
    1.45  	memcpy(target, req, sizeof(*req));
    1.46  	target->id = usr_idx;
    1.47 +	wmb(); /* blktap_poll() reads req_prod_pvt asynchronously */
    1.48  	info->ufe_ring.req_prod_pvt++;
    1.49  	return;
    1.50