block: explicitly acquire aiocontext in aio callbacks that need it
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Fam Zheng <famz@redhat.com> Reviewed-by: Daniel P. Berrange <berrange@redhat.com> Message-id: 20170213135235.12274-16-pbonzini@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
1919631e6b
commit
b9e413dd37
@ -310,11 +310,8 @@ static void qemu_archipelago_complete_aio(void *opaque)
|
|||||||
{
|
{
|
||||||
AIORequestData *reqdata = (AIORequestData *) opaque;
|
AIORequestData *reqdata = (AIORequestData *) opaque;
|
||||||
ArchipelagoAIOCB *aio_cb = (ArchipelagoAIOCB *) reqdata->aio_cb;
|
ArchipelagoAIOCB *aio_cb = (ArchipelagoAIOCB *) reqdata->aio_cb;
|
||||||
AioContext *ctx = bdrv_get_aio_context(aio_cb->common.bs);
|
|
||||||
|
|
||||||
aio_context_acquire(ctx);
|
|
||||||
aio_cb->common.cb(aio_cb->common.opaque, aio_cb->ret);
|
aio_cb->common.cb(aio_cb->common.opaque, aio_cb->ret);
|
||||||
aio_context_release(ctx);
|
|
||||||
aio_cb->status = 0;
|
aio_cb->status = 0;
|
||||||
|
|
||||||
qemu_aio_unref(aio_cb);
|
qemu_aio_unref(aio_cb);
|
||||||
|
@ -939,12 +939,9 @@ int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags)
|
|||||||
static void error_callback_bh(void *opaque)
|
static void error_callback_bh(void *opaque)
|
||||||
{
|
{
|
||||||
struct BlockBackendAIOCB *acb = opaque;
|
struct BlockBackendAIOCB *acb = opaque;
|
||||||
AioContext *ctx = bdrv_get_aio_context(acb->common.bs);
|
|
||||||
|
|
||||||
bdrv_dec_in_flight(acb->common.bs);
|
bdrv_dec_in_flight(acb->common.bs);
|
||||||
aio_context_acquire(ctx);
|
|
||||||
acb->common.cb(acb->common.opaque, acb->ret);
|
acb->common.cb(acb->common.opaque, acb->ret);
|
||||||
aio_context_release(ctx);
|
|
||||||
qemu_aio_unref(acb);
|
qemu_aio_unref(acb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -986,12 +983,8 @@ static void blk_aio_complete(BlkAioEmAIOCB *acb)
|
|||||||
static void blk_aio_complete_bh(void *opaque)
|
static void blk_aio_complete_bh(void *opaque)
|
||||||
{
|
{
|
||||||
BlkAioEmAIOCB *acb = opaque;
|
BlkAioEmAIOCB *acb = opaque;
|
||||||
AioContext *ctx = bdrv_get_aio_context(acb->common.bs);
|
|
||||||
|
|
||||||
assert(acb->has_returned);
|
assert(acb->has_returned);
|
||||||
aio_context_acquire(ctx);
|
|
||||||
blk_aio_complete(acb);
|
blk_aio_complete(acb);
|
||||||
aio_context_release(ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset, int bytes,
|
static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset, int bytes,
|
||||||
|
@ -854,11 +854,11 @@ static void curl_readv_bh_cb(void *p)
|
|||||||
curl_multi_socket_action(s->multi, CURL_SOCKET_TIMEOUT, 0, &running);
|
curl_multi_socket_action(s->multi, CURL_SOCKET_TIMEOUT, 0, &running);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
aio_context_release(ctx);
|
||||||
if (ret != -EINPROGRESS) {
|
if (ret != -EINPROGRESS) {
|
||||||
acb->common.cb(acb->common.opaque, ret);
|
acb->common.cb(acb->common.opaque, ret);
|
||||||
qemu_aio_unref(acb);
|
qemu_aio_unref(acb);
|
||||||
}
|
}
|
||||||
aio_context_release(ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static BlockAIOCB *curl_aio_readv(BlockDriverState *bs,
|
static BlockAIOCB *curl_aio_readv(BlockDriverState *bs,
|
||||||
|
@ -813,7 +813,7 @@ static void bdrv_co_io_em_complete(void *opaque, int ret)
|
|||||||
CoroutineIOCompletion *co = opaque;
|
CoroutineIOCompletion *co = opaque;
|
||||||
|
|
||||||
co->ret = ret;
|
co->ret = ret;
|
||||||
qemu_coroutine_enter(co->coroutine);
|
aio_co_wake(co->coroutine);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn bdrv_driver_preadv(BlockDriverState *bs,
|
static int coroutine_fn bdrv_driver_preadv(BlockDriverState *bs,
|
||||||
@ -2152,13 +2152,9 @@ static void bdrv_co_complete(BlockAIOCBCoroutine *acb)
|
|||||||
static void bdrv_co_em_bh(void *opaque)
|
static void bdrv_co_em_bh(void *opaque)
|
||||||
{
|
{
|
||||||
BlockAIOCBCoroutine *acb = opaque;
|
BlockAIOCBCoroutine *acb = opaque;
|
||||||
BlockDriverState *bs = acb->common.bs;
|
|
||||||
AioContext *ctx = bdrv_get_aio_context(bs);
|
|
||||||
|
|
||||||
assert(!acb->need_bh);
|
assert(!acb->need_bh);
|
||||||
aio_context_acquire(ctx);
|
|
||||||
bdrv_co_complete(acb);
|
bdrv_co_complete(acb);
|
||||||
aio_context_release(ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bdrv_co_maybe_schedule_bh(BlockAIOCBCoroutine *acb)
|
static void bdrv_co_maybe_schedule_bh(BlockAIOCBCoroutine *acb)
|
||||||
|
@ -136,16 +136,13 @@ static void
|
|||||||
iscsi_bh_cb(void *p)
|
iscsi_bh_cb(void *p)
|
||||||
{
|
{
|
||||||
IscsiAIOCB *acb = p;
|
IscsiAIOCB *acb = p;
|
||||||
AioContext *ctx = bdrv_get_aio_context(acb->common.bs);
|
|
||||||
|
|
||||||
qemu_bh_delete(acb->bh);
|
qemu_bh_delete(acb->bh);
|
||||||
|
|
||||||
g_free(acb->buf);
|
g_free(acb->buf);
|
||||||
acb->buf = NULL;
|
acb->buf = NULL;
|
||||||
|
|
||||||
aio_context_acquire(ctx);
|
|
||||||
acb->common.cb(acb->common.opaque, acb->status);
|
acb->common.cb(acb->common.opaque, acb->status);
|
||||||
aio_context_release(ctx);
|
|
||||||
|
|
||||||
if (acb->task != NULL) {
|
if (acb->task != NULL) {
|
||||||
scsi_free_scsi_task(acb->task);
|
scsi_free_scsi_task(acb->task);
|
||||||
|
@ -75,7 +75,6 @@ static inline ssize_t io_event_ret(struct io_event *ev)
|
|||||||
*/
|
*/
|
||||||
static void qemu_laio_process_completion(struct qemu_laiocb *laiocb)
|
static void qemu_laio_process_completion(struct qemu_laiocb *laiocb)
|
||||||
{
|
{
|
||||||
LinuxAioState *s = laiocb->ctx;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = laiocb->ret;
|
ret = laiocb->ret;
|
||||||
@ -94,7 +93,6 @@ static void qemu_laio_process_completion(struct qemu_laiocb *laiocb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
laiocb->ret = ret;
|
laiocb->ret = ret;
|
||||||
aio_context_acquire(s->aio_context);
|
|
||||||
if (laiocb->co) {
|
if (laiocb->co) {
|
||||||
/* If the coroutine is already entered it must be in ioq_submit() and
|
/* If the coroutine is already entered it must be in ioq_submit() and
|
||||||
* will notice laio->ret has been filled in when it eventually runs
|
* will notice laio->ret has been filled in when it eventually runs
|
||||||
@ -102,13 +100,12 @@ static void qemu_laio_process_completion(struct qemu_laiocb *laiocb)
|
|||||||
* that!
|
* that!
|
||||||
*/
|
*/
|
||||||
if (!qemu_coroutine_entered(laiocb->co)) {
|
if (!qemu_coroutine_entered(laiocb->co)) {
|
||||||
qemu_coroutine_enter(laiocb->co);
|
aio_co_wake(laiocb->co);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
laiocb->common.cb(laiocb->common.opaque, ret);
|
laiocb->common.cb(laiocb->common.opaque, ret);
|
||||||
qemu_aio_unref(laiocb);
|
qemu_aio_unref(laiocb);
|
||||||
}
|
}
|
||||||
aio_context_release(s->aio_context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -132,6 +132,8 @@ static void mirror_write_complete(void *opaque, int ret)
|
|||||||
{
|
{
|
||||||
MirrorOp *op = opaque;
|
MirrorOp *op = opaque;
|
||||||
MirrorBlockJob *s = op->s;
|
MirrorBlockJob *s = op->s;
|
||||||
|
|
||||||
|
aio_context_acquire(blk_get_aio_context(s->common.blk));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
BlockErrorAction action;
|
BlockErrorAction action;
|
||||||
|
|
||||||
@ -142,12 +144,15 @@ static void mirror_write_complete(void *opaque, int ret)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
mirror_iteration_done(op, ret);
|
mirror_iteration_done(op, ret);
|
||||||
|
aio_context_release(blk_get_aio_context(s->common.blk));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mirror_read_complete(void *opaque, int ret)
|
static void mirror_read_complete(void *opaque, int ret)
|
||||||
{
|
{
|
||||||
MirrorOp *op = opaque;
|
MirrorOp *op = opaque;
|
||||||
MirrorBlockJob *s = op->s;
|
MirrorBlockJob *s = op->s;
|
||||||
|
|
||||||
|
aio_context_acquire(blk_get_aio_context(s->common.blk));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
BlockErrorAction action;
|
BlockErrorAction action;
|
||||||
|
|
||||||
@ -158,10 +163,11 @@ static void mirror_read_complete(void *opaque, int ret)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mirror_iteration_done(op, ret);
|
mirror_iteration_done(op, ret);
|
||||||
return;
|
} else {
|
||||||
}
|
|
||||||
blk_aio_pwritev(s->target, op->sector_num * BDRV_SECTOR_SIZE, &op->qiov,
|
blk_aio_pwritev(s->target, op->sector_num * BDRV_SECTOR_SIZE, &op->qiov,
|
||||||
0, mirror_write_complete, op);
|
0, mirror_write_complete, op);
|
||||||
|
}
|
||||||
|
aio_context_release(blk_get_aio_context(s->common.blk));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void mirror_clip_sectors(MirrorBlockJob *s,
|
static inline void mirror_clip_sectors(MirrorBlockJob *s,
|
||||||
|
@ -134,22 +134,14 @@ static const AIOCBInfo null_aiocb_info = {
|
|||||||
static void null_bh_cb(void *opaque)
|
static void null_bh_cb(void *opaque)
|
||||||
{
|
{
|
||||||
NullAIOCB *acb = opaque;
|
NullAIOCB *acb = opaque;
|
||||||
AioContext *ctx = bdrv_get_aio_context(acb->common.bs);
|
|
||||||
|
|
||||||
aio_context_acquire(ctx);
|
|
||||||
acb->common.cb(acb->common.opaque, 0);
|
acb->common.cb(acb->common.opaque, 0);
|
||||||
aio_context_release(ctx);
|
|
||||||
qemu_aio_unref(acb);
|
qemu_aio_unref(acb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void null_timer_cb(void *opaque)
|
static void null_timer_cb(void *opaque)
|
||||||
{
|
{
|
||||||
NullAIOCB *acb = opaque;
|
NullAIOCB *acb = opaque;
|
||||||
AioContext *ctx = bdrv_get_aio_context(acb->common.bs);
|
|
||||||
|
|
||||||
aio_context_acquire(ctx);
|
|
||||||
acb->common.cb(acb->common.opaque, 0);
|
acb->common.cb(acb->common.opaque, 0);
|
||||||
aio_context_release(ctx);
|
|
||||||
timer_deinit(&acb->timer);
|
timer_deinit(&acb->timer);
|
||||||
qemu_aio_unref(acb);
|
qemu_aio_unref(acb);
|
||||||
}
|
}
|
||||||
|
@ -83,6 +83,7 @@ static void qed_find_cluster_cb(void *opaque, int ret)
|
|||||||
unsigned int index;
|
unsigned int index;
|
||||||
unsigned int n;
|
unsigned int n;
|
||||||
|
|
||||||
|
qed_acquire(s);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -109,6 +110,7 @@ static void qed_find_cluster_cb(void *opaque, int ret)
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
find_cluster_cb->cb(find_cluster_cb->opaque, ret, offset, len);
|
find_cluster_cb->cb(find_cluster_cb->opaque, ret, offset, len);
|
||||||
|
qed_release(s);
|
||||||
g_free(find_cluster_cb);
|
g_free(find_cluster_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ static void qed_read_table_cb(void *opaque, int ret)
|
|||||||
{
|
{
|
||||||
QEDReadTableCB *read_table_cb = opaque;
|
QEDReadTableCB *read_table_cb = opaque;
|
||||||
QEDTable *table = read_table_cb->table;
|
QEDTable *table = read_table_cb->table;
|
||||||
|
BDRVQEDState *s = read_table_cb->s;
|
||||||
int noffsets = read_table_cb->qiov.size / sizeof(uint64_t);
|
int noffsets = read_table_cb->qiov.size / sizeof(uint64_t);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -40,13 +41,15 @@ static void qed_read_table_cb(void *opaque, int ret)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Byteswap offsets */
|
/* Byteswap offsets */
|
||||||
|
qed_acquire(s);
|
||||||
for (i = 0; i < noffsets; i++) {
|
for (i = 0; i < noffsets; i++) {
|
||||||
table->offsets[i] = le64_to_cpu(table->offsets[i]);
|
table->offsets[i] = le64_to_cpu(table->offsets[i]);
|
||||||
}
|
}
|
||||||
|
qed_release(s);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
/* Completion */
|
/* Completion */
|
||||||
trace_qed_read_table_cb(read_table_cb->s, read_table_cb->table, ret);
|
trace_qed_read_table_cb(s, read_table_cb->table, ret);
|
||||||
gencb_complete(&read_table_cb->gencb, ret);
|
gencb_complete(&read_table_cb->gencb, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,8 +87,9 @@ typedef struct {
|
|||||||
static void qed_write_table_cb(void *opaque, int ret)
|
static void qed_write_table_cb(void *opaque, int ret)
|
||||||
{
|
{
|
||||||
QEDWriteTableCB *write_table_cb = opaque;
|
QEDWriteTableCB *write_table_cb = opaque;
|
||||||
|
BDRVQEDState *s = write_table_cb->s;
|
||||||
|
|
||||||
trace_qed_write_table_cb(write_table_cb->s,
|
trace_qed_write_table_cb(s,
|
||||||
write_table_cb->orig_table,
|
write_table_cb->orig_table,
|
||||||
write_table_cb->flush,
|
write_table_cb->flush,
|
||||||
ret);
|
ret);
|
||||||
@ -97,8 +101,10 @@ static void qed_write_table_cb(void *opaque, int ret)
|
|||||||
if (write_table_cb->flush) {
|
if (write_table_cb->flush) {
|
||||||
/* We still need to flush first */
|
/* We still need to flush first */
|
||||||
write_table_cb->flush = false;
|
write_table_cb->flush = false;
|
||||||
|
qed_acquire(s);
|
||||||
bdrv_aio_flush(write_table_cb->s->bs, qed_write_table_cb,
|
bdrv_aio_flush(write_table_cb->s->bs, qed_write_table_cb,
|
||||||
write_table_cb);
|
write_table_cb);
|
||||||
|
qed_release(s);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,6 +219,7 @@ static void qed_read_l2_table_cb(void *opaque, int ret)
|
|||||||
CachedL2Table *l2_table = request->l2_table;
|
CachedL2Table *l2_table = request->l2_table;
|
||||||
uint64_t l2_offset = read_l2_table_cb->l2_offset;
|
uint64_t l2_offset = read_l2_table_cb->l2_offset;
|
||||||
|
|
||||||
|
qed_acquire(s);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
/* can't trust loaded L2 table anymore */
|
/* can't trust loaded L2 table anymore */
|
||||||
qed_unref_l2_cache_entry(l2_table);
|
qed_unref_l2_cache_entry(l2_table);
|
||||||
@ -228,6 +235,7 @@ static void qed_read_l2_table_cb(void *opaque, int ret)
|
|||||||
request->l2_table = qed_find_l2_cache_entry(&s->l2_cache, l2_offset);
|
request->l2_table = qed_find_l2_cache_entry(&s->l2_cache, l2_offset);
|
||||||
assert(request->l2_table != NULL);
|
assert(request->l2_table != NULL);
|
||||||
}
|
}
|
||||||
|
qed_release(s);
|
||||||
|
|
||||||
gencb_complete(&read_l2_table_cb->gencb, ret);
|
gencb_complete(&read_l2_table_cb->gencb, ret);
|
||||||
}
|
}
|
||||||
|
@ -745,7 +745,7 @@ static void qed_is_allocated_cb(void *opaque, int ret, uint64_t offset, size_t l
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cb->co) {
|
if (cb->co) {
|
||||||
qemu_coroutine_enter(cb->co);
|
aio_co_wake(cb->co);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1462,7 +1462,7 @@ static void coroutine_fn qed_co_pwrite_zeroes_cb(void *opaque, int ret)
|
|||||||
cb->done = true;
|
cb->done = true;
|
||||||
cb->ret = ret;
|
cb->ret = ret;
|
||||||
if (cb->co) {
|
if (cb->co) {
|
||||||
qemu_coroutine_enter(cb->co);
|
aio_co_wake(cb->co);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,7 +413,6 @@ shutdown:
|
|||||||
static void qemu_rbd_complete_aio(RADOSCB *rcb)
|
static void qemu_rbd_complete_aio(RADOSCB *rcb)
|
||||||
{
|
{
|
||||||
RBDAIOCB *acb = rcb->acb;
|
RBDAIOCB *acb = rcb->acb;
|
||||||
AioContext *ctx = bdrv_get_aio_context(acb->common.bs);
|
|
||||||
int64_t r;
|
int64_t r;
|
||||||
|
|
||||||
r = rcb->ret;
|
r = rcb->ret;
|
||||||
@ -446,10 +445,7 @@ static void qemu_rbd_complete_aio(RADOSCB *rcb)
|
|||||||
qemu_iovec_from_buf(acb->qiov, 0, acb->bounce, acb->qiov->size);
|
qemu_iovec_from_buf(acb->qiov, 0, acb->bounce, acb->qiov->size);
|
||||||
}
|
}
|
||||||
qemu_vfree(acb->bounce);
|
qemu_vfree(acb->bounce);
|
||||||
|
|
||||||
aio_context_acquire(ctx);
|
|
||||||
acb->common.cb(acb->common.opaque, (acb->ret > 0 ? 0 : acb->ret));
|
acb->common.cb(acb->common.opaque, (acb->ret > 0 ? 0 : acb->ret));
|
||||||
aio_context_release(ctx);
|
|
||||||
|
|
||||||
qemu_aio_unref(acb);
|
qemu_aio_unref(acb);
|
||||||
}
|
}
|
||||||
|
@ -87,10 +87,7 @@ static void win32_aio_process_completion(QEMUWin32AIOState *s,
|
|||||||
qemu_vfree(waiocb->buf);
|
qemu_vfree(waiocb->buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
aio_context_acquire(s->aio_ctx);
|
|
||||||
waiocb->common.cb(waiocb->common.opaque, ret);
|
waiocb->common.cb(waiocb->common.opaque, ret);
|
||||||
aio_context_release(s->aio_ctx);
|
|
||||||
qemu_aio_unref(waiocb);
|
qemu_aio_unref(waiocb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,9 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
|
|||||||
static void virtio_blk_rw_complete(void *opaque, int ret)
|
static void virtio_blk_rw_complete(void *opaque, int ret)
|
||||||
{
|
{
|
||||||
VirtIOBlockReq *next = opaque;
|
VirtIOBlockReq *next = opaque;
|
||||||
|
VirtIOBlock *s = next->dev;
|
||||||
|
|
||||||
|
aio_context_acquire(blk_get_aio_context(s->conf.conf.blk));
|
||||||
while (next) {
|
while (next) {
|
||||||
VirtIOBlockReq *req = next;
|
VirtIOBlockReq *req = next;
|
||||||
next = req->mr_next;
|
next = req->mr_next;
|
||||||
@ -122,21 +124,27 @@ static void virtio_blk_rw_complete(void *opaque, int ret)
|
|||||||
block_acct_done(blk_get_stats(req->dev->blk), &req->acct);
|
block_acct_done(blk_get_stats(req->dev->blk), &req->acct);
|
||||||
virtio_blk_free_request(req);
|
virtio_blk_free_request(req);
|
||||||
}
|
}
|
||||||
|
aio_context_release(blk_get_aio_context(s->conf.conf.blk));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void virtio_blk_flush_complete(void *opaque, int ret)
|
static void virtio_blk_flush_complete(void *opaque, int ret)
|
||||||
{
|
{
|
||||||
VirtIOBlockReq *req = opaque;
|
VirtIOBlockReq *req = opaque;
|
||||||
|
VirtIOBlock *s = req->dev;
|
||||||
|
|
||||||
|
aio_context_acquire(blk_get_aio_context(s->conf.conf.blk));
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (virtio_blk_handle_rw_error(req, -ret, 0)) {
|
if (virtio_blk_handle_rw_error(req, -ret, 0)) {
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
|
virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
|
||||||
block_acct_done(blk_get_stats(req->dev->blk), &req->acct);
|
block_acct_done(blk_get_stats(req->dev->blk), &req->acct);
|
||||||
virtio_blk_free_request(req);
|
virtio_blk_free_request(req);
|
||||||
|
|
||||||
|
out:
|
||||||
|
aio_context_release(blk_get_aio_context(s->conf.conf.blk));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
@ -183,8 +191,10 @@ static void virtio_blk_ioctl_complete(void *opaque, int status)
|
|||||||
virtio_stl_p(vdev, &scsi->data_len, hdr->dxfer_len);
|
virtio_stl_p(vdev, &scsi->data_len, hdr->dxfer_len);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
aio_context_acquire(blk_get_aio_context(s->conf.conf.blk));
|
||||||
virtio_blk_req_complete(req, status);
|
virtio_blk_req_complete(req, status);
|
||||||
virtio_blk_free_request(req);
|
virtio_blk_free_request(req);
|
||||||
|
aio_context_release(blk_get_aio_context(s->conf.conf.blk));
|
||||||
g_free(ioctl_req);
|
g_free(ioctl_req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,6 +207,7 @@ static void scsi_aio_complete(void *opaque, int ret)
|
|||||||
|
|
||||||
assert(r->req.aiocb != NULL);
|
assert(r->req.aiocb != NULL);
|
||||||
r->req.aiocb = NULL;
|
r->req.aiocb = NULL;
|
||||||
|
aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
||||||
if (scsi_disk_req_check_error(r, ret, true)) {
|
if (scsi_disk_req_check_error(r, ret, true)) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -215,6 +216,7 @@ static void scsi_aio_complete(void *opaque, int ret)
|
|||||||
scsi_req_complete(&r->req, GOOD);
|
scsi_req_complete(&r->req, GOOD);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
|
||||||
scsi_req_unref(&r->req);
|
scsi_req_unref(&r->req);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,12 +292,14 @@ static void scsi_dma_complete(void *opaque, int ret)
|
|||||||
assert(r->req.aiocb != NULL);
|
assert(r->req.aiocb != NULL);
|
||||||
r->req.aiocb = NULL;
|
r->req.aiocb = NULL;
|
||||||
|
|
||||||
|
aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
||||||
} else {
|
} else {
|
||||||
block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
||||||
}
|
}
|
||||||
scsi_dma_complete_noio(r, ret);
|
scsi_dma_complete_noio(r, ret);
|
||||||
|
aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scsi_read_complete(void * opaque, int ret)
|
static void scsi_read_complete(void * opaque, int ret)
|
||||||
@ -306,6 +310,7 @@ static void scsi_read_complete(void * opaque, int ret)
|
|||||||
|
|
||||||
assert(r->req.aiocb != NULL);
|
assert(r->req.aiocb != NULL);
|
||||||
r->req.aiocb = NULL;
|
r->req.aiocb = NULL;
|
||||||
|
aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
||||||
if (scsi_disk_req_check_error(r, ret, true)) {
|
if (scsi_disk_req_check_error(r, ret, true)) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -320,6 +325,7 @@ static void scsi_read_complete(void * opaque, int ret)
|
|||||||
|
|
||||||
done:
|
done:
|
||||||
scsi_req_unref(&r->req);
|
scsi_req_unref(&r->req);
|
||||||
|
aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Actually issue a read to the block device. */
|
/* Actually issue a read to the block device. */
|
||||||
@ -364,12 +370,14 @@ static void scsi_do_read_cb(void *opaque, int ret)
|
|||||||
assert (r->req.aiocb != NULL);
|
assert (r->req.aiocb != NULL);
|
||||||
r->req.aiocb = NULL;
|
r->req.aiocb = NULL;
|
||||||
|
|
||||||
|
aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
||||||
} else {
|
} else {
|
||||||
block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
||||||
}
|
}
|
||||||
scsi_do_read(opaque, ret);
|
scsi_do_read(opaque, ret);
|
||||||
|
aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read more data from scsi device into buffer. */
|
/* Read more data from scsi device into buffer. */
|
||||||
@ -489,12 +497,14 @@ static void scsi_write_complete(void * opaque, int ret)
|
|||||||
assert (r->req.aiocb != NULL);
|
assert (r->req.aiocb != NULL);
|
||||||
r->req.aiocb = NULL;
|
r->req.aiocb = NULL;
|
||||||
|
|
||||||
|
aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
||||||
} else {
|
} else {
|
||||||
block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
||||||
}
|
}
|
||||||
scsi_write_complete_noio(r, ret);
|
scsi_write_complete_noio(r, ret);
|
||||||
|
aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scsi_write_data(SCSIRequest *req)
|
static void scsi_write_data(SCSIRequest *req)
|
||||||
@ -1625,11 +1635,14 @@ static void scsi_unmap_complete(void *opaque, int ret)
|
|||||||
{
|
{
|
||||||
UnmapCBData *data = opaque;
|
UnmapCBData *data = opaque;
|
||||||
SCSIDiskReq *r = data->r;
|
SCSIDiskReq *r = data->r;
|
||||||
|
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
||||||
|
|
||||||
assert(r->req.aiocb != NULL);
|
assert(r->req.aiocb != NULL);
|
||||||
r->req.aiocb = NULL;
|
r->req.aiocb = NULL;
|
||||||
|
|
||||||
|
aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
||||||
scsi_unmap_complete_noio(data, ret);
|
scsi_unmap_complete_noio(data, ret);
|
||||||
|
aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scsi_disk_emulate_unmap(SCSIDiskReq *r, uint8_t *inbuf)
|
static void scsi_disk_emulate_unmap(SCSIDiskReq *r, uint8_t *inbuf)
|
||||||
@ -1696,6 +1709,7 @@ static void scsi_write_same_complete(void *opaque, int ret)
|
|||||||
|
|
||||||
assert(r->req.aiocb != NULL);
|
assert(r->req.aiocb != NULL);
|
||||||
r->req.aiocb = NULL;
|
r->req.aiocb = NULL;
|
||||||
|
aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
||||||
if (scsi_disk_req_check_error(r, ret, true)) {
|
if (scsi_disk_req_check_error(r, ret, true)) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -1724,6 +1738,7 @@ done:
|
|||||||
scsi_req_unref(&r->req);
|
scsi_req_unref(&r->req);
|
||||||
qemu_vfree(data->iov.iov_base);
|
qemu_vfree(data->iov.iov_base);
|
||||||
g_free(data);
|
g_free(data);
|
||||||
|
aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf)
|
static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf)
|
||||||
|
@ -143,10 +143,14 @@ done:
|
|||||||
static void scsi_command_complete(void *opaque, int ret)
|
static void scsi_command_complete(void *opaque, int ret)
|
||||||
{
|
{
|
||||||
SCSIGenericReq *r = (SCSIGenericReq *)opaque;
|
SCSIGenericReq *r = (SCSIGenericReq *)opaque;
|
||||||
|
SCSIDevice *s = r->req.dev;
|
||||||
|
|
||||||
assert(r->req.aiocb != NULL);
|
assert(r->req.aiocb != NULL);
|
||||||
r->req.aiocb = NULL;
|
r->req.aiocb = NULL;
|
||||||
|
|
||||||
|
aio_context_acquire(blk_get_aio_context(s->conf.blk));
|
||||||
scsi_command_complete_noio(r, ret);
|
scsi_command_complete_noio(r, ret);
|
||||||
|
aio_context_release(blk_get_aio_context(s->conf.blk));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int execute_command(BlockBackend *blk,
|
static int execute_command(BlockBackend *blk,
|
||||||
@ -182,9 +186,11 @@ static void scsi_read_complete(void * opaque, int ret)
|
|||||||
assert(r->req.aiocb != NULL);
|
assert(r->req.aiocb != NULL);
|
||||||
r->req.aiocb = NULL;
|
r->req.aiocb = NULL;
|
||||||
|
|
||||||
|
aio_context_acquire(blk_get_aio_context(s->conf.blk));
|
||||||
|
|
||||||
if (ret || r->req.io_canceled) {
|
if (ret || r->req.io_canceled) {
|
||||||
scsi_command_complete_noio(r, ret);
|
scsi_command_complete_noio(r, ret);
|
||||||
return;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = r->io_header.dxfer_len - r->io_header.resid;
|
len = r->io_header.dxfer_len - r->io_header.resid;
|
||||||
@ -193,7 +199,7 @@ static void scsi_read_complete(void * opaque, int ret)
|
|||||||
r->len = -1;
|
r->len = -1;
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
scsi_command_complete_noio(r, 0);
|
scsi_command_complete_noio(r, 0);
|
||||||
return;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Snoop READ CAPACITY output to set the blocksize. */
|
/* Snoop READ CAPACITY output to set the blocksize. */
|
||||||
@ -237,6 +243,9 @@ static void scsi_read_complete(void * opaque, int ret)
|
|||||||
}
|
}
|
||||||
scsi_req_data(&r->req, len);
|
scsi_req_data(&r->req, len);
|
||||||
scsi_req_unref(&r->req);
|
scsi_req_unref(&r->req);
|
||||||
|
|
||||||
|
done:
|
||||||
|
aio_context_release(blk_get_aio_context(s->conf.blk));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read more data from scsi device into buffer. */
|
/* Read more data from scsi device into buffer. */
|
||||||
@ -272,9 +281,11 @@ static void scsi_write_complete(void * opaque, int ret)
|
|||||||
assert(r->req.aiocb != NULL);
|
assert(r->req.aiocb != NULL);
|
||||||
r->req.aiocb = NULL;
|
r->req.aiocb = NULL;
|
||||||
|
|
||||||
|
aio_context_acquire(blk_get_aio_context(s->conf.blk));
|
||||||
|
|
||||||
if (ret || r->req.io_canceled) {
|
if (ret || r->req.io_canceled) {
|
||||||
scsi_command_complete_noio(r, ret);
|
scsi_command_complete_noio(r, ret);
|
||||||
return;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
|
if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
|
||||||
@ -284,6 +295,9 @@ static void scsi_write_complete(void * opaque, int ret)
|
|||||||
}
|
}
|
||||||
|
|
||||||
scsi_command_complete_noio(r, ret);
|
scsi_command_complete_noio(r, ret);
|
||||||
|
|
||||||
|
done:
|
||||||
|
aio_context_release(blk_get_aio_context(s->conf.blk));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write data to a scsi device. Returns nonzero on failure.
|
/* Write data to a scsi device. Returns nonzero on failure.
|
||||||
|
@ -185,7 +185,9 @@ restart:
|
|||||||
*/
|
*/
|
||||||
qemu_bh_schedule(pool->completion_bh);
|
qemu_bh_schedule(pool->completion_bh);
|
||||||
|
|
||||||
|
aio_context_release(pool->ctx);
|
||||||
elem->common.cb(elem->common.opaque, elem->ret);
|
elem->common.cb(elem->common.opaque, elem->ret);
|
||||||
|
aio_context_acquire(pool->ctx);
|
||||||
qemu_aio_unref(elem);
|
qemu_aio_unref(elem);
|
||||||
goto restart;
|
goto restart;
|
||||||
} else {
|
} else {
|
||||||
@ -269,7 +271,7 @@ static void thread_pool_co_cb(void *opaque, int ret)
|
|||||||
ThreadPoolCo *co = opaque;
|
ThreadPoolCo *co = opaque;
|
||||||
|
|
||||||
co->ret = ret;
|
co->ret = ret;
|
||||||
qemu_coroutine_enter(co->co);
|
aio_co_wake(co->co);
|
||||||
}
|
}
|
||||||
|
|
||||||
int coroutine_fn thread_pool_submit_co(ThreadPool *pool, ThreadPoolFunc *func,
|
int coroutine_fn thread_pool_submit_co(ThreadPool *pool, ThreadPoolFunc *func,
|
||||||
|
Loading…
Reference in New Issue
Block a user