@@ -27,9 +27,6 @@
#include "qom/object_interfaces.h"
struct VirtIOBlockDataPlane {
- bool starting;
- bool stopping;
-
VirtIOBlkConf *conf;
VirtIODevice *vdev;
QEMUBH *bh; /* bh for guest notification */
@@ -145,7 +142,7 @@ void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s)
}
vblk = VIRTIO_BLK(s->vdev);
- assert(!vblk->dataplane_started);
+ assert(qatomic_read(&vblk->dataplane_state) != DATAPLANE_STARTED);
g_free(s->batch_notify_vqs);
qemu_bh_delete(s->bh);
if (s->iothread) {
@@ -167,11 +164,11 @@ int virtio_blk_data_plane_start(VirtIODevice *vdev)
Error *local_err = NULL;
int r;
- if (vblk->dataplane_started || s->starting) {
+ if (qatomic_read(&vblk->dataplane_state) <= DATAPLANE_STARTED) {
return 0;
}
- s->starting = true;
+ qatomic_set(&vblk->dataplane_state, DATAPLANE_STARTING);
if (!virtio_vdev_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
s->batch_notifications = true;
@@ -219,8 +216,7 @@ int virtio_blk_data_plane_start(VirtIODevice *vdev)
memory_region_transaction_commit();
- s->starting = false;
- vblk->dataplane_started = true;
+ qatomic_set(&vblk->dataplane_state, DATAPLANE_STARTED);
trace_virtio_blk_data_plane_start(s);
old_context = blk_get_aio_context(s->conf->conf.blk);
@@ -273,8 +269,7 @@ int virtio_blk_data_plane_start(VirtIODevice *vdev)
*/
virtio_blk_process_queued_requests(vblk, false);
vblk->dataplane_disabled = true;
- s->starting = false;
- vblk->dataplane_started = true;
+ qatomic_set(&vblk->dataplane_state, DATAPLANE_STARTED);
return -ENOSYS;
}
@@ -304,17 +299,17 @@ void virtio_blk_data_plane_stop(VirtIODevice *vdev)
unsigned i;
unsigned nvqs = s->conf->num_queues;
- if (!vblk->dataplane_started || s->stopping) {
+ if (qatomic_read(&vblk->dataplane_state) != DATAPLANE_STARTED) {
return;
}
/* Better luck next time. */
if (vblk->dataplane_disabled) {
vblk->dataplane_disabled = false;
- vblk->dataplane_started = false;
+ qatomic_set(&vblk->dataplane_state, DATAPLANE_STOPPED);
return;
}
- s->stopping = true;
+ qatomic_set(&vblk->dataplane_state, DATAPLANE_STOPPING);
trace_virtio_blk_data_plane_stop(s);
aio_context_acquire(s->ctx);
@@ -352,6 +347,5 @@ void virtio_blk_data_plane_stop(VirtIODevice *vdev)
/* Clean up guest notifier (irq) */
k->set_guest_notifiers(qbus->parent, nvqs, false);
- vblk->dataplane_started = false;
- s->stopping = false;
+ qatomic_set(&vblk->dataplane_state, DATAPLANE_STOPPED);
}
@@ -84,7 +84,8 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status)
iov_discard_undo(&req->inhdr_undo);
iov_discard_undo(&req->outhdr_undo);
virtqueue_push(req->vq, &req->elem, req->in_len);
- if (s->dataplane_started && !s->dataplane_disabled) {
+ if (qatomic_read(&s->dataplane_state) == DATAPLANE_STARTED &&
+ !s->dataplane_disabled) {
virtio_blk_data_plane_notify(s->dataplane, req->vq);
} else {
virtio_notify(vdev, req->vq);
@@ -807,7 +808,7 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
{
VirtIOBlock *s = (VirtIOBlock *)vdev;
- if (s->dataplane && !s->dataplane_started) {
+ if (s->dataplane && qatomic_read(&s->dataplane_state) > DATAPLANE_STARTED) {
/* Some guests kick before setting VIRTIO_CONFIG_S_DRIVER_OK so start
* dataplane here instead of waiting for .set_status().
*/
@@ -907,7 +908,7 @@ static void virtio_blk_reset(VirtIODevice *vdev)
aio_context_release(ctx);
- assert(!s->dataplane_started);
+ assert(qatomic_read(&s->dataplane_state) != DATAPLANE_STARTED);
blk_set_enable_write_cache(s->blk, s->original_wce);
}
@@ -1033,7 +1034,7 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
VirtIOBlock *s = VIRTIO_BLK(vdev);
if (!(status & (VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_DRIVER_OK))) {
- assert(!s->dataplane_started);
+ assert(qatomic_read(&s->dataplane_state) != DATAPLANE_STARTED);
}
if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
@@ -60,7 +60,7 @@ struct VirtIOBlock {
bool original_wce;
VMChangeStateEntry *change;
bool dataplane_disabled;
- bool dataplane_started;
+ enum VirtIODataplaneStates dataplane_state;
struct VirtIOBlockDataPlane *dataplane;
uint64_t host_features;
size_t config_size;
Virtio-blk uses VirtIOBlockDataPlane and VirtIOBlock to keep track of the dataplane flags. This is completely unnecessary, as both structures are always accessed together and we can simplify the sages with an enum. Read/write the enum atomically, as it can be read also by iothread callbacks. Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> --- hw/block/dataplane/virtio-blk.c | 24 +++++++++--------------- hw/block/virtio-blk.c | 9 +++++---- include/hw/virtio/virtio-blk.h | 2 +- 3 files changed, 15 insertions(+), 20 deletions(-)