From: "Cédric Le Goater" <clg@redhat.com>
To: Eric Auger <eauger@redhat.com>, qemu-devel@nongnu.org
Cc: "Peter Xu" <peterx@redhat.com>, "Fabiano Rosas" <farosas@suse.de>,
"Alex Williamson" <alex.williamson@redhat.com>,
"Avihai Horon" <avihaih@nvidia.com>,
"Philippe Mathieu-Daudé" <philmd@linaro.org>,
"Markus Armbruster" <armbru@redhat.com>
Subject: Re: [PATCH v6 4/9] vfio/migration: Add an Error** argument to vfio_migration_set_state()
Date: Thu, 16 May 2024 09:17:08 +0200 [thread overview]
Message-ID: <f4c6ab68-22d6-4cda-8c5d-d1a8f35cc624@redhat.com> (raw)
In-Reply-To: <396a3c36-45a3-4749-88b3-439af8819965@redhat.com>
On 5/15/24 09:20, Eric Auger wrote:
> Hi Cédric,
>
> On 5/14/24 17:31, Cédric Le Goater wrote:
>> Add an Error** argument to vfio_migration_set_state() and adjust
>> callers, including vfio_save_setup(). The error will be propagated up
>> to qemu_savevm_state_setup() where the save_setup() handler is
>> executed.
>>
>> Modify vfio_vmstate_change_prepare() and vfio_vmstate_change() to
>> store a reported error under the migration stream if a migration is in
>> progress.
>>
>> Signed-off-by: Cédric Le Goater <clg@redhat.com>
>> ---
>>
>> Changes in v6:
>>
>> - Commit log improvements (Avihai)
>> - vfio_migration_set_state() : Dropped the error_setg_errno() change
>> when setting device in recover state fails (Avihai)
>> - vfio_migration_state_notifier() : report local error (Avihai)
>>
>> Changes in v5:
>>
>> - Replaced error_setg() by error_setg_errno() in vfio_migration_set_state()
>> - Rebased on 20c64c8a51a4 ("migration: migration_file_set_error")
>>
>> hw/vfio/migration.c | 77 ++++++++++++++++++++++++++++-----------------
>> 1 file changed, 48 insertions(+), 29 deletions(-)
>>
>> diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
>> index bf2fd0759ba6e4fb103cc5c1a43edb180a3d0de4..bf11135167ebb162dd41415656bdacfa0e1ca550 100644
>> --- a/hw/vfio/migration.c
>> +++ b/hw/vfio/migration.c
>> @@ -82,7 +82,8 @@ static const char *mig_state_to_str(enum vfio_device_mig_state state)
>>
>> static int vfio_migration_set_state(VFIODevice *vbasedev,
>> enum vfio_device_mig_state new_state,
>> - enum vfio_device_mig_state recover_state)
>> + enum vfio_device_mig_state recover_state,
>> + Error **errp)
>> {
>> VFIOMigration *migration = vbasedev->migration;
>> uint64_t buf[DIV_ROUND_UP(sizeof(struct vfio_device_feature) +
>> @@ -102,18 +103,19 @@ static int vfio_migration_set_state(VFIODevice *vbasedev,
>> ret = -errno;
>>
>> if (recover_state == VFIO_DEVICE_STATE_ERROR) {
>> - error_report("%s: Failed setting device state to %s, err: %s. "
>> - "Recover state is ERROR. Resetting device",
>> - vbasedev->name, mig_state_to_str(new_state),
>> - strerror(errno));
>> + error_setg_errno(errp, errno,
>> + "%s: Failed setting device state to %s. "
>> + "Recover state is ERROR. Resetting device",
>> + vbasedev->name, mig_state_to_str(new_state));
> nit: this may be simplified
> with a first unconditional msg saying Failed setting device state to %s.
> Recover state is %s.
> and not duplicating the msg.
>
> In the reset label you can prepend "resetting the device ..."
I agree.
I'd rather do that in a followup patch after ther error_setg_* changes.
Adding to the TODO list.
>>
>> goto reset_device;
>> }
>>
>> - error_report(
>> - "%s: Failed setting device state to %s, err: %s. Setting device in recover state %s",
>> - vbasedev->name, mig_state_to_str(new_state),
>> - strerror(errno), mig_state_to_str(recover_state));
>> + error_setg_errno(errp, errno,
>> + "%s: Failed setting device state to %s. "
>> + "Setting device in recover state %s",
>> + vbasedev->name, mig_state_to_str(new_state),
>> + mig_state_to_str(recover_state));>
>> mig_state->device_state = recover_state;
>> if (ioctl(vbasedev->fd, VFIO_DEVICE_FEATURE, feature)) {
> in case you fail setting the device in recover state, your simply
> error_report() and do not prepend any other msg in the error handle. Is
> it what you want?
yes. Otherwise, we loose the previous error message, which I think is more
important to report (first error). The following error_report handles an
error of an error, which can go on stderr.
> In the positive, maybe worth a comment.
OK, to avoid a resend, I will amend the patch with:
mig_state->device_state = recover_state;
if (ioctl(vbasedev->fd, VFIO_DEVICE_FEATURE, feature)) {
ret = -errno;
+ /*
+ * If setting the device in recover state fails, report
+ * the error here and propagate the first error.
+ */
error_report(
"%s: Failed setting device in recover state, err: %s. Resetting device",
vbasedev->name, strerror(errno));
Thanks,
C.
>> @@ -137,7 +139,7 @@ static int vfio_migration_set_state(VFIODevice *vbasedev,
>> * This can happen if the device is asynchronously reset and
>> * terminates a data transfer.
>> */
>> - error_report("%s: data_fd out of sync", vbasedev->name);
>> + error_setg(errp, "%s: data_fd out of sync", vbasedev->name);
>> close(mig_state->data_fd);
>>
>> return -EBADF;
>> @@ -168,10 +170,11 @@ reset_device:
>> */
>> static int
>> vfio_migration_set_state_or_reset(VFIODevice *vbasedev,
>> - enum vfio_device_mig_state new_state)
>> + enum vfio_device_mig_state new_state,
>> + Error **errp)
>> {
>> return vfio_migration_set_state(vbasedev, new_state,
>> - VFIO_DEVICE_STATE_ERROR);
>> + VFIO_DEVICE_STATE_ERROR, errp);
>> }
>>
>> static int vfio_load_buffer(QEMUFile *f, VFIODevice *vbasedev,
>> @@ -399,10 +402,8 @@ static int vfio_save_setup(QEMUFile *f, void *opaque, Error **errp)
>> switch (migration->device_state) {
>> case VFIO_DEVICE_STATE_RUNNING:
>> ret = vfio_migration_set_state(vbasedev, VFIO_DEVICE_STATE_PRE_COPY,
>> - VFIO_DEVICE_STATE_RUNNING);
>> + VFIO_DEVICE_STATE_RUNNING, errp);
>> if (ret) {
>> - error_setg(errp, "%s: Failed to set new PRE_COPY state",
>> - vbasedev->name);
>> return ret;
>> }
>>
>> @@ -435,13 +436,20 @@ static void vfio_save_cleanup(void *opaque)
>> {
>> VFIODevice *vbasedev = opaque;
>> VFIOMigration *migration = vbasedev->migration;
>> + Error *local_err = NULL;
>> + int ret;
>>
>> /*
>> * Changing device state from STOP_COPY to STOP can take time. Do it here,
>> * after migration has completed, so it won't increase downtime.
>> */
>> if (migration->device_state == VFIO_DEVICE_STATE_STOP_COPY) {
>> - vfio_migration_set_state_or_reset(vbasedev, VFIO_DEVICE_STATE_STOP);
>> + ret = vfio_migration_set_state_or_reset(vbasedev,
>> + VFIO_DEVICE_STATE_STOP,
>> + &local_err);
>> + if (ret) {
>> + error_report_err(local_err);
>> + }
>> }
>>
>> g_free(migration->data_buffer);
>> @@ -549,11 +557,13 @@ static int vfio_save_complete_precopy(QEMUFile *f, void *opaque)
>> VFIODevice *vbasedev = opaque;
>> ssize_t data_size;
>> int ret;
>> + Error *local_err = NULL;
>>
>> /* We reach here with device state STOP or STOP_COPY only */
>> ret = vfio_migration_set_state(vbasedev, VFIO_DEVICE_STATE_STOP_COPY,
>> - VFIO_DEVICE_STATE_STOP);
>> + VFIO_DEVICE_STATE_STOP, &local_err);
>> if (ret) {
>> + error_report_err(local_err);
>> return ret;
>> }
>>
>> @@ -591,14 +601,9 @@ static void vfio_save_state(QEMUFile *f, void *opaque)
>> static int vfio_load_setup(QEMUFile *f, void *opaque, Error **errp)
>> {
>> VFIODevice *vbasedev = opaque;
>> - int ret;
>>
>> - ret = vfio_migration_set_state(vbasedev, VFIO_DEVICE_STATE_RESUMING,
>> - vbasedev->migration->device_state);
>> - if (ret) {
>> - error_setg(errp, "%s: Failed to set RESUMING state", vbasedev->name);
>> - }
>> - return ret;
>> + return vfio_migration_set_state(vbasedev, VFIO_DEVICE_STATE_RESUMING,
>> + vbasedev->migration->device_state, errp);
>> }
>>
>> static int vfio_load_cleanup(void *opaque)
>> @@ -714,19 +719,20 @@ static void vfio_vmstate_change_prepare(void *opaque, bool running,
>> VFIODevice *vbasedev = opaque;
>> VFIOMigration *migration = vbasedev->migration;
>> enum vfio_device_mig_state new_state;
>> + Error *local_err = NULL;
>> int ret;
>>
>> new_state = migration->device_state == VFIO_DEVICE_STATE_PRE_COPY ?
>> VFIO_DEVICE_STATE_PRE_COPY_P2P :
>> VFIO_DEVICE_STATE_RUNNING_P2P;
>>
>> - ret = vfio_migration_set_state_or_reset(vbasedev, new_state);
>> + ret = vfio_migration_set_state_or_reset(vbasedev, new_state, &local_err);
>> if (ret) {
>> /*
>> * Migration should be aborted in this case, but vm_state_notify()
>> * currently does not support reporting failures.
>> */
>> - migration_file_set_error(ret, NULL);
>> + migration_file_set_error(ret, local_err);
>> }
>>
>> trace_vfio_vmstate_change_prepare(vbasedev->name, running,
>> @@ -738,6 +744,7 @@ static void vfio_vmstate_change(void *opaque, bool running, RunState state)
>> {
>> VFIODevice *vbasedev = opaque;
>> enum vfio_device_mig_state new_state;
>> + Error *local_err = NULL;
>> int ret;
>>
>> if (running) {
>> @@ -750,13 +757,13 @@ static void vfio_vmstate_change(void *opaque, bool running, RunState state)
>> VFIO_DEVICE_STATE_STOP;
>> }
>>
>> - ret = vfio_migration_set_state_or_reset(vbasedev, new_state);
>> + ret = vfio_migration_set_state_or_reset(vbasedev, new_state, &local_err);
>> if (ret) {
>> /*
>> * Migration should be aborted in this case, but vm_state_notify()
>> * currently does not support reporting failures.
>> */
>> - migration_file_set_error(ret, NULL);
>> + migration_file_set_error(ret, local_err);
>> }
>>
>> trace_vfio_vmstate_change(vbasedev->name, running, RunState_str(state),
>> @@ -769,11 +776,23 @@ static int vfio_migration_state_notifier(NotifierWithReturn *notifier,
>> VFIOMigration *migration = container_of(notifier, VFIOMigration,
>> migration_state);
>> VFIODevice *vbasedev = migration->vbasedev;
>> + Error *local_err = NULL;
>> + int ret = 0;
>>
>> trace_vfio_migration_state_notifier(vbasedev->name, e->type);
>>
>> if (e->type == MIG_EVENT_PRECOPY_FAILED) {
>> - vfio_migration_set_state_or_reset(vbasedev, VFIO_DEVICE_STATE_RUNNING);
>> + /*
>> + * MigrationNotifyFunc may return an error code and an Error
>> + * object only for MIG_EVENT_PRECOPY_SETUP. Hence, report the
>> + * error locally and ignore the errp argument.
>> + */
>> + ret = vfio_migration_set_state_or_reset(vbasedev,
>> + VFIO_DEVICE_STATE_RUNNING,
>> + &local_err);
>> + if (ret) {
>> + error_report_err(local_err);
>> + }
>> }
>> return 0;
>> }
> Thanks
>
> Eric
>
next prev parent reply other threads:[~2024-05-16 7:17 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-14 15:31 [PATCH v6 0/9] vfio: Improve error reporting (part 2 Cédric Le Goater
2024-05-14 15:31 ` [PATCH v6 1/9] vfio: Add Error** argument to .set_dirty_page_tracking() handler Cédric Le Goater
2024-05-15 6:40 ` Eric Auger
2024-05-15 16:55 ` Cédric Le Goater
2024-05-14 15:31 ` [PATCH v6 2/9] vfio: Add Error** argument to vfio_devices_dma_logging_start() Cédric Le Goater
2024-05-15 6:53 ` Eric Auger
2024-05-15 17:09 ` Cédric Le Goater
2024-05-14 15:31 ` [PATCH v6 3/9] migration: Extend migration_file_set_error() with Error* argument Cédric Le Goater
2024-05-15 7:04 ` Eric Auger
2024-05-15 17:15 ` Cédric Le Goater
2024-05-14 15:31 ` [PATCH v6 4/9] vfio/migration: Add an Error** argument to vfio_migration_set_state() Cédric Le Goater
2024-05-15 7:20 ` Eric Auger
2024-05-16 7:17 ` Cédric Le Goater [this message]
2024-05-16 8:18 ` Avihai Horon
2024-05-16 12:07 ` Cédric Le Goater
2024-05-14 15:31 ` [PATCH v6 5/9] vfio/migration: Add Error** argument to .vfio_save_config() handler Cédric Le Goater
2024-05-15 9:20 ` Eric Auger
2024-05-16 8:22 ` Avihai Horon
2024-05-14 15:31 ` [PATCH v6 6/9] vfio: Reverse test on vfio_get_xlat_addr() Cédric Le Goater
2024-05-15 9:22 ` Eric Auger
2024-05-14 15:31 ` [PATCH v6 7/9] memory: Add Error** argument to memory_get_xlat_addr() Cédric Le Goater
2024-05-15 9:25 ` Eric Auger
2024-05-16 8:25 ` Avihai Horon
2024-05-14 15:31 ` [PATCH v6 8/9] vfio: Add Error** argument to .get_dirty_bitmap() handler Cédric Le Goater
2024-05-15 9:34 ` Eric Auger
2024-05-16 8:42 ` Avihai Horon
2024-05-16 12:22 ` Cédric Le Goater
2024-05-14 15:31 ` [PATCH v6 9/9] vfio: Also trace event failures in vfio_save_complete_precopy() Cédric Le Goater
2024-05-15 9:34 ` Eric Auger
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=f4c6ab68-22d6-4cda-8c5d-d1a8f35cc624@redhat.com \
--to=clg@redhat.com \
--cc=alex.williamson@redhat.com \
--cc=armbru@redhat.com \
--cc=avihaih@nvidia.com \
--cc=eauger@redhat.com \
--cc=farosas@suse.de \
--cc=peterx@redhat.com \
--cc=philmd@linaro.org \
--cc=qemu-devel@nongnu.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.