From patchwork Tue Nov 20 14:26:15 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amit Shah X-Patchwork-Id: 200352 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id AAC2C2C007E for ; Wed, 21 Nov 2012 01:40:52 +1100 (EST) Received: from localhost ([::1]:37930 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Taone-0007KA-Pu for incoming@patchwork.ozlabs.org; Tue, 20 Nov 2012 09:27:42 -0500 Received: from eggs.gnu.org ([208.118.235.92]:52313) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Taomr-0004yj-2G for qemu-devel@nongnu.org; Tue, 20 Nov 2012 09:26:58 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Taomg-0002RX-NJ for qemu-devel@nongnu.org; Tue, 20 Nov 2012 09:26:52 -0500 Received: from mx1.redhat.com ([209.132.183.28]:6187) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Taomg-0002RP-FH for qemu-devel@nongnu.org; Tue, 20 Nov 2012 09:26:42 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id qAKEQfCa004169 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 20 Nov 2012 09:26:41 -0500 Received: from localhost ([10.65.195.62]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id qAKEQdlh032128; Tue, 20 Nov 2012 09:26:40 -0500 From: Amit Shah To: Anthony Liguori Date: Tue, 20 Nov 2012 19:56:15 +0530 Message-Id: In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: Amit Shah , Paolo Bonzini , qemu list Subject: [Qemu-devel] [PATCH 1/4] virtio-rng: use virtqueue_get_avail_bytes, fix migration X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Popping an elem from the vq just to find out its length causes problems with save/load later on. Use the new virtqueue_get_avail_bytes() function instead, saves us the complexity in the migration code, as well as makes the migration endian-safe. Signed-off-by: Amit Shah Reviewed-by: Anthony Liguori --- hw/virtio-rng.c | 76 +++++++++------------------------------------------------ 1 file changed, 12 insertions(+), 64 deletions(-) diff --git a/hw/virtio-rng.c b/hw/virtio-rng.c index 3ca96c8..6c49bb2 100644 --- a/hw/virtio-rng.c +++ b/hw/virtio-rng.c @@ -22,14 +22,10 @@ typedef struct VirtIORNG { /* Only one vq - guest puts buffer(s) on it when it needs entropy */ VirtQueue *vq; - VirtQueueElement elem; /* Config data for the device -- currently only chardev */ VirtIORNGConf *conf; - /* Whether we've popped a vq element into 'elem' above */ - bool popped; - RngBackend *rng; /* We purposefully don't migrate this state. The quota will reset on the @@ -48,17 +44,12 @@ static bool is_guest_ready(VirtIORNG *vrng) return false; } -static size_t pop_an_elem(VirtIORNG *vrng) +static size_t get_request_size(VirtQueue *vq) { - size_t size; + unsigned int in, out; - if (!vrng->popped && !virtqueue_pop(vrng->vq, &vrng->elem)) { - return 0; - } - vrng->popped = true; - - size = iov_size(vrng->elem.in_sg, vrng->elem.in_num); - return size; + virtqueue_get_avail_bytes(vq, &in, &out); + return in; } static void virtio_rng_process(VirtIORNG *vrng); @@ -67,6 +58,7 @@ static void virtio_rng_process(VirtIORNG *vrng); static void chr_read(void *opaque, const void *buf, size_t size) { VirtIORNG *vrng = opaque; + VirtQueueElement elem; size_t len; int offset; @@ -78,15 +70,14 @@ static void chr_read(void *opaque, const void *buf, size_t size) offset = 0; while (offset < size) { - if (!pop_an_elem(vrng)) { + if (!virtqueue_pop(vrng->vq, &elem)) { break; } - len = iov_from_buf(vrng->elem.in_sg, vrng->elem.in_num, + len = iov_from_buf(elem.in_sg, elem.in_num, 0, buf + offset, size - offset); offset += len; - virtqueue_push(vrng->vq, &vrng->elem, len); - vrng->popped = false; + virtqueue_push(vrng->vq, &elem, len); } virtio_notify(&vrng->vdev, vrng->vq); @@ -100,21 +91,19 @@ static void chr_read(void *opaque, const void *buf, size_t size) static void virtio_rng_process(VirtIORNG *vrng) { - ssize_t size; + size_t size; if (!is_guest_ready(vrng)) { return; } - size = pop_an_elem(vrng); + size = get_request_size(vrng->vq); size = MIN(vrng->quota_remaining, size); - - if (size > 0) { + if (size) { rng_backend_request_entropy(vrng->rng, size, chr_read, vrng); } } - static void handle_input(VirtIODevice *vdev, VirtQueue *vq) { VirtIORNG *vrng = DO_UPCAST(VirtIORNG, vdev, vdev); @@ -131,23 +120,6 @@ static void virtio_rng_save(QEMUFile *f, void *opaque) VirtIORNG *vrng = opaque; virtio_save(&vrng->vdev, f); - - qemu_put_byte(f, vrng->popped); - if (vrng->popped) { - int i; - - qemu_put_be32(f, vrng->elem.index); - - qemu_put_be32(f, vrng->elem.in_num); - for (i = 0; i < vrng->elem.in_num; i++) { - qemu_put_be64(f, vrng->elem.in_addr[i]); - } - - qemu_put_be32(f, vrng->elem.out_num); - for (i = 0; i < vrng->elem.out_num; i++) { - qemu_put_be64(f, vrng->elem.out_addr[i]); - } - } } static int virtio_rng_load(QEMUFile *f, void *opaque, int version_id) @@ -159,30 +131,6 @@ static int virtio_rng_load(QEMUFile *f, void *opaque, int version_id) } virtio_load(&vrng->vdev, f); - vrng->popped = qemu_get_byte(f); - if (vrng->popped) { - int i; - - vrng->elem.index = qemu_get_be32(f); - - vrng->elem.in_num = qemu_get_be32(f); - g_assert(vrng->elem.in_num < VIRTQUEUE_MAX_SIZE); - for (i = 0; i < vrng->elem.in_num; i++) { - vrng->elem.in_addr[i] = qemu_get_be64(f); - } - - vrng->elem.out_num = qemu_get_be32(f); - g_assert(vrng->elem.out_num < VIRTQUEUE_MAX_SIZE); - for (i = 0; i < vrng->elem.out_num; i++) { - vrng->elem.out_addr[i] = qemu_get_be64(f); - } - - virtqueue_map_sg(vrng->elem.in_sg, vrng->elem.in_addr, - vrng->elem.in_num, 1); - virtqueue_map_sg(vrng->elem.out_sg, vrng->elem.out_addr, - vrng->elem.out_num, 0); - } - /* We may have an element ready but couldn't process it due to a quota limit. Make sure to try again after live migration when the quota may have been reset. @@ -232,7 +180,7 @@ VirtIODevice *virtio_rng_init(DeviceState *dev, VirtIORNGConf *conf) vrng->qdev = dev; vrng->conf = conf; - vrng->popped = false; + vrng->quota_remaining = vrng->conf->max_bytes; g_assert_cmpint(vrng->conf->max_bytes, <=, INT64_MAX);