From: "Michael S. Tsirkin" <mst@redhat.com>
To: Alex Williamson <alex.williamson@redhat.com>
Cc: qemu-devel@nongnu.org, kraxel@redhat.com
Subject: Re: [PATCH] vfio/pci: Generate more relevant log messages for reset failures
Date: Wed, 5 Jan 2022 16:05:45 -0500 [thread overview]
Message-ID: <20220105160400-mutt-send-email-mst@kernel.org> (raw)
In-Reply-To: <164141259622.4193261.8252690438434562107.stgit@omen>
On Wed, Jan 05, 2022 at 12:56:42PM -0700, Alex Williamson wrote:
> The VFIO_DEVICE_RESET ioctl might be backed by several different reset
> methods, including a device specific reset (ie. custom reset code in
> kernel), an ACPI reset (ie. custom reset code in firmware), FLR, PM,
> and bus resets. This listing is also the default priority order used
> by the kernel for trying reset methods. Traditionally we've had some
> FUD regarding the PM reset as the extent of a "Soft Reset" is not well
> defined in the PCI specification. Therefore we try to guess what type
> of reset a device might use for the VFIO_DEVICE_RESET and insert a bus
> reset via the vfio hot reset interface if we think it could be a PM
> reset.
>
> This results in a couple odd tests for PM reset in our hot reset code,
> as we assume if we don't detect has_pm_reset support that we can't
> reset the device otherwise. Starting with kernel v5.15, the kernel
> exposes a sysfs attribute for devices that can tell us the priority
> order for device resets, so long term (not implemented here) we no
> longer need to play this guessing game, and if permissions allow we
> could manipulate the order ourselves so that we don't need to inject
> our own hot reset.
>
> In the shorter term, implemented here, let's not assume we're out of
> reset methods if we can't perform a hot reset and the device doesn't
> support PM reset. We can use reset_works as the authority, which
> allows us to generate more comprehensible error messages for the case
> when it actually doesn't work.
>
> The impetus for this change is a result of commit d5daff7d3126 ("pcie:
> implement slot power control for pcie root ports"), where powering off
> a slot now results in a device reset. If the slot is powered off as a
> result of qdev_unplug() via the device request event, that device
> request is potentially the result of an unbind operation in the host.
> That unbind operation holds the kernel device lock, which causes the
> VFIO_DEVICE_RESET ioctl to fail (or in the case of some kernels, has
> cleared the flag indicating support of a device reset function). We
> can then end up with an SR-IOV VF device trying to trigger a hot reset,
> which finds that it needs ownership of the PF group to perform such a
> reset, resulting in confusing log messages.
>
> Ultimately the above commit still introduces a log message that we
> didn't have prior on such an unplug, but it's not unjustified to
> perform such a reset, though it might be considered unnecessary.
> Arguably failure to reset the device should always generate some sort
> of meaningful log message.
>
> Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Looks reasonable. Just an extra idea: do we want to maybe validate the
return code from the ioctl? I assume it's something like EBUSY right?
In any case better than what we have now:
Acked-by: Michael S. Tsirkin <mst@redhat.com>
> ---
> hw/vfio/pci.c | 44 ++++++++++++++++++++++++++++++++------------
> 1 file changed, 32 insertions(+), 12 deletions(-)
>
> diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
> index 7b45353ce27f..ea697951556e 100644
> --- a/hw/vfio/pci.c
> +++ b/hw/vfio/pci.c
> @@ -2224,7 +2224,7 @@ static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single)
> ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_PCI_HOT_RESET_INFO, info);
> if (ret && errno != ENOSPC) {
> ret = -errno;
> - if (!vdev->has_pm_reset) {
> + if (!vdev->vbasedev.reset_works) {
> error_report("vfio: Cannot reset device %s, "
> "no available reset mechanism.", vdev->vbasedev.name);
> }
> @@ -2270,7 +2270,7 @@ static int vfio_pci_hot_reset(VFIOPCIDevice *vdev, bool single)
> }
>
> if (!group) {
> - if (!vdev->has_pm_reset) {
> + if (!vdev->vbasedev.reset_works) {
> error_report("vfio: Cannot reset device %s, "
> "depends on group %d which is not owned.",
> vdev->vbasedev.name, devices[i].group_id);
> @@ -3162,6 +3162,8 @@ static void vfio_exitfn(PCIDevice *pdev)
> static void vfio_pci_reset(DeviceState *dev)
> {
> VFIOPCIDevice *vdev = VFIO_PCI(dev);
> + Error *err = NULL;
> + int ret;
>
> trace_vfio_pci_reset(vdev->vbasedev.name);
>
> @@ -3175,26 +3177,44 @@ static void vfio_pci_reset(DeviceState *dev)
> goto post_reset;
> }
>
> - if (vdev->vbasedev.reset_works &&
> - (vdev->has_flr || !vdev->has_pm_reset) &&
> - !ioctl(vdev->vbasedev.fd, VFIO_DEVICE_RESET)) {
> - trace_vfio_pci_reset_flr(vdev->vbasedev.name);
> - goto post_reset;
> + if (vdev->vbasedev.reset_works && (vdev->has_flr || !vdev->has_pm_reset)) {
> + if (!ioctl(vdev->vbasedev.fd, VFIO_DEVICE_RESET)) {
> + trace_vfio_pci_reset_flr(vdev->vbasedev.name);
> + goto post_reset;
> + }
> +
> + error_setg_errno(&err, errno, "Unable to reset device");
> }
>
> /* See if we can do our own bus reset */
> - if (!vfio_pci_hot_reset_one(vdev)) {
> + ret = vfio_pci_hot_reset_one(vdev);
> + if (!ret) {
> goto post_reset;
> }
>
> + if (!err) {
> + error_setg_errno(&err, -ret, "Unable to perform bus reset");
> + }
> +
> /* If nothing else works and the device supports PM reset, use it */
> - if (vdev->vbasedev.reset_works && vdev->has_pm_reset &&
> - !ioctl(vdev->vbasedev.fd, VFIO_DEVICE_RESET)) {
> - trace_vfio_pci_reset_pm(vdev->vbasedev.name);
> - goto post_reset;
> + if (vdev->vbasedev.reset_works && vdev->has_pm_reset) {
> + /* Prefer to report the ioctl failure mode */
> + error_free(err);
> + err = NULL;
> +
> + if (!ioctl(vdev->vbasedev.fd, VFIO_DEVICE_RESET)) {
> + trace_vfio_pci_reset_pm(vdev->vbasedev.name);
> + goto post_reset;
> + }
> +
> + error_setg_errno(&err, errno, "Unable to reset device");
> }
>
> + warn_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
> + err = NULL;
> +
> post_reset:
> + error_free(err);
> vfio_pci_post_reset(vdev);
> }
>
>
next prev parent reply other threads:[~2022-01-05 21:07 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-05 19:56 [PATCH] vfio/pci: Generate more relevant log messages for reset failures Alex Williamson
2022-01-05 21:05 ` Michael S. Tsirkin [this message]
2022-01-05 22:12 ` Alex Williamson
2022-01-05 22:38 ` Michael S. Tsirkin
-- strict thread matches above, loose matches on Subject: below --
2022-01-05 19:56 Alex Williamson
2022-01-05 20:05 ` Alex Williamson
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=20220105160400-mutt-send-email-mst@kernel.org \
--to=mst@redhat.com \
--cc=alex.williamson@redhat.com \
--cc=kraxel@redhat.com \
--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 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).