Merge remote-tracking branch 'stefanha/block' into staging
# By Kevin Wolf (4) and others # Via Stefan Hajnoczi * stefanha/block: dataplane: support viostor virtio-pci status bit setting dataplane: avoid reentrancy during virtio_blk_data_plane_stop() win32-aio: use iov utility functions instead of open-coding them win32-aio: Fix memory leak win32-aio: Fix vectored reads aio: Fix return value of aio_poll() ide: Remove wrong assertion block: fix null-pointer bug on error case in block commit
This commit is contained in:
commit
8b17ed4caa
@ -264,5 +264,6 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return progress;
|
assert(progress || busy);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -214,5 +214,6 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
|||||||
events[ret - WAIT_OBJECT_0] = events[--count];
|
events[ret - WAIT_OBJECT_0] = events[--count];
|
||||||
}
|
}
|
||||||
|
|
||||||
return progress;
|
assert(progress || busy);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ static void coroutine_fn commit_run(void *opaque)
|
|||||||
BlockDriverState *active = s->active;
|
BlockDriverState *active = s->active;
|
||||||
BlockDriverState *top = s->top;
|
BlockDriverState *top = s->top;
|
||||||
BlockDriverState *base = s->base;
|
BlockDriverState *base = s->base;
|
||||||
BlockDriverState *overlay_bs = NULL;
|
BlockDriverState *overlay_bs;
|
||||||
int64_t sector_num, end;
|
int64_t sector_num, end;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
@ -92,8 +92,6 @@ static void coroutine_fn commit_run(void *opaque)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
overlay_bs = bdrv_find_overlay(active, top);
|
|
||||||
|
|
||||||
end = s->common.len >> BDRV_SECTOR_BITS;
|
end = s->common.len >> BDRV_SECTOR_BITS;
|
||||||
buf = qemu_blockalign(top, COMMIT_BUFFER_SIZE);
|
buf = qemu_blockalign(top, COMMIT_BUFFER_SIZE);
|
||||||
|
|
||||||
@ -156,7 +154,8 @@ exit_restore_reopen:
|
|||||||
if (s->base_flags != bdrv_get_flags(base)) {
|
if (s->base_flags != bdrv_get_flags(base)) {
|
||||||
bdrv_reopen(base, s->base_flags, NULL);
|
bdrv_reopen(base, s->base_flags, NULL);
|
||||||
}
|
}
|
||||||
if (s->orig_overlay_flags != bdrv_get_flags(overlay_bs)) {
|
overlay_bs = bdrv_find_overlay(active, top);
|
||||||
|
if (overlay_bs && s->orig_overlay_flags != bdrv_get_flags(overlay_bs)) {
|
||||||
bdrv_reopen(overlay_bs, s->orig_overlay_flags, NULL);
|
bdrv_reopen(overlay_bs, s->orig_overlay_flags, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "block/aio.h"
|
#include "block/aio.h"
|
||||||
#include "raw-aio.h"
|
#include "raw-aio.h"
|
||||||
#include "qemu/event_notifier.h"
|
#include "qemu/event_notifier.h"
|
||||||
|
#include "qemu/iov.h"
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <winioctl.h>
|
#include <winioctl.h>
|
||||||
|
|
||||||
@ -80,15 +81,9 @@ static void win32_aio_process_completion(QEMUWin32AIOState *s,
|
|||||||
if (!waiocb->is_linear) {
|
if (!waiocb->is_linear) {
|
||||||
if (ret == 0 && waiocb->is_read) {
|
if (ret == 0 && waiocb->is_read) {
|
||||||
QEMUIOVector *qiov = waiocb->qiov;
|
QEMUIOVector *qiov = waiocb->qiov;
|
||||||
char *p = waiocb->buf;
|
iov_from_buf(qiov->iov, qiov->niov, 0, waiocb->buf, qiov->size);
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < qiov->niov; ++i) {
|
|
||||||
memcpy(p, qiov->iov[i].iov_base, qiov->iov[i].iov_len);
|
|
||||||
p += qiov->iov[i].iov_len;
|
|
||||||
}
|
|
||||||
qemu_vfree(waiocb->buf);
|
|
||||||
}
|
}
|
||||||
|
qemu_vfree(waiocb->buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -153,13 +148,7 @@ BlockDriverAIOCB *win32_aio_submit(BlockDriverState *bs,
|
|||||||
if (qiov->niov > 1) {
|
if (qiov->niov > 1) {
|
||||||
waiocb->buf = qemu_blockalign(bs, qiov->size);
|
waiocb->buf = qemu_blockalign(bs, qiov->size);
|
||||||
if (type & QEMU_AIO_WRITE) {
|
if (type & QEMU_AIO_WRITE) {
|
||||||
char *p = waiocb->buf;
|
iov_to_buf(qiov->iov, qiov->niov, 0, waiocb->buf, qiov->size);
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < qiov->niov; ++i) {
|
|
||||||
memcpy(p, qiov->iov[i].iov_base, qiov->iov[i].iov_len);
|
|
||||||
p += qiov->iov[i].iov_len;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
waiocb->is_linear = false;
|
waiocb->is_linear = false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -40,6 +40,7 @@ typedef struct {
|
|||||||
|
|
||||||
struct VirtIOBlockDataPlane {
|
struct VirtIOBlockDataPlane {
|
||||||
bool started;
|
bool started;
|
||||||
|
bool stopping;
|
||||||
QEMUBH *start_bh;
|
QEMUBH *start_bh;
|
||||||
QemuThread thread;
|
QemuThread thread;
|
||||||
|
|
||||||
@ -357,7 +358,7 @@ static void *data_plane_thread(void *opaque)
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
event_poll(&s->event_poll);
|
event_poll(&s->event_poll);
|
||||||
} while (s->started || s->num_reqs > 0);
|
} while (!s->stopping || s->num_reqs > 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,10 +487,10 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
|
|||||||
|
|
||||||
void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
|
void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
|
||||||
{
|
{
|
||||||
if (!s->started) {
|
if (!s->started || s->stopping) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
s->started = false;
|
s->stopping = true;
|
||||||
trace_virtio_blk_data_plane_stop(s);
|
trace_virtio_blk_data_plane_stop(s);
|
||||||
|
|
||||||
/* Stop thread or cancel pending thread creation BH */
|
/* Stop thread or cancel pending thread creation BH */
|
||||||
@ -511,4 +512,6 @@ void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
|
|||||||
s->vdev->binding->set_guest_notifiers(s->vdev->binding_opaque, 1, false);
|
s->vdev->binding->set_guest_notifiers(s->vdev->binding_opaque, 1, false);
|
||||||
|
|
||||||
vring_teardown(&s->vring);
|
vring_teardown(&s->vring);
|
||||||
|
s->started = false;
|
||||||
|
s->stopping = false;
|
||||||
}
|
}
|
||||||
|
@ -311,7 +311,6 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val)
|
|||||||
if (bm->bus->dma->aiocb) {
|
if (bm->bus->dma->aiocb) {
|
||||||
bdrv_drain_all();
|
bdrv_drain_all();
|
||||||
assert(bm->bus->dma->aiocb == NULL);
|
assert(bm->bus->dma->aiocb == NULL);
|
||||||
assert((bm->status & BM_STATUS_DMAING) == 0);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bm->cur_addr = bm->addr;
|
bm->cur_addr = bm->addr;
|
||||||
|
@ -571,7 +571,8 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
|
|||||||
uint32_t features;
|
uint32_t features;
|
||||||
|
|
||||||
#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
|
#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
|
||||||
if (s->dataplane && !(status & VIRTIO_CONFIG_S_DRIVER)) {
|
if (s->dataplane && !(status & (VIRTIO_CONFIG_S_DRIVER |
|
||||||
|
VIRTIO_CONFIG_S_DRIVER_OK))) {
|
||||||
virtio_blk_data_plane_stop(s->dataplane);
|
virtio_blk_data_plane_stop(s->dataplane);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -173,16 +173,14 @@ bool aio_pending(AioContext *ctx);
|
|||||||
* aio as a result of executing I/O completion or bh callbacks.
|
* aio as a result of executing I/O completion or bh callbacks.
|
||||||
*
|
*
|
||||||
* If there is no pending AIO operation or completion (bottom half),
|
* If there is no pending AIO operation or completion (bottom half),
|
||||||
* return false. If there are pending bottom halves, return true.
|
* return false. If there are pending AIO operations of bottom halves,
|
||||||
|
* return true.
|
||||||
*
|
*
|
||||||
* If there are no pending bottom halves, but there are pending AIO
|
* If there are no pending bottom halves, but there are pending AIO
|
||||||
* operations, it may not be possible to make any progress without
|
* operations, it may not be possible to make any progress without
|
||||||
* blocking. If @blocking is true, this function will wait until one
|
* blocking. If @blocking is true, this function will wait until one
|
||||||
* or more AIO events have completed, to ensure something has moved
|
* or more AIO events have completed, to ensure something has moved
|
||||||
* before returning.
|
* before returning.
|
||||||
*
|
|
||||||
* If @blocking is false, this function will also return false if the
|
|
||||||
* function cannot make any progress without blocking.
|
|
||||||
*/
|
*/
|
||||||
bool aio_poll(AioContext *ctx, bool blocking);
|
bool aio_poll(AioContext *ctx, bool blocking);
|
||||||
|
|
||||||
|
@ -315,13 +315,13 @@ static void test_wait_event_notifier_noflush(void)
|
|||||||
event_notifier_set(&data.e);
|
event_notifier_set(&data.e);
|
||||||
g_assert(aio_poll(ctx, false));
|
g_assert(aio_poll(ctx, false));
|
||||||
g_assert_cmpint(data.n, ==, 1);
|
g_assert_cmpint(data.n, ==, 1);
|
||||||
g_assert(!aio_poll(ctx, false));
|
g_assert(aio_poll(ctx, false));
|
||||||
g_assert_cmpint(data.n, ==, 1);
|
g_assert_cmpint(data.n, ==, 1);
|
||||||
|
|
||||||
event_notifier_set(&data.e);
|
event_notifier_set(&data.e);
|
||||||
g_assert(aio_poll(ctx, false));
|
g_assert(aio_poll(ctx, false));
|
||||||
g_assert_cmpint(data.n, ==, 2);
|
g_assert_cmpint(data.n, ==, 2);
|
||||||
g_assert(!aio_poll(ctx, false));
|
g_assert(aio_poll(ctx, false));
|
||||||
g_assert_cmpint(data.n, ==, 2);
|
g_assert_cmpint(data.n, ==, 2);
|
||||||
|
|
||||||
event_notifier_set(&dummy.e);
|
event_notifier_set(&dummy.e);
|
||||||
|
Loading…
Reference in New Issue
Block a user