diff options
author | Stefan Hajnoczi <stefanha@redhat.com> | 2014-07-09 10:05:49 +0200 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2014-07-14 12:03:20 +0200 |
commit | f897bf751fbd95e4015b95d202c706548586813a (patch) | |
tree | 38023ac92b901f2cd4c7aa45b34549a08cfba9ca /hw/block/dataplane | |
parent | 869d66af53d8e04709456c9cae5cca7c560d4b93 (diff) |
virtio-blk: embed VirtQueueElement in VirtIOBlockReq
The memory allocation between hw/block/virtio-blk.c,
hw/block/dataplane/virtio-blk.c, and hw/virtio/dataplane/vring.c is
messy. Structs are allocated in different files than they are freed in.
This is risky and makes memory leaks easier.
Embed VirtQueueElement in VirtIOBlockReq to reduce the amount of memory
allocation we need to juggle. This also makes vring.c and virtio.c
slightly more similar.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'hw/block/dataplane')
-rw-r--r-- | hw/block/dataplane/virtio-blk.c | 29 |
1 files changed, 14 insertions, 15 deletions
diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c index bed9f13793..227bb15efc 100644 --- a/hw/block/dataplane/virtio-blk.c +++ b/hw/block/dataplane/virtio-blk.c @@ -65,7 +65,7 @@ static void complete_request_vring(VirtIOBlockReq *req, unsigned char status) { stb_p(&req->in->status, status); - vring_push(&req->dev->dataplane->vring, req->elem, + vring_push(&req->dev->dataplane->vring, &req->elem, req->qiov.size + sizeof(*req->in)); notify_guest(req->dev->dataplane); } @@ -74,33 +74,32 @@ static void handle_notify(EventNotifier *e) { VirtIOBlockDataPlane *s = container_of(e, VirtIOBlockDataPlane, host_notifier); - - VirtQueueElement *elem; - VirtIOBlockReq *req; - int ret; - MultiReqBuffer mrb = { - .num_writes = 0, - }; + VirtIOBlock *vblk = VIRTIO_BLK(s->vdev); event_notifier_test_and_clear(&s->host_notifier); bdrv_io_plug(s->blk->conf.bs); for (;;) { + MultiReqBuffer mrb = { + .num_writes = 0, + }; + int ret; + /* Disable guest->host notifies to avoid unnecessary vmexits */ vring_disable_notification(s->vdev, &s->vring); for (;;) { - ret = vring_pop(s->vdev, &s->vring, &elem); + VirtIOBlockReq *req = virtio_blk_alloc_request(vblk); + + ret = vring_pop(s->vdev, &s->vring, &req->elem); if (ret < 0) { - assert(elem == NULL); + virtio_blk_free_request(req); break; /* no more requests */ } - trace_virtio_blk_data_plane_process_request(s, elem->out_num, - elem->in_num, elem->index); + trace_virtio_blk_data_plane_process_request(s, req->elem.out_num, + req->elem.in_num, + req->elem.index); - req = g_slice_new(VirtIOBlockReq); - req->dev = VIRTIO_BLK(s->vdev); - req->elem = elem; virtio_blk_handle_request(req, &mrb); } |