[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] implement support for splitting requests in block-vbd
Hi all, the main issue with stubdoms at the moment is that the new dma api does not support an upper limit for the number of sectors in a single dma transfer. This means that block-vbd can issue blkfront_aio transfers that exceed the blktap limit BLKIF_MAX_SEGMENTS_PER_REQUEST. The attached qemu patch makes block-vbd split any request bigger than the limit above. The small xen patch is also needed to change struct blkfront_aiocb. Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> diff -r 0b13d9787622 extras/mini-os/include/blkfront.h --- a/extras/mini-os/include/blkfront.h Tue Mar 24 06:55:29 2009 +0000 +++ b/extras/mini-os/include/blkfront.h Fri Mar 27 17:05:09 2009 +0000 @@ -8,6 +8,8 @@ uint8_t *aio_buf; size_t aio_nbytes; off_t aio_offset; + size_t total_bytes; + uint8_t is_write; void *data; grant_ref_t gref[BLKIF_MAX_SEGMENTS_PER_REQUEST]; diff --git a/block-vbd.c b/block-vbd.c index 8c15d65..0e70ef2 100644 --- a/block-vbd.c +++ b/block-vbd.c @@ -31,6 +31,10 @@ #include <malloc.h> #include "qemu-char.h" +#include <xen/io/blkif.h> +#define IDE_DMA_BUF_SECTORS \ + (((BLKIF_MAX_SEGMENTS_PER_REQUEST - 1 ) * TARGET_PAGE_SIZE) / 512) +#define IDE_DMA_BUF_BYTES (IDE_DMA_BUF_SECTORS * 512) #define SECTOR_SIZE 512 #ifndef QEMU_TOOL @@ -131,8 +135,18 @@ void qemu_aio_wait(void) remove_waiter(w); } -static void vbd_aio_callback(struct blkfront_aiocb *aiocbp, int ret) { +static void vbd_do_aio(struct blkfront_aiocb *aiocbp, int ret) { VbdAIOCB *acb = aiocbp->data; + int n = aiocbp->aio_nbytes; + + aiocbp->total_bytes -= n; + if (aiocbp->total_bytes > 0) { + aiocbp->aio_buf += n; + aiocbp->aio_offset += n; + aiocbp->aio_nbytes = aiocbp->total_bytes > IDE_DMA_BUF_BYTES ? IDE_DMA_BUF_BYTES : aiocbp->total_bytes; + blkfront_aio(aiocbp, aiocbp->is_write); + return; + } acb->common.cb(acb->common.opaque, ret); qemu_aio_release(acb); @@ -140,7 +154,7 @@ static void vbd_aio_callback(struct blkfront_aiocb *aiocbp, int ret) { static VbdAIOCB *vbd_aio_setup(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors, - BlockDriverCompletionFunc *cb, void *opaque) + BlockDriverCompletionFunc *cb, uint8_t is_write, void *opaque) { BDRVVbdState *s = bs->opaque; VbdAIOCB *acb; @@ -150,9 +164,15 @@ static VbdAIOCB *vbd_aio_setup(BlockDriverState *bs, return NULL; acb->aiocb.aio_dev = s->dev; acb->aiocb.aio_buf = buf; - acb->aiocb.aio_nbytes = nb_sectors * SECTOR_SIZE; acb->aiocb.aio_offset = sector_num * SECTOR_SIZE; - acb->aiocb.aio_cb = vbd_aio_callback; + if (nb_sectors <= IDE_DMA_BUF_SECTORS) + acb->aiocb.aio_nbytes = nb_sectors * SECTOR_SIZE; + else + acb->aiocb.aio_nbytes = IDE_DMA_BUF_BYTES; + acb->aiocb.aio_cb = vbd_do_aio; + + acb->aiocb.total_bytes = nb_sectors * SECTOR_SIZE; + acb->aiocb.is_write = is_write; acb->aiocb.data = acb; return acb; @@ -164,7 +184,7 @@ static BlockDriverAIOCB *vbd_aio_read(BlockDriverState *bs, { VbdAIOCB *acb; - acb = vbd_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque); + acb = vbd_aio_setup(bs, sector_num, buf, nb_sectors, cb, 0, opaque); if (!acb) return NULL; blkfront_aio(&acb->aiocb, 0); @@ -177,7 +197,7 @@ static BlockDriverAIOCB *vbd_aio_write(BlockDriverState *bs, { VbdAIOCB *acb; - acb = vbd_aio_setup(bs, sector_num, (uint8_t*) buf, nb_sectors, cb, opaque); + acb = vbd_aio_setup(bs, sector_num, (uint8_t*) buf, nb_sectors, cb, 1, opaque); if (!acb) return NULL; blkfront_aio(&acb->aiocb, 1); @@ -196,7 +216,7 @@ static int vbd_aligned_io(BlockDriverState *bs, VbdAIOCB *acb; int result[2]; result[0] = 0; - acb = vbd_aio_setup(bs, sector_num, (uint8_t*) buf, nb_sectors, vbd_cb, &result); + acb = vbd_aio_setup(bs, sector_num, (uint8_t*) buf, nb_sectors, vbd_cb, write, &result); blkfront_aio(&acb->aiocb, write); while (!result[0]) qemu_aio_wait(); @@ -268,13 +288,13 @@ static BlockDriverAIOCB *vbd_aio_flush(BlockDriverState *bs, } if (s->info.barrier == 1) { acb = vbd_aio_setup(bs, 0, NULL, 0, - s->info.flush == 1 ? vbd_nop_cb : cb, opaque); + s->info.flush == 1 ? vbd_nop_cb : cb, 0, opaque); if (!acb) return NULL; blkfront_aio_push_operation(&acb->aiocb, BLKIF_OP_WRITE_BARRIER); } if (s->info.flush == 1) { - acb = vbd_aio_setup(bs, 0, NULL, 0, cb, opaque); + acb = vbd_aio_setup(bs, 0, NULL, 0, cb, 0, opaque); if (!acb) return NULL; blkfront_aio_push_operation(&acb->aiocb, BLKIF_OP_FLUSH_DISKCACHE); _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |