From: "Michael S. Tsirkin" <mst@redhat.com>
To: qemu-devel@nongnu.org
Cc: Roman Kagan <rvkagan@yandex-team.ru>,
Peter Maydell <peter.maydell@linaro.org>
Subject: [PULL 21/52] vhost: stick to -errno error return convention
Date: Thu, 6 Jan 2022 08:17:11 -0500 [thread overview]
Message-ID: <20220106131534.423671-22-mst@redhat.com> (raw)
In-Reply-To: <20220106131534.423671-1-mst@redhat.com>
From: Roman Kagan <rvkagan@yandex-team.ru>
The generic vhost code expects that many of the VhostOps methods in the
respective backends set errno on errors. However, none of the existing
backends actually bothers to do so. In a number of those methods errno
from the failed call is clobbered by successful later calls to some
library functions; on a few code paths the generic vhost code then
negates and returns that errno, thus making failures look as successes
to the caller.
As a result, in certain scenarios (e.g. live migration) the device
doesn't notice the first failure and goes on through its state
transitions as if everything is ok, instead of taking recovery actions
(break and reestablish the vhost-user connection, cancel migration, etc)
before it's too late.
To fix this, consolidate on the convention to return negated errno on
failures throughout generic vhost, and use it for error propagation.
Signed-off-by: Roman Kagan <rvkagan@yandex-team.ru>
Message-Id: <20211111153354.18807-10-rvkagan@yandex-team.ru>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
hw/virtio/vhost.c | 100 +++++++++++++++++++++-------------------------
1 file changed, 46 insertions(+), 54 deletions(-)
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 98a4b0a0df..cbf3b792da 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -33,11 +33,13 @@
#define _VHOST_DEBUG 1
#ifdef _VHOST_DEBUG
-#define VHOST_OPS_DEBUG(fmt, ...) \
- do { error_report(fmt ": %s (%d)", ## __VA_ARGS__, \
- strerror(errno), errno); } while (0)
+#define VHOST_OPS_DEBUG(retval, fmt, ...) \
+ do { \
+ error_report(fmt ": %s (%d)", ## __VA_ARGS__, \
+ strerror(-retval), -retval); \
+ } while (0)
#else
-#define VHOST_OPS_DEBUG(fmt, ...) \
+#define VHOST_OPS_DEBUG(retval, fmt, ...) \
do { } while (0)
#endif
@@ -297,7 +299,7 @@ static inline void vhost_dev_log_resize(struct vhost_dev *dev, uint64_t size)
releasing the current log, to ensure no logging is lost */
r = dev->vhost_ops->vhost_set_log_base(dev, log_base, log);
if (r < 0) {
- VHOST_OPS_DEBUG("vhost_set_log_base failed");
+ VHOST_OPS_DEBUG(r, "vhost_set_log_base failed");
}
vhost_log_put(dev, true);
@@ -550,7 +552,7 @@ static void vhost_commit(MemoryListener *listener)
if (!dev->log_enabled) {
r = dev->vhost_ops->vhost_set_mem_table(dev, dev->mem);
if (r < 0) {
- VHOST_OPS_DEBUG("vhost_set_mem_table failed");
+ VHOST_OPS_DEBUG(r, "vhost_set_mem_table failed");
}
goto out;
}
@@ -564,7 +566,7 @@ static void vhost_commit(MemoryListener *listener)
}
r = dev->vhost_ops->vhost_set_mem_table(dev, dev->mem);
if (r < 0) {
- VHOST_OPS_DEBUG("vhost_set_mem_table failed");
+ VHOST_OPS_DEBUG(r, "vhost_set_mem_table failed");
}
/* To log less, can only decrease log size after table update. */
if (dev->log_size > log_size + VHOST_LOG_BUFFER) {
@@ -803,8 +805,8 @@ static int vhost_virtqueue_set_addr(struct vhost_dev *dev,
if (dev->vhost_ops->vhost_vq_get_addr) {
r = dev->vhost_ops->vhost_vq_get_addr(dev, &addr, vq);
if (r < 0) {
- VHOST_OPS_DEBUG("vhost_vq_get_addr failed");
- return -errno;
+ VHOST_OPS_DEBUG(r, "vhost_vq_get_addr failed");
+ return r;
}
} else {
addr.desc_user_addr = (uint64_t)(unsigned long)vq->desc;
@@ -816,10 +818,9 @@ static int vhost_virtqueue_set_addr(struct vhost_dev *dev,
addr.flags = enable_log ? (1 << VHOST_VRING_F_LOG) : 0;
r = dev->vhost_ops->vhost_set_vring_addr(dev, &addr);
if (r < 0) {
- VHOST_OPS_DEBUG("vhost_set_vring_addr failed");
- return -errno;
+ VHOST_OPS_DEBUG(r, "vhost_set_vring_addr failed");
}
- return 0;
+ return r;
}
static int vhost_dev_set_features(struct vhost_dev *dev,
@@ -840,19 +841,19 @@ static int vhost_dev_set_features(struct vhost_dev *dev,
}
r = dev->vhost_ops->vhost_set_features(dev, features);
if (r < 0) {
- VHOST_OPS_DEBUG("vhost_set_features failed");
+ VHOST_OPS_DEBUG(r, "vhost_set_features failed");
goto out;
}
if (dev->vhost_ops->vhost_set_backend_cap) {
r = dev->vhost_ops->vhost_set_backend_cap(dev);
if (r < 0) {
- VHOST_OPS_DEBUG("vhost_set_backend_cap failed");
+ VHOST_OPS_DEBUG(r, "vhost_set_backend_cap failed");
goto out;
}
}
out:
- return r < 0 ? -errno : 0;
+ return r;
}
static int vhost_dev_set_log(struct vhost_dev *dev, bool enable_log)
@@ -999,22 +1000,17 @@ static int vhost_virtqueue_set_vring_endian_legacy(struct vhost_dev *dev,
bool is_big_endian,
int vhost_vq_index)
{
+ int r;
struct vhost_vring_state s = {
.index = vhost_vq_index,
.num = is_big_endian
};
- if (!dev->vhost_ops->vhost_set_vring_endian(dev, &s)) {
- return 0;
+ r = dev->vhost_ops->vhost_set_vring_endian(dev, &s);
+ if (r < 0) {
+ VHOST_OPS_DEBUG(r, "vhost_set_vring_endian failed");
}
-
- VHOST_OPS_DEBUG("vhost_set_vring_endian failed");
- if (errno == ENOTTY) {
- error_report("vhost does not support cross-endian");
- return -ENOSYS;
- }
-
- return -errno;
+ return r;
}
static int vhost_memory_region_lookup(struct vhost_dev *hdev,
@@ -1106,15 +1102,15 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
vq->num = state.num = virtio_queue_get_num(vdev, idx);
r = dev->vhost_ops->vhost_set_vring_num(dev, &state);
if (r) {
- VHOST_OPS_DEBUG("vhost_set_vring_num failed");
- return -errno;
+ VHOST_OPS_DEBUG(r, "vhost_set_vring_num failed");
+ return r;
}
state.num = virtio_queue_get_last_avail_idx(vdev, idx);
r = dev->vhost_ops->vhost_set_vring_base(dev, &state);
if (r) {
- VHOST_OPS_DEBUG("vhost_set_vring_base failed");
- return -errno;
+ VHOST_OPS_DEBUG(r, "vhost_set_vring_base failed");
+ return r;
}
if (vhost_needs_vring_endian(vdev)) {
@@ -1122,7 +1118,7 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
virtio_is_big_endian(vdev),
vhost_vq_index);
if (r) {
- return -errno;
+ return r;
}
}
@@ -1150,15 +1146,13 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
r = vhost_virtqueue_set_addr(dev, vq, vhost_vq_index, dev->log_enabled);
if (r < 0) {
- r = -errno;
goto fail_alloc;
}
file.fd = event_notifier_get_fd(virtio_queue_get_host_notifier(vvq));
r = dev->vhost_ops->vhost_set_vring_kick(dev, &file);
if (r) {
- VHOST_OPS_DEBUG("vhost_set_vring_kick failed");
- r = -errno;
+ VHOST_OPS_DEBUG(r, "vhost_set_vring_kick failed");
goto fail_kick;
}
@@ -1218,7 +1212,7 @@ static void vhost_virtqueue_stop(struct vhost_dev *dev,
r = dev->vhost_ops->vhost_get_vring_base(dev, &state);
if (r < 0) {
- VHOST_OPS_DEBUG("vhost VQ %u ring restore failed: %d", idx, r);
+ VHOST_OPS_DEBUG(r, "vhost VQ %u ring restore failed: %d", idx, r);
/* Connection to the backend is broken, so let's sync internal
* last avail idx to the device used idx.
*/
@@ -1274,7 +1268,7 @@ static int vhost_virtqueue_set_busyloop_timeout(struct vhost_dev *dev,
r = dev->vhost_ops->vhost_set_vring_busyloop_timeout(dev, &state);
if (r) {
- VHOST_OPS_DEBUG("vhost_set_vring_busyloop_timeout failed");
+ VHOST_OPS_DEBUG(r, "vhost_set_vring_busyloop_timeout failed");
return r;
}
@@ -1296,8 +1290,7 @@ static int vhost_virtqueue_init(struct vhost_dev *dev,
file.fd = event_notifier_get_fd(&vq->masked_notifier);
r = dev->vhost_ops->vhost_set_vring_call(dev, &file);
if (r) {
- VHOST_OPS_DEBUG("vhost_set_vring_call failed");
- r = -errno;
+ VHOST_OPS_DEBUG(r, "vhost_set_vring_call failed");
goto fail_call;
}
@@ -1557,7 +1550,7 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
file.index = hdev->vhost_ops->vhost_get_vq_index(hdev, n);
r = hdev->vhost_ops->vhost_set_vring_call(hdev, &file);
if (r < 0) {
- VHOST_OPS_DEBUG("vhost_set_vring_call failed");
+ VHOST_OPS_DEBUG(r, "vhost_set_vring_call failed");
}
}
@@ -1595,7 +1588,7 @@ void vhost_config_mask(struct vhost_dev *hdev, VirtIODevice *vdev, bool mask)
}
r = hdev->vhost_ops->vhost_set_config_call(hdev, fd);
if (r < 0) {
- VHOST_OPS_DEBUG("vhost_set_config_call failed");
+ VHOST_OPS_DEBUG(r, "vhost_set_config_call failed");
}
}
@@ -1660,7 +1653,7 @@ int vhost_dev_get_config(struct vhost_dev *hdev, uint8_t *config,
}
error_setg(errp, "vhost_get_config not implemented");
- return -ENOTSUP;
+ return -ENOSYS;
}
int vhost_dev_set_config(struct vhost_dev *hdev, const uint8_t *data,
@@ -1673,7 +1666,7 @@ int vhost_dev_set_config(struct vhost_dev *hdev, const uint8_t *data,
size, flags);
}
- return -1;
+ return -ENOSYS;
}
void vhost_dev_set_config_notifier(struct vhost_dev *hdev,
@@ -1702,7 +1695,7 @@ static int vhost_dev_resize_inflight(struct vhost_inflight *inflight,
if (err) {
error_report_err(err);
- return -1;
+ return -ENOMEM;
}
vhost_dev_free_inflight(inflight);
@@ -1735,8 +1728,9 @@ int vhost_dev_load_inflight(struct vhost_inflight *inflight, QEMUFile *f)
}
if (inflight->size != size) {
- if (vhost_dev_resize_inflight(inflight, size)) {
- return -1;
+ int ret = vhost_dev_resize_inflight(inflight, size);
+ if (ret < 0) {
+ return ret;
}
}
inflight->queue_size = qemu_get_be16(f);
@@ -1759,7 +1753,7 @@ int vhost_dev_prepare_inflight(struct vhost_dev *hdev, VirtIODevice *vdev)
r = vhost_dev_set_features(hdev, hdev->log_enabled);
if (r < 0) {
- VHOST_OPS_DEBUG("vhost_dev_prepare_inflight failed");
+ VHOST_OPS_DEBUG(r, "vhost_dev_prepare_inflight failed");
return r;
}
@@ -1774,8 +1768,8 @@ int vhost_dev_set_inflight(struct vhost_dev *dev,
if (dev->vhost_ops->vhost_set_inflight_fd && inflight->addr) {
r = dev->vhost_ops->vhost_set_inflight_fd(dev, inflight);
if (r) {
- VHOST_OPS_DEBUG("vhost_set_inflight_fd failed");
- return -errno;
+ VHOST_OPS_DEBUG(r, "vhost_set_inflight_fd failed");
+ return r;
}
}
@@ -1790,8 +1784,8 @@ int vhost_dev_get_inflight(struct vhost_dev *dev, uint16_t queue_size,
if (dev->vhost_ops->vhost_get_inflight_fd) {
r = dev->vhost_ops->vhost_get_inflight_fd(dev, queue_size, inflight);
if (r) {
- VHOST_OPS_DEBUG("vhost_get_inflight_fd failed");
- return -errno;
+ VHOST_OPS_DEBUG(r, "vhost_get_inflight_fd failed");
+ return r;
}
}
@@ -1820,8 +1814,7 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
r = hdev->vhost_ops->vhost_set_mem_table(hdev, hdev->mem);
if (r < 0) {
- VHOST_OPS_DEBUG("vhost_set_mem_table failed");
- r = -errno;
+ VHOST_OPS_DEBUG(r, "vhost_set_mem_table failed");
goto fail_mem;
}
for (i = 0; i < hdev->nvqs; ++i) {
@@ -1855,8 +1848,7 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
hdev->log_size ? log_base : 0,
hdev->log);
if (r < 0) {
- VHOST_OPS_DEBUG("vhost_set_log_base failed");
- r = -errno;
+ VHOST_OPS_DEBUG(r, "vhost_set_log_base failed");
goto fail_log;
}
}
@@ -1936,5 +1928,5 @@ int vhost_net_set_backend(struct vhost_dev *hdev,
return hdev->vhost_ops->vhost_net_set_backend(hdev, file);
}
- return -1;
+ return -ENOSYS;
}
--
MST
next prev parent reply other threads:[~2022-01-06 13:45 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-06 13:16 [PULL 00/52] virtio,pci,pc: features,fixes,cleanups Michael S. Tsirkin
2022-01-06 13:16 ` [PULL 01/52] virtio-mem: Don't skip alignment checks when warning about block size Michael S. Tsirkin
2022-01-06 13:16 ` [PULL 02/52] acpi: validate hotplug selector on access Michael S. Tsirkin
2022-01-06 13:16 ` [PULL 03/52] virtio: introduce macro IRTIO_CONFIG_IRQ_IDX Michael S. Tsirkin
2022-01-06 13:16 ` [PULL 05/52] virtio-pci: decouple the single vector from the interrupt process Michael S. Tsirkin
2022-01-06 13:16 ` [PULL 06/52] vhost: introduce new VhostOps vhost_set_config_call Michael S. Tsirkin
2022-01-06 13:22 ` Michael S. Tsirkin
2022-01-06 13:16 ` [PULL 07/52] vhost-vdpa: add support for config interrupt Michael S. Tsirkin
2022-01-06 13:16 ` [PULL 08/52] virtio: add support for configure interrupt Michael S. Tsirkin
2022-01-06 13:16 ` [PULL 09/52] vhost: " Michael S. Tsirkin
2022-01-06 13:16 ` [PULL 10/52] virtio-net: " Michael S. Tsirkin
2022-01-06 13:16 ` [PULL 11/52] virtio-mmio: " Michael S. Tsirkin
2022-01-06 13:16 ` [PULL 12/52] virtio-pci: " Michael S. Tsirkin
2022-01-06 13:16 ` [PULL 13/52] trace-events,pci: unify trace events format Michael S. Tsirkin
2022-01-06 13:16 ` [PULL 14/52] vhost-user-blk: reconnect on any error during realize Michael S. Tsirkin
2022-01-06 13:16 ` [PULL 15/52] chardev/char-socket: tcp_chr_recv: don't clobber errno Michael S. Tsirkin
2022-01-06 13:16 ` [PULL 16/52] chardev/char-socket: tcp_chr_sync_read: " Michael S. Tsirkin
2022-01-06 13:17 ` [PULL 17/52] vhost-backend: avoid overflow on memslots_limit Michael S. Tsirkin
2022-01-06 13:17 ` [PULL 18/52] vhost-backend: stick to -errno error return convention Michael S. Tsirkin
2022-01-06 13:17 ` [PULL 19/52] vhost-vdpa: " Michael S. Tsirkin
2022-01-06 13:17 ` [PULL 20/52] vhost-user: " Michael S. Tsirkin
2022-01-06 13:17 ` Michael S. Tsirkin [this message]
2022-01-06 13:17 ` [PULL 22/52] vhost-user-blk: propagate error return from generic vhost Michael S. Tsirkin
2022-01-06 13:17 ` [PULL 23/52] pci: Export the pci_intx() function Michael S. Tsirkin
2022-01-06 13:17 ` [PULL 24/52] pcie_aer: Don't trigger a LSI if none are defined Michael S. Tsirkin
2022-01-06 13:17 ` [PULL 25/52] smbios: Rename SMBIOS_ENTRY_POINT_* enums Michael S. Tsirkin
2022-01-06 13:17 ` [PULL 26/52] hw/smbios: Use qapi for SmbiosEntryPointType Michael S. Tsirkin
2022-01-06 13:17 ` [PULL 27/52] hw/i386: expose a "smbios-entry-point-type" PC machine property Michael S. Tsirkin
2022-01-06 13:17 ` [PULL 28/52] hw/vhost-user-blk: turn on VIRTIO_BLK_F_SIZE_MAX feature for virtio blk device Michael S. Tsirkin
2022-01-06 13:17 ` [PULL 29/52] util/oslib-posix: Let touch_all_pages() return an error Michael S. Tsirkin
2022-01-06 13:17 ` [PULL 30/52] util/oslib-posix: Support MADV_POPULATE_WRITE for os_mem_prealloc() Michael S. Tsirkin
2022-01-06 13:17 ` [PULL 31/52] util/oslib-posix: Introduce and use MemsetContext for touch_all_pages() Michael S. Tsirkin
2022-01-06 13:17 ` [PULL 32/52] util/oslib-posix: Don't create too many threads with small memory or little pages Michael S. Tsirkin
2022-01-06 13:17 ` [PULL 33/52] util/oslib-posix: Avoid creating a single thread with MADV_POPULATE_WRITE Michael S. Tsirkin
2022-01-06 13:17 ` [PULL 34/52] util/oslib-posix: Support concurrent os_mem_prealloc() invocation Michael S. Tsirkin
2022-01-06 13:17 ` [PULL 35/52] util/oslib-posix: Forward SIGBUS to MCE handler under Linux Michael S. Tsirkin
2022-01-06 13:17 ` [PULL 36/52] virtio-mem: Support "prealloc=on" option Michael S. Tsirkin
2022-01-06 13:18 ` [PULL 37/52] virtio: signal after wrapping packed used_idx Michael S. Tsirkin
2022-01-06 13:18 ` [PULL 38/52] MAINTAINERS: Add a separate entry for acpi/VIOT tables Michael S. Tsirkin
2022-01-06 13:18 ` [PULL 39/52] linux-headers: sync VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE Michael S. Tsirkin
2022-01-06 13:18 ` [PULL 40/52] virtio-mem: Support VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE Michael S. Tsirkin
2022-01-06 13:18 ` [PULL 41/52] virtio-mem: Set "unplugged-inaccessible=auto" for the 7.0 machine on x86 Michael S. Tsirkin
2022-01-06 13:18 ` [PULL 42/52] intel-iommu: correctly check passthrough during translation Michael S. Tsirkin
2022-01-06 13:18 ` [PULL 43/52] acpi: fix QEMU crash when started with SLIC table Michael S. Tsirkin
2022-01-06 13:18 ` [PULL 46/52] tests: acpi: SLIC: update expected blobs Michael S. Tsirkin
2022-01-06 13:18 ` [PULL 47/52] acpihp: simplify acpi_pcihp_disable_root_bus Michael S. Tsirkin
2022-01-06 13:18 ` [PULL 48/52] hw/i386/pc: Add missing property descriptions Michael S. Tsirkin
2022-01-06 13:18 ` [PULL 49/52] docs: reSTify virtio-balloon-stats documentation and move to docs/interop Michael S. Tsirkin
2022-01-06 13:18 ` [PULL 50/52] hw/scsi/vhost-scsi: don't leak vqs on error Michael S. Tsirkin
2022-01-06 13:18 ` [PULL 51/52] hw/scsi/vhost-scsi: don't double close vhostfd " Michael S. Tsirkin
2022-01-06 13:18 ` [PULL 52/52] virtio/vhost-vsock: don't double close vhostfd, remove redundant cleanup Michael S. Tsirkin
2022-01-06 13:21 ` [PULL 45/52] tests: acpi: add SLIC table test Michael S. Tsirkin
2022-01-06 13:18 ` Michael S. Tsirkin
2022-01-06 13:21 ` [PULL 44/52] tests: acpi: whitelist expected blobs before changing them Michael S. Tsirkin
2022-01-06 13:22 ` [PULL 04/52] virtio-pci: decouple notifier from interrupt process Michael S. Tsirkin
2022-01-06 23:06 ` [PULL 00/52] virtio,pci,pc: features,fixes,cleanups Richard Henderson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220106131534.423671-22-mst@redhat.com \
--to=mst@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=rvkagan@yandex-team.ru \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).