diff --git a/block.c b/block.c index 6e4d910a76..e6b91c60ac 100644 --- a/block.c +++ b/block.c @@ -48,23 +48,12 @@ #define SECTOR_BITS 9 #define SECTOR_SIZE (1 << SECTOR_BITS) -typedef struct BlockDriverAIOCBSync { - BlockDriverAIOCB common; - QEMUBH *bh; - int ret; - /* vector translation state */ - QEMUIOVector *qiov; - uint8_t *bounce; - int is_write; -} BlockDriverAIOCBSync; - static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque); static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque); -static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb); static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors); static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num, @@ -138,21 +127,17 @@ void path_combine(char *dest, int dest_size, } } - void bdrv_register(BlockDriver *bdrv) { if (!bdrv->bdrv_aio_readv) { /* add AIO emulation layer */ bdrv->bdrv_aio_readv = bdrv_aio_readv_em; bdrv->bdrv_aio_writev = bdrv_aio_writev_em; - bdrv->bdrv_aio_cancel = bdrv_aio_cancel_em; - bdrv->aiocb_size = sizeof(BlockDriverAIOCBSync); } else if (!bdrv->bdrv_read) { /* add synchronous IO emulation layer */ bdrv->bdrv_read = bdrv_read_em; bdrv->bdrv_write = bdrv_write_em; } - aio_pool_init(&bdrv->aio_pool, bdrv->aiocb_size, bdrv->bdrv_aio_cancel); bdrv->next = first_drv; first_drv = bdrv; } @@ -1369,6 +1354,28 @@ void bdrv_aio_cancel(BlockDriverAIOCB *acb) /**************************************************************/ /* async block device emulation */ +typedef struct BlockDriverAIOCBSync { + BlockDriverAIOCB common; + QEMUBH *bh; + int ret; + /* vector translation state */ + QEMUIOVector *qiov; + uint8_t *bounce; + int is_write; +} BlockDriverAIOCBSync; + +static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb) +{ + BlockDriverAIOCBSync *acb = (BlockDriverAIOCBSync *)blockacb; + qemu_bh_cancel(acb->bh); + qemu_aio_release(acb); +} + +static AIOPool bdrv_em_aio_pool = { + .aiocb_size = sizeof(BlockDriverAIOCBSync), + .cancel = bdrv_aio_cancel_em, +}; + static void bdrv_aio_bh_cb(void *opaque) { BlockDriverAIOCBSync *acb = opaque; @@ -1392,7 +1399,7 @@ static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs, { BlockDriverAIOCBSync *acb; - acb = qemu_aio_get(bs, cb, opaque); + acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque); acb->is_write = is_write; acb->qiov = qiov; acb->bounce = qemu_blockalign(bs, qiov->size); @@ -1426,14 +1433,6 @@ static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs, return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1); } - -static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb) -{ - BlockDriverAIOCBSync *acb = (BlockDriverAIOCBSync *)blockacb; - qemu_bh_cancel(acb->bh); - qemu_aio_release(acb); -} - /**************************************************************/ /* sync block device emulation */ @@ -1495,16 +1494,8 @@ void bdrv_init(void) module_call_init(MODULE_INIT_BLOCK); } -void aio_pool_init(AIOPool *pool, int aiocb_size, - void (*cancel)(BlockDriverAIOCB *acb)) -{ - pool->aiocb_size = aiocb_size; - pool->cancel = cancel; - pool->free_aiocb = NULL; -} - -void *qemu_aio_get_pool(AIOPool *pool, BlockDriverState *bs, - BlockDriverCompletionFunc *cb, void *opaque) +void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs, + BlockDriverCompletionFunc *cb, void *opaque) { BlockDriverAIOCB *acb; @@ -1521,12 +1512,6 @@ void *qemu_aio_get_pool(AIOPool *pool, BlockDriverState *bs, return acb; } -void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb, - void *opaque) -{ - return qemu_aio_get_pool(&bs->drv->aio_pool, bs, cb, opaque); -} - void qemu_aio_release(void *p) { BlockDriverAIOCB *acb = (BlockDriverAIOCB *)p; diff --git a/block/curl.c b/block/curl.c index 5d1487dea1..e1a553f7a2 100644 --- a/block/curl.c +++ b/block/curl.c @@ -349,6 +349,16 @@ out_noclean: return -EINVAL; } +static void curl_aio_cancel(BlockDriverAIOCB *blockacb) +{ + // Do we have to implement canceling? Seems to work without... +} + +static AIOPool curl_aio_pool = { + .aiocb_size = sizeof(CURLAIOCB), + .cancel = curl_aio_cancel, +}; + static BlockDriverAIOCB *curl_aio_readv(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque) @@ -359,7 +369,7 @@ static BlockDriverAIOCB *curl_aio_readv(BlockDriverState *bs, size_t end; CURLState *state; - acb = qemu_aio_get(bs, cb, opaque); + acb = qemu_aio_get(&curl_aio_pool, bs, cb, opaque); if (!acb) return NULL; @@ -406,11 +416,6 @@ static BlockDriverAIOCB *curl_aio_readv(BlockDriverState *bs, return &acb->common; } -static void curl_aio_cancel(BlockDriverAIOCB *blockacb) -{ - // Do we have to implement canceling? Seems to work without... -} - static void curl_close(BlockDriverState *bs) { BDRVCURLState *s = bs->opaque; @@ -450,9 +455,7 @@ static BlockDriver bdrv_http = { .bdrv_close = curl_close, .bdrv_getlength = curl_getlength, - .aiocb_size = sizeof(CURLAIOCB), .bdrv_aio_readv = curl_aio_readv, - .bdrv_aio_cancel = curl_aio_cancel, }; static BlockDriver bdrv_https = { @@ -464,9 +467,7 @@ static BlockDriver bdrv_https = { .bdrv_close = curl_close, .bdrv_getlength = curl_getlength, - .aiocb_size = sizeof(CURLAIOCB), .bdrv_aio_readv = curl_aio_readv, - .bdrv_aio_cancel = curl_aio_cancel, }; static BlockDriver bdrv_ftp = { @@ -478,9 +479,7 @@ static BlockDriver bdrv_ftp = { .bdrv_close = curl_close, .bdrv_getlength = curl_getlength, - .aiocb_size = sizeof(CURLAIOCB), .bdrv_aio_readv = curl_aio_readv, - .bdrv_aio_cancel = curl_aio_cancel, }; static BlockDriver bdrv_ftps = { @@ -492,9 +491,7 @@ static BlockDriver bdrv_ftps = { .bdrv_close = curl_close, .bdrv_getlength = curl_getlength, - .aiocb_size = sizeof(CURLAIOCB), .bdrv_aio_readv = curl_aio_readv, - .bdrv_aio_cancel = curl_aio_cancel, }; static BlockDriver bdrv_tftp = { @@ -506,9 +503,7 @@ static BlockDriver bdrv_tftp = { .bdrv_close = curl_close, .bdrv_getlength = curl_getlength, - .aiocb_size = sizeof(CURLAIOCB), .bdrv_aio_readv = curl_aio_readv, - .bdrv_aio_cancel = curl_aio_cancel, }; static void curl_block_init(void) diff --git a/block/qcow.c b/block/qcow.c index b22df46374..329b364b70 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -503,6 +503,18 @@ typedef struct QCowAIOCB { BlockDriverAIOCB *hd_aiocb; } QCowAIOCB; +static void qcow_aio_cancel(BlockDriverAIOCB *blockacb) +{ + QCowAIOCB *acb = (QCowAIOCB *)blockacb; + if (acb->hd_aiocb) + bdrv_aio_cancel(acb->hd_aiocb); + qemu_aio_release(acb); +} + +static AIOPool qcow_aio_pool = { + .aiocb_size = sizeof(QCowAIOCB), + .cancel = qcow_aio_cancel, +}; static QCowAIOCB *qcow_aio_setup(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, @@ -510,7 +522,7 @@ static QCowAIOCB *qcow_aio_setup(BlockDriverState *bs, { QCowAIOCB *acb; - acb = qemu_aio_get(bs, cb, opaque); + acb = qemu_aio_get(&qcow_aio_pool, bs, cb, opaque); if (!acb) return NULL; acb->hd_aiocb = NULL; @@ -720,14 +732,6 @@ static BlockDriverAIOCB *qcow_aio_writev(BlockDriverState *bs, return &acb->common; } -static void qcow_aio_cancel(BlockDriverAIOCB *blockacb) -{ - QCowAIOCB *acb = (QCowAIOCB *)blockacb; - if (acb->hd_aiocb) - bdrv_aio_cancel(acb->hd_aiocb); - qemu_aio_release(acb); -} - static void qcow_close(BlockDriverState *bs) { BDRVQcowState *s = bs->opaque; @@ -924,8 +928,6 @@ static BlockDriver bdrv_qcow = { .bdrv_make_empty = qcow_make_empty, .bdrv_aio_readv = qcow_aio_readv, .bdrv_aio_writev = qcow_aio_writev, - .bdrv_aio_cancel = qcow_aio_cancel, - .aiocb_size = sizeof(QCowAIOCB), .bdrv_write_compressed = qcow_write_compressed, .bdrv_get_info = qcow_get_info, diff --git a/block/qcow2.c b/block/qcow2.c index 619b923142..d1611d14ca 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1246,6 +1246,19 @@ typedef struct QCowAIOCB { QCowL2Meta l2meta; } QCowAIOCB; +static void qcow_aio_cancel(BlockDriverAIOCB *blockacb) +{ + QCowAIOCB *acb = (QCowAIOCB *)blockacb; + if (acb->hd_aiocb) + bdrv_aio_cancel(acb->hd_aiocb); + qemu_aio_release(acb); +} + +static AIOPool qcow_aio_pool = { + .aiocb_size = sizeof(QCowAIOCB), + .cancel = qcow_aio_cancel, +}; + static void qcow_aio_read_cb(void *opaque, int ret); static void qcow_aio_read_bh(void *opaque) { @@ -1375,7 +1388,7 @@ static QCowAIOCB *qcow_aio_setup(BlockDriverState *bs, { QCowAIOCB *acb; - acb = qemu_aio_get(bs, cb, opaque); + acb = qemu_aio_get(&qcow_aio_pool, bs, cb, opaque); if (!acb) return NULL; acb->hd_aiocb = NULL; @@ -1498,14 +1511,6 @@ static BlockDriverAIOCB *qcow_aio_writev(BlockDriverState *bs, return &acb->common; } -static void qcow_aio_cancel(BlockDriverAIOCB *blockacb) -{ - QCowAIOCB *acb = (QCowAIOCB *)blockacb; - if (acb->hd_aiocb) - bdrv_aio_cancel(acb->hd_aiocb); - qemu_aio_release(acb); -} - static void qcow_close(BlockDriverState *bs) { BDRVQcowState *s = bs->opaque; @@ -2998,8 +3003,6 @@ static BlockDriver bdrv_qcow2 = { .bdrv_aio_readv = qcow_aio_readv, .bdrv_aio_writev = qcow_aio_writev, - .bdrv_aio_cancel = qcow_aio_cancel, - .aiocb_size = sizeof(QCowAIOCB), .bdrv_write_compressed = qcow_write_compressed, .bdrv_snapshot_create = qcow_snapshot_create, diff --git a/block/raw-posix.c b/block/raw-posix.c index 93ed675b9b..38c4aa71af 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -599,6 +599,45 @@ static int posix_aio_init(void) return 0; } +static void raw_aio_remove(RawAIOCB *acb) +{ + RawAIOCB **pacb; + + /* remove the callback from the queue */ + pacb = &posix_aio_state->first_aio; + for(;;) { + if (*pacb == NULL) { + fprintf(stderr, "raw_aio_remove: aio request not found!\n"); + break; + } else if (*pacb == acb) { + *pacb = acb->next; + qemu_aio_release(acb); + break; + } + pacb = &(*pacb)->next; + } +} + +static void raw_aio_cancel(BlockDriverAIOCB *blockacb) +{ + int ret; + RawAIOCB *acb = (RawAIOCB *)blockacb; + + ret = qemu_paio_cancel(acb->aiocb.aio_fildes, &acb->aiocb); + if (ret == QEMU_PAIO_NOTCANCELED) { + /* fail safe: if the aio could not be canceled, we wait for + it */ + while (qemu_paio_error(&acb->aiocb) == EINPROGRESS); + } + + raw_aio_remove(acb); +} + +static AIOPool raw_aio_pool = { + .aiocb_size = sizeof(RawAIOCB), + .cancel = raw_aio_cancel, +}; + static RawAIOCB *raw_aio_setup(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque) @@ -609,7 +648,7 @@ static RawAIOCB *raw_aio_setup(BlockDriverState *bs, int64_t sector_num, if (fd_open(bs) < 0) return NULL; - acb = qemu_aio_get(bs, cb, opaque); + acb = qemu_aio_get(&raw_aio_pool, bs, cb, opaque); if (!acb) return NULL; acb->aiocb.aio_fildes = s->fd; @@ -633,25 +672,6 @@ static RawAIOCB *raw_aio_setup(BlockDriverState *bs, int64_t sector_num, return acb; } -static void raw_aio_remove(RawAIOCB *acb) -{ - RawAIOCB **pacb; - - /* remove the callback from the queue */ - pacb = &posix_aio_state->first_aio; - for(;;) { - if (*pacb == NULL) { - fprintf(stderr, "raw_aio_remove: aio request not found!\n"); - break; - } else if (*pacb == acb) { - *pacb = acb->next; - qemu_aio_release(acb); - break; - } - pacb = &(*pacb)->next; - } -} - static BlockDriverAIOCB *raw_aio_readv(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque) @@ -683,21 +703,6 @@ static BlockDriverAIOCB *raw_aio_writev(BlockDriverState *bs, } return &acb->common; } - -static void raw_aio_cancel(BlockDriverAIOCB *blockacb) -{ - int ret; - RawAIOCB *acb = (RawAIOCB *)blockacb; - - ret = qemu_paio_cancel(acb->aiocb.aio_fildes, &acb->aiocb); - if (ret == QEMU_PAIO_NOTCANCELED) { - /* fail safe: if the aio could not be canceled, we wait for - it */ - while (qemu_paio_error(&acb->aiocb) == EINPROGRESS); - } - - raw_aio_remove(acb); -} #else /* CONFIG_AIO */ static int posix_aio_init(void) { @@ -871,8 +876,6 @@ static BlockDriver bdrv_raw = { #ifdef CONFIG_AIO .bdrv_aio_readv = raw_aio_readv, .bdrv_aio_writev = raw_aio_writev, - .bdrv_aio_cancel = raw_aio_cancel, - .aiocb_size = sizeof(RawAIOCB), #endif .bdrv_truncate = raw_truncate, @@ -1205,7 +1208,7 @@ static BlockDriverAIOCB *raw_aio_ioctl(BlockDriverState *bs, if (fd_open(bs) < 0) return NULL; - acb = qemu_aio_get(bs, cb, opaque); + acb = qemu_aio_get(&raw_aio_pool, bs, cb, opaque); if (!acb) return NULL; acb->aiocb.aio_fildes = s->fd; @@ -1417,8 +1420,6 @@ static BlockDriver bdrv_host_device = { #ifdef CONFIG_AIO .bdrv_aio_readv = raw_aio_readv, .bdrv_aio_writev = raw_aio_writev, - .bdrv_aio_cancel = raw_aio_cancel, - .aiocb_size = sizeof(RawAIOCB), #endif .bdrv_read = raw_read, diff --git a/block_int.h b/block_int.h index 0820ed1d5c..8d0da7cfd7 100644 --- a/block_int.h +++ b/block_int.h @@ -67,8 +67,6 @@ struct BlockDriver { BlockDriverAIOCB *(*bdrv_aio_writev)(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque); - void (*bdrv_aio_cancel)(BlockDriverAIOCB *acb); - int aiocb_size; const char *protocol_name; int (*bdrv_truncate)(BlockDriverState *bs, int64_t offset); @@ -102,8 +100,6 @@ struct BlockDriver { unsigned long int req, void *buf, BlockDriverCompletionFunc *cb, void *opaque); - AIOPool aio_pool; - /* List of options for creating images, terminated by name == NULL */ QEMUOptionParameter *create_options; @@ -173,13 +169,8 @@ struct BlockDriverAIOCB { void get_tmp_filename(char *filename, int size); -void aio_pool_init(AIOPool *pool, int aiocb_size, - void (*cancel)(BlockDriverAIOCB *acb)); - -void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb, - void *opaque); -void *qemu_aio_get_pool(AIOPool *pool, BlockDriverState *bs, - BlockDriverCompletionFunc *cb, void *opaque); +void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs, + BlockDriverCompletionFunc *cb, void *opaque); void qemu_aio_release(void *p); void *qemu_blockalign(BlockDriverState *bs, size_t size); diff --git a/dma-helpers.c b/dma-helpers.c index f9eb2240b2..712ed897f3 100644 --- a/dma-helpers.c +++ b/dma-helpers.c @@ -10,8 +10,6 @@ #include "dma.h" #include "block_int.h" -static AIOPool dma_aio_pool; - void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint) { qsg->sg = qemu_malloc(alloc_hint * sizeof(ScatterGatherEntry)); @@ -132,12 +130,26 @@ static void dma_bdrv_cb(void *opaque, int ret) } } +static void dma_aio_cancel(BlockDriverAIOCB *acb) +{ + DMAAIOCB *dbs = container_of(acb, DMAAIOCB, common); + + if (dbs->acb) { + bdrv_aio_cancel(dbs->acb); + } +} + +static AIOPool dma_aio_pool = { + .aiocb_size = sizeof(DMAAIOCB), + .cancel = dma_aio_cancel, +}; + static BlockDriverAIOCB *dma_bdrv_io( BlockDriverState *bs, QEMUSGList *sg, uint64_t sector_num, BlockDriverCompletionFunc *cb, void *opaque, int is_write) { - DMAAIOCB *dbs = qemu_aio_get_pool(&dma_aio_pool, bs, cb, opaque); + DMAAIOCB *dbs = qemu_aio_get(&dma_aio_pool, bs, cb, opaque); dbs->acb = NULL; dbs->bs = bs; @@ -170,17 +182,3 @@ BlockDriverAIOCB *dma_bdrv_write(BlockDriverState *bs, { return dma_bdrv_io(bs, sg, sector, cb, opaque, 1); } - -static void dma_aio_cancel(BlockDriverAIOCB *acb) -{ - DMAAIOCB *dbs = container_of(acb, DMAAIOCB, common); - - if (dbs->acb) { - bdrv_aio_cancel(dbs->acb); - } -} - -void dma_helper_init(void) -{ - aio_pool_init(&dma_aio_pool, sizeof(DMAAIOCB), dma_aio_cancel); -} diff --git a/dma.h b/dma.h index 4fd80b9723..f3bb275159 100644 --- a/dma.h +++ b/dma.h @@ -38,6 +38,4 @@ BlockDriverAIOCB *dma_bdrv_read(BlockDriverState *bs, BlockDriverAIOCB *dma_bdrv_write(BlockDriverState *bs, QEMUSGList *sg, uint64_t sector, BlockDriverCompletionFunc *cb, void *opaque); -void dma_helper_init(void); - #endif diff --git a/vl.c b/vl.c index b1216c0183..0d6c85b4cb 100644 --- a/vl.c +++ b/vl.c @@ -5753,7 +5753,6 @@ int main(int argc, char **argv, char **envp) cpu_exec_init_all(tb_size * 1024 * 1024); bdrv_init(); - dma_helper_init(); /* we always create the cdrom drive, even if no disk is there */