ia64/linux-2.6.18-xen.hg

changeset 725:61ab98b5cc0e

blkback: Do not queue up bio structs before submitting them.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Nov 06 10:29:00 2008 +0000 (2008-11-06)
parents 0729cb8b1292
children d31b6ccf10e4
files drivers/xen/blkback/blkback.c
line diff
     1.1 --- a/drivers/xen/blkback/blkback.c	Wed Nov 05 15:43:55 2008 +0000
     1.2 +++ b/drivers/xen/blkback/blkback.c	Thu Nov 06 10:29:00 2008 +0000
     1.3 @@ -151,9 +151,9 @@ static void unplug_queue(blkif_t *blkif)
     1.4  	blkif->plug = NULL;
     1.5  }
     1.6  
     1.7 -static void plug_queue(blkif_t *blkif, struct bio *bio)
     1.8 +static void plug_queue(blkif_t *blkif, struct block_device *bdev)
     1.9  {
    1.10 -	request_queue_t *q = bdev_get_queue(bio->bi_bdev);
    1.11 +	request_queue_t *q = bdev_get_queue(bdev);
    1.12  
    1.13  	if (q == blkif->plug)
    1.14  		return;
    1.15 @@ -389,8 +389,8 @@ static void dispatch_rw_block_io(blkif_t
    1.16  		unsigned long buf; unsigned int nsec;
    1.17  	} seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
    1.18  	unsigned int nseg;
    1.19 -	struct bio *bio = NULL, *biolist[BLKIF_MAX_SEGMENTS_PER_REQUEST];
    1.20 -	int ret, i, nbio = 0;
    1.21 +	struct bio *bio = NULL;
    1.22 +	int ret, i;
    1.23  	int operation;
    1.24  
    1.25  	switch (req->operation) {
    1.26 @@ -477,6 +477,10 @@ static void dispatch_rw_block_io(blkif_t
    1.27  		goto fail_flush;
    1.28  	}
    1.29  
    1.30 +	plug_queue(blkif, preq.bdev);
    1.31 +	atomic_set(&pending_req->pendcnt, 1);
    1.32 +	blkif_get(blkif);
    1.33 +
    1.34  	for (i = 0; i < nseg; i++) {
    1.35  		if (((int)preq.sector_number|(int)seg[i].nsec) &
    1.36  		    ((bdev_hardsect_size(preq.bdev) >> 9) - 1)) {
    1.37 @@ -490,7 +494,12 @@ static void dispatch_rw_block_io(blkif_t
    1.38  				     virt_to_page(vaddr(pending_req, i)),
    1.39  				     seg[i].nsec << 9,
    1.40  				     seg[i].buf & ~PAGE_MASK) == 0)) {
    1.41 -			bio = biolist[nbio++] = bio_alloc(GFP_KERNEL, nseg-i);
    1.42 +			if (bio) {
    1.43 +				atomic_inc(&pending_req->pendcnt);
    1.44 +				submit_bio(operation, bio);
    1.45 +			}
    1.46 +
    1.47 +			bio = bio_alloc(GFP_KERNEL, nseg-i);
    1.48  			if (unlikely(bio == NULL))
    1.49  				goto fail_put_bio;
    1.50  
    1.51 @@ -505,7 +514,7 @@ static void dispatch_rw_block_io(blkif_t
    1.52  
    1.53  	if (!bio) {
    1.54  		BUG_ON(operation != WRITE_BARRIER);
    1.55 -		bio = biolist[nbio++] = bio_alloc(GFP_KERNEL, 0);
    1.56 +		bio = bio_alloc(GFP_KERNEL, 0);
    1.57  		if (unlikely(bio == NULL))
    1.58  			goto fail_put_bio;
    1.59  
    1.60 @@ -515,12 +524,7 @@ static void dispatch_rw_block_io(blkif_t
    1.61  		bio->bi_sector  = -1;
    1.62  	}
    1.63  
    1.64 -	plug_queue(blkif, bio);
    1.65 -	atomic_set(&pending_req->pendcnt, nbio);
    1.66 -	blkif_get(blkif);
    1.67 -
    1.68 -	for (i = 0; i < nbio; i++)
    1.69 -		submit_bio(operation, biolist[i]);
    1.70 +	submit_bio(operation, bio);
    1.71  
    1.72  	if (operation == READ)
    1.73  		blkif->st_rd_sect += preq.nr_sects;
    1.74 @@ -529,16 +533,22 @@ static void dispatch_rw_block_io(blkif_t
    1.75  
    1.76  	return;
    1.77  
    1.78 - fail_put_bio:
    1.79 -	for (i = 0; i < (nbio-1); i++)
    1.80 -		bio_put(biolist[i]);
    1.81   fail_flush:
    1.82  	fast_flush_area(pending_req);
    1.83   fail_response:
    1.84  	make_response(blkif, req->id, req->operation, BLKIF_RSP_ERROR);
    1.85  	free_req(pending_req);
    1.86  	msleep(1); /* back off a bit */
    1.87 -} 
    1.88 +	return;
    1.89 +
    1.90 + fail_put_bio:
    1.91 +	__end_block_io_op(pending_req, -EINVAL);
    1.92 +	if (bio)
    1.93 +		bio_put(bio);
    1.94 +	unplug_queue(blkif);
    1.95 +	msleep(1); /* back off a bit */
    1.96 +	return;
    1.97 +}
    1.98  
    1.99  
   1.100