block/raw-win32: implement .bdrv_detach/attach_aio_context()
Drop the assumption that we're using the main AioContext for raw-win32. Convert the aio-win32 code to support detach/attach and replace qemu_aio_wait() with aio_poll(). The .bdrv_detach/attach_aio_context() interfaces move the aio-win32 event notifier from the old to the new AioContext. Cc: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
99cc598924
commit
85ebd381fd
|
@ -51,6 +51,10 @@ BlockDriverAIOCB *win32_aio_submit(BlockDriverState *bs,
|
||||||
QEMUWin32AIOState *aio, HANDLE hfile,
|
QEMUWin32AIOState *aio, HANDLE hfile,
|
||||||
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
|
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
|
||||||
BlockDriverCompletionFunc *cb, void *opaque, int type);
|
BlockDriverCompletionFunc *cb, void *opaque, int type);
|
||||||
|
void win32_aio_detach_aio_context(QEMUWin32AIOState *aio,
|
||||||
|
AioContext *old_context);
|
||||||
|
void win32_aio_attach_aio_context(QEMUWin32AIOState *aio,
|
||||||
|
AioContext *new_context);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* QEMU_RAW_AIO_H */
|
#endif /* QEMU_RAW_AIO_H */
|
||||||
|
|
|
@ -200,6 +200,25 @@ static int set_sparse(int fd)
|
||||||
NULL, 0, NULL, 0, &returned, NULL);
|
NULL, 0, NULL, 0, &returned, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void raw_detach_aio_context(BlockDriverState *bs)
|
||||||
|
{
|
||||||
|
BDRVRawState *s = bs->opaque;
|
||||||
|
|
||||||
|
if (s->aio) {
|
||||||
|
win32_aio_detach_aio_context(s->aio, bdrv_get_aio_context(bs));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void raw_attach_aio_context(BlockDriverState *bs,
|
||||||
|
AioContext *new_context)
|
||||||
|
{
|
||||||
|
BDRVRawState *s = bs->opaque;
|
||||||
|
|
||||||
|
if (s->aio) {
|
||||||
|
win32_aio_attach_aio_context(s->aio, new_context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void raw_probe_alignment(BlockDriverState *bs)
|
static void raw_probe_alignment(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BDRVRawState *s = bs->opaque;
|
BDRVRawState *s = bs->opaque;
|
||||||
|
@ -339,6 +358,8 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
|
||||||
error_setg_errno(errp, -ret, "Could not enable AIO");
|
error_setg_errno(errp, -ret, "Could not enable AIO");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
win32_aio_attach_aio_context(s->aio, bdrv_get_aio_context(bs));
|
||||||
}
|
}
|
||||||
|
|
||||||
raw_probe_alignment(bs);
|
raw_probe_alignment(bs);
|
||||||
|
@ -388,6 +409,7 @@ static void raw_close(BlockDriverState *bs)
|
||||||
BDRVRawState *s = bs->opaque;
|
BDRVRawState *s = bs->opaque;
|
||||||
|
|
||||||
if (s->aio) {
|
if (s->aio) {
|
||||||
|
win32_aio_detach_aio_context(s->aio, bdrv_get_aio_context(bs));
|
||||||
win32_aio_cleanup(s->aio);
|
win32_aio_cleanup(s->aio);
|
||||||
s->aio = NULL;
|
s->aio = NULL;
|
||||||
}
|
}
|
||||||
|
@ -687,6 +709,9 @@ static BlockDriver bdrv_host_device = {
|
||||||
.bdrv_aio_writev = raw_aio_writev,
|
.bdrv_aio_writev = raw_aio_writev,
|
||||||
.bdrv_aio_flush = raw_aio_flush,
|
.bdrv_aio_flush = raw_aio_flush,
|
||||||
|
|
||||||
|
.bdrv_detach_aio_context = raw_detach_aio_context,
|
||||||
|
.bdrv_attach_aio_context = raw_attach_aio_context,
|
||||||
|
|
||||||
.bdrv_getlength = raw_getlength,
|
.bdrv_getlength = raw_getlength,
|
||||||
.has_variable_length = true,
|
.has_variable_length = true,
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ struct QEMUWin32AIOState {
|
||||||
HANDLE hIOCP;
|
HANDLE hIOCP;
|
||||||
EventNotifier e;
|
EventNotifier e;
|
||||||
int count;
|
int count;
|
||||||
|
bool is_aio_context_attached;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct QEMUWin32AIOCB {
|
typedef struct QEMUWin32AIOCB {
|
||||||
|
@ -114,7 +115,7 @@ static void win32_aio_cancel(BlockDriverAIOCB *blockacb)
|
||||||
* wait for completion.
|
* wait for completion.
|
||||||
*/
|
*/
|
||||||
while (!HasOverlappedIoCompleted(&waiocb->ov)) {
|
while (!HasOverlappedIoCompleted(&waiocb->ov)) {
|
||||||
qemu_aio_wait();
|
aio_poll(bdrv_get_aio_context(blockacb->bs), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,6 +181,20 @@ int win32_aio_attach(QEMUWin32AIOState *aio, HANDLE hfile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void win32_aio_detach_aio_context(QEMUWin32AIOState *aio,
|
||||||
|
AioContext *old_context)
|
||||||
|
{
|
||||||
|
aio_set_event_notifier(old_context, &aio->e, NULL);
|
||||||
|
aio->is_aio_context_attached = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void win32_aio_attach_aio_context(QEMUWin32AIOState *aio,
|
||||||
|
AioContext *new_context)
|
||||||
|
{
|
||||||
|
aio->is_aio_context_attached = true;
|
||||||
|
aio_set_event_notifier(new_context, &aio->e, win32_aio_completion_cb);
|
||||||
|
}
|
||||||
|
|
||||||
QEMUWin32AIOState *win32_aio_init(void)
|
QEMUWin32AIOState *win32_aio_init(void)
|
||||||
{
|
{
|
||||||
QEMUWin32AIOState *s;
|
QEMUWin32AIOState *s;
|
||||||
|
@ -194,8 +209,6 @@ QEMUWin32AIOState *win32_aio_init(void)
|
||||||
goto out_close_efd;
|
goto out_close_efd;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_aio_set_event_notifier(&s->e, win32_aio_completion_cb);
|
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
|
||||||
out_close_efd:
|
out_close_efd:
|
||||||
|
@ -207,7 +220,7 @@ out_free_state:
|
||||||
|
|
||||||
void win32_aio_cleanup(QEMUWin32AIOState *aio)
|
void win32_aio_cleanup(QEMUWin32AIOState *aio)
|
||||||
{
|
{
|
||||||
qemu_aio_set_event_notifier(&aio->e, NULL);
|
assert(!aio->is_aio_context_attached);
|
||||||
CloseHandle(aio->hIOCP);
|
CloseHandle(aio->hIOCP);
|
||||||
event_notifier_cleanup(&aio->e);
|
event_notifier_cleanup(&aio->e);
|
||||||
g_free(aio);
|
g_free(aio);
|
||||||
|
|
Loading…
Reference in New Issue