138 lines
4.1 KiB
Diff
138 lines
4.1 KiB
Diff
From b591f5930d0eaa93690c5a7acf95e4f5a3e04e06 Mon Sep 17 00:00:00 2001
|
|
From: Avi Kivity <avi@redhat.com>
|
|
Date: Fri, 20 Mar 2009 18:26:16 +0000
|
|
Subject: [STABLE][PATCH 2/4] Move block dma helpers aiocb to store dma state
|
|
|
|
Use the dedicated dma aiocb to store intermediate state for dma block
|
|
transactions.
|
|
|
|
Signed-off-by: Avi Kivity <avi@redhat.com>
|
|
|
|
---
|
|
dma-helpers.c | 37 ++++++++++++++++++++-----------------
|
|
1 files changed, 20 insertions(+), 17 deletions(-)
|
|
|
|
diff --git a/dma-helpers.c b/dma-helpers.c
|
|
index 19fa4f0..96a120c 100644
|
|
--- a/dma-helpers.c
|
|
+++ b/dma-helpers.c
|
|
@@ -39,6 +39,7 @@ void qemu_sglist_destroy(QEMUSGList *qsg)
|
|
}
|
|
|
|
typedef struct {
|
|
+ BlockDriverAIOCB common;
|
|
BlockDriverState *bs;
|
|
BlockDriverAIOCB *acb;
|
|
QEMUSGList *sg;
|
|
@@ -48,13 +49,13 @@ typedef struct {
|
|
target_phys_addr_t sg_cur_byte;
|
|
QEMUIOVector iov;
|
|
QEMUBH *bh;
|
|
-} DMABlockState;
|
|
+} DMAAIOCB;
|
|
|
|
static void dma_bdrv_cb(void *opaque, int ret);
|
|
|
|
static void reschedule_dma(void *opaque)
|
|
{
|
|
- DMABlockState *dbs = (DMABlockState *)opaque;
|
|
+ DMAAIOCB *dbs = (DMAAIOCB *)opaque;
|
|
|
|
qemu_bh_delete(dbs->bh);
|
|
dbs->bh = NULL;
|
|
@@ -63,7 +64,7 @@ static void reschedule_dma(void *opaque)
|
|
|
|
static void continue_after_map_failure(void *opaque)
|
|
{
|
|
- DMABlockState *dbs = (DMABlockState *)opaque;
|
|
+ DMAAIOCB *dbs = (DMAAIOCB *)opaque;
|
|
|
|
dbs->bh = qemu_bh_new(reschedule_dma, dbs);
|
|
qemu_bh_schedule(dbs->bh);
|
|
@@ -71,11 +72,12 @@ static void continue_after_map_failure(void *opaque)
|
|
|
|
static void dma_bdrv_cb(void *opaque, int ret)
|
|
{
|
|
- DMABlockState *dbs = (DMABlockState *)opaque;
|
|
+ DMAAIOCB *dbs = (DMAAIOCB *)opaque;
|
|
target_phys_addr_t cur_addr, cur_len;
|
|
void *mem;
|
|
int i;
|
|
|
|
+ dbs->acb = NULL;
|
|
dbs->sector_num += dbs->iov.size / 512;
|
|
for (i = 0; i < dbs->iov.niov; ++i) {
|
|
cpu_physical_memory_unmap(dbs->iov.iov[i].iov_base,
|
|
@@ -85,10 +87,9 @@ static void dma_bdrv_cb(void *opaque, int ret)
|
|
qemu_iovec_reset(&dbs->iov);
|
|
|
|
if (dbs->sg_cur_index == dbs->sg->nsg || ret < 0) {
|
|
- dbs->acb->cb(dbs->acb->opaque, ret);
|
|
+ dbs->common.cb(dbs->common.opaque, ret);
|
|
qemu_iovec_destroy(&dbs->iov);
|
|
- qemu_aio_release(dbs->acb);
|
|
- qemu_free(dbs);
|
|
+ qemu_aio_release(dbs);
|
|
return;
|
|
}
|
|
|
|
@@ -112,11 +113,11 @@ static void dma_bdrv_cb(void *opaque, int ret)
|
|
}
|
|
|
|
if (dbs->is_write) {
|
|
- bdrv_aio_writev(dbs->bs, dbs->sector_num, &dbs->iov,
|
|
- dbs->iov.size / 512, dma_bdrv_cb, dbs);
|
|
+ dbs->acb = bdrv_aio_writev(dbs->bs, dbs->sector_num, &dbs->iov,
|
|
+ dbs->iov.size / 512, dma_bdrv_cb, dbs);
|
|
} else {
|
|
- bdrv_aio_readv(dbs->bs, dbs->sector_num, &dbs->iov,
|
|
- dbs->iov.size / 512, dma_bdrv_cb, dbs);
|
|
+ dbs->acb = bdrv_aio_readv(dbs->bs, dbs->sector_num, &dbs->iov,
|
|
+ dbs->iov.size / 512, dma_bdrv_cb, dbs);
|
|
}
|
|
}
|
|
|
|
@@ -125,10 +126,10 @@ static BlockDriverAIOCB *dma_bdrv_io(
|
|
BlockDriverCompletionFunc *cb, void *opaque,
|
|
int is_write)
|
|
{
|
|
- DMABlockState *dbs = qemu_malloc(sizeof(*dbs));
|
|
+ DMAAIOCB *dbs = qemu_aio_get_pool(&dma_aio_pool, bs, cb, opaque);
|
|
|
|
+ dbs->acb = NULL;
|
|
dbs->bs = bs;
|
|
- dbs->acb = qemu_aio_get_pool(&dma_aio_pool, bs, cb, opaque);
|
|
dbs->sg = sg;
|
|
dbs->sector_num = sector_num;
|
|
dbs->sg_cur_index = 0;
|
|
@@ -137,7 +138,7 @@ static BlockDriverAIOCB *dma_bdrv_io(
|
|
dbs->bh = NULL;
|
|
qemu_iovec_init(&dbs->iov, sg->nsg);
|
|
dma_bdrv_cb(dbs, 0);
|
|
- return dbs->acb;
|
|
+ return &dbs->common;
|
|
}
|
|
|
|
|
|
@@ -157,12 +158,14 @@ BlockDriverAIOCB *dma_bdrv_write(BlockDriverState *bs,
|
|
|
|
static void dma_aio_cancel(BlockDriverAIOCB *acb)
|
|
{
|
|
- DMABlockState *dbs = (DMABlockState *)acb->opaque;
|
|
+ DMAAIOCB *dbs = container_of(acb, DMAAIOCB, common);
|
|
|
|
- bdrv_aio_cancel(dbs->acb);
|
|
+ if (dbs->acb) {
|
|
+ bdrv_aio_cancel(dbs->acb);
|
|
+ }
|
|
}
|
|
|
|
void dma_helper_init(void)
|
|
{
|
|
- aio_pool_init(&dma_aio_pool, sizeof(BlockDriverAIOCB), dma_aio_cancel);
|
|
+ aio_pool_init(&dma_aio_pool, sizeof(DMAAIOCB), dma_aio_cancel);
|
|
}
|
|
--
|
|
1.6.0.6
|
|
|