block: remove AIOCBInfo->get_aio_context()
The synchronous bdrv_aio_cancel() function needs the acb's AioContext so it can call aio_poll() to wait for cancellation. It turns out that all users run under the BQL in the main AioContext, so this callback is not needed. Remove the callback, mark bdrv_aio_cancel() GLOBAL_STATE_CODE just like its blk_aio_cancel() caller, and poll the main loop AioContext. The purpose of this cleanup is to identify bdrv_aio_cancel() as an API that does not work with the multi-queue block layer. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Message-ID: <20230912231037.826804-2-stefanha@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Klaus Jensen <k.jensen@samsung.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
52b10c9c0c
commit
652b0dd808
@ -33,8 +33,6 @@
|
||||
|
||||
#define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
|
||||
|
||||
static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb);
|
||||
|
||||
typedef struct BlockBackendAioNotifier {
|
||||
void (*attached_aio_context)(AioContext *new_context, void *opaque);
|
||||
void (*detach_aio_context)(void *opaque);
|
||||
@ -103,7 +101,6 @@ typedef struct BlockBackendAIOCB {
|
||||
} BlockBackendAIOCB;
|
||||
|
||||
static const AIOCBInfo block_backend_aiocb_info = {
|
||||
.get_aio_context = blk_aiocb_get_aio_context,
|
||||
.aiocb_size = sizeof(BlockBackendAIOCB),
|
||||
};
|
||||
|
||||
@ -1562,16 +1559,8 @@ typedef struct BlkAioEmAIOCB {
|
||||
bool has_returned;
|
||||
} BlkAioEmAIOCB;
|
||||
|
||||
static AioContext *blk_aio_em_aiocb_get_aio_context(BlockAIOCB *acb_)
|
||||
{
|
||||
BlkAioEmAIOCB *acb = container_of(acb_, BlkAioEmAIOCB, common);
|
||||
|
||||
return blk_get_aio_context(acb->rwco.blk);
|
||||
}
|
||||
|
||||
static const AIOCBInfo blk_aio_em_aiocb_info = {
|
||||
.aiocb_size = sizeof(BlkAioEmAIOCB),
|
||||
.get_aio_context = blk_aio_em_aiocb_get_aio_context,
|
||||
};
|
||||
|
||||
static void blk_aio_complete(BlkAioEmAIOCB *acb)
|
||||
@ -2451,12 +2440,6 @@ AioContext *blk_get_aio_context(BlockBackend *blk)
|
||||
return blk->ctx;
|
||||
}
|
||||
|
||||
static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb)
|
||||
{
|
||||
BlockBackendAIOCB *blk_acb = DO_UPCAST(BlockBackendAIOCB, common, acb);
|
||||
return blk_get_aio_context(blk_acb->blk);
|
||||
}
|
||||
|
||||
int blk_set_aio_context(BlockBackend *blk, AioContext *new_context,
|
||||
Error **errp)
|
||||
{
|
||||
|
23
block/io.c
23
block/io.c
@ -2950,25 +2950,18 @@ int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
|
||||
/**************************************************************/
|
||||
/* async I/Os */
|
||||
|
||||
/**
|
||||
* Synchronously cancels an acb. Must be called with the BQL held and the acb
|
||||
* must be processed with the BQL held too (IOThreads are not allowed).
|
||||
*
|
||||
* Use bdrv_aio_cancel_async() instead when possible.
|
||||
*/
|
||||
void bdrv_aio_cancel(BlockAIOCB *acb)
|
||||
{
|
||||
IO_CODE();
|
||||
GLOBAL_STATE_CODE();
|
||||
qemu_aio_ref(acb);
|
||||
bdrv_aio_cancel_async(acb);
|
||||
while (acb->refcnt > 1) {
|
||||
if (acb->aiocb_info->get_aio_context) {
|
||||
aio_poll(acb->aiocb_info->get_aio_context(acb), true);
|
||||
} else if (acb->bs) {
|
||||
/* qemu_aio_ref and qemu_aio_unref are not thread-safe, so
|
||||
* assert that we're not using an I/O thread. Thread-safe
|
||||
* code should use bdrv_aio_cancel_async exclusively.
|
||||
*/
|
||||
assert(bdrv_get_aio_context(acb->bs) == qemu_get_aio_context());
|
||||
aio_poll(bdrv_get_aio_context(acb->bs), true);
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
AIO_WAIT_WHILE_UNLOCKED(NULL, acb->refcnt > 1);
|
||||
qemu_aio_unref(acb);
|
||||
}
|
||||
|
||||
|
@ -2130,11 +2130,6 @@ static inline bool nvme_is_write(NvmeRequest *req)
|
||||
rw->opcode == NVME_CMD_WRITE_ZEROES;
|
||||
}
|
||||
|
||||
static AioContext *nvme_get_aio_context(BlockAIOCB *acb)
|
||||
{
|
||||
return qemu_get_aio_context();
|
||||
}
|
||||
|
||||
static void nvme_misc_cb(void *opaque, int ret)
|
||||
{
|
||||
NvmeRequest *req = opaque;
|
||||
@ -3302,7 +3297,6 @@ static void nvme_flush_cancel(BlockAIOCB *acb)
|
||||
static const AIOCBInfo nvme_flush_aiocb_info = {
|
||||
.aiocb_size = sizeof(NvmeFlushAIOCB),
|
||||
.cancel_async = nvme_flush_cancel,
|
||||
.get_aio_context = nvme_get_aio_context,
|
||||
};
|
||||
|
||||
static void nvme_do_flush(NvmeFlushAIOCB *iocb);
|
||||
@ -6478,7 +6472,6 @@ static void nvme_format_cancel(BlockAIOCB *aiocb)
|
||||
static const AIOCBInfo nvme_format_aiocb_info = {
|
||||
.aiocb_size = sizeof(NvmeFormatAIOCB),
|
||||
.cancel_async = nvme_format_cancel,
|
||||
.get_aio_context = nvme_get_aio_context,
|
||||
};
|
||||
|
||||
static void nvme_format_set(NvmeNamespace *ns, uint8_t lbaf, uint8_t mset,
|
||||
|
@ -31,7 +31,6 @@ typedef void BlockCompletionFunc(void *opaque, int ret);
|
||||
|
||||
typedef struct AIOCBInfo {
|
||||
void (*cancel_async)(BlockAIOCB *acb);
|
||||
AioContext *(*get_aio_context)(BlockAIOCB *acb);
|
||||
size_t aiocb_size;
|
||||
} AIOCBInfo;
|
||||
|
||||
|
@ -185,6 +185,8 @@ void bdrv_drain_all_begin_nopoll(void);
|
||||
void bdrv_drain_all_end(void);
|
||||
void bdrv_drain_all(void);
|
||||
|
||||
void bdrv_aio_cancel(BlockAIOCB *acb);
|
||||
|
||||
int bdrv_has_zero_init_1(BlockDriverState *bs);
|
||||
int bdrv_has_zero_init(BlockDriverState *bs);
|
||||
BlockDriverState *bdrv_find_node(const char *node_name);
|
||||
|
@ -101,7 +101,6 @@ bdrv_co_delete_file_noerr(BlockDriverState *bs);
|
||||
|
||||
|
||||
/* async block I/O */
|
||||
void bdrv_aio_cancel(BlockAIOCB *acb);
|
||||
void bdrv_aio_cancel_async(BlockAIOCB *acb);
|
||||
|
||||
/* sg packet commands */
|
||||
|
@ -206,17 +206,9 @@ static void dma_aio_cancel(BlockAIOCB *acb)
|
||||
}
|
||||
}
|
||||
|
||||
static AioContext *dma_get_aio_context(BlockAIOCB *acb)
|
||||
{
|
||||
DMAAIOCB *dbs = container_of(acb, DMAAIOCB, common);
|
||||
|
||||
return dbs->ctx;
|
||||
}
|
||||
|
||||
static const AIOCBInfo dma_aiocb_info = {
|
||||
.aiocb_size = sizeof(DMAAIOCB),
|
||||
.cancel_async = dma_aio_cancel,
|
||||
.get_aio_context = dma_get_aio_context,
|
||||
};
|
||||
|
||||
BlockAIOCB *dma_blk_io(AioContext *ctx,
|
||||
|
@ -228,17 +228,9 @@ static void thread_pool_cancel(BlockAIOCB *acb)
|
||||
|
||||
}
|
||||
|
||||
static AioContext *thread_pool_get_aio_context(BlockAIOCB *acb)
|
||||
{
|
||||
ThreadPoolElement *elem = (ThreadPoolElement *)acb;
|
||||
ThreadPool *pool = elem->pool;
|
||||
return pool->ctx;
|
||||
}
|
||||
|
||||
static const AIOCBInfo thread_pool_aiocb_info = {
|
||||
.aiocb_size = sizeof(ThreadPoolElement),
|
||||
.cancel_async = thread_pool_cancel,
|
||||
.get_aio_context = thread_pool_get_aio_context,
|
||||
};
|
||||
|
||||
BlockAIOCB *thread_pool_submit_aio(ThreadPoolFunc *func, void *arg,
|
||||
|
Loading…
Reference in New Issue
Block a user