All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefan Hajnoczi <stefanha@redhat.com>
To: mst@redhat.com
Cc: Yi Sun <yi.sun@unisoc.com>,
	axboe@kernel.dk, yi sun <sunyibuaa@gmail.com>,
	jasowang@redhat.com, xuanzhuo@linux.alibaba.com,
	pbonzini@redhat.com, virtualization@lists.linux.dev,
	linux-block@vger.kernel.org, linux-kernel@vger.kernel.org,
	zhiguo.niu@unisoc.com, hongyu.jin@unisoc.com
Subject: Re: [PATCH 2/2] virtio-blk: Ensure no requests in virtqueues before deleting vqs.
Date: Tue, 23 Jan 2024 10:09:24 -0500	[thread overview]
Message-ID: <20240123150924.GD484337@fedora> (raw)
In-Reply-To: <CALpufv0h-sQ4Qfp-Sxd7wME4onMNAMop_gi-np6Dk2R96sba0Q@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 4039 bytes --]

Hi Michael,
This could potentially affect other VIRTIO drivers too. Please see
below.

On Tue, Jan 23, 2024 at 11:27:40AM +0800, yi sun wrote:
> On Mon, Jan 22, 2024 at 11:43 PM Stefan Hajnoczi <stefanha@redhat.com> wrote:
> >
> > On Mon, Jan 22, 2024 at 07:07:22PM +0800, Yi Sun wrote:
> > > Ensure no remaining requests in virtqueues before resetting vdev and
> > > deleting virtqueues. Otherwise these requests will never be completed.
> > > It may cause the system to become unresponsive. So it is better to place
> > > blk_mq_quiesce_queue() in front of virtio_reset_device().
> >
> > QEMU's virtio-blk device implementation completes all requests during
> > device reset. Most device implementations have to do the same to avoid
> > leaving dangling requests in flight across device reset.
> >
> > Which device implementation are you using and why is it safe for the
> > device is simply drop requests across device reset?
> >
> > Stefan
> 
> Virtio-blk device implementation completes all requests during device reset, but
> this can only ensure that the device has finished using virtqueue. We should
> also consider the driver's use of virtqueue.
> 
> I caught such an example. Before del_vqs, the request had been processed by
> the device, but it had not been processed by the driver. Although I am
> using kernel5.4,
> I think this problem may also occur with the latest version of kernel.
> 
> The debug code I added is as follows:
> virtblk_freeze()
> {
>         vdev reset();
>         quiesce queue();
>         if (virtqueue->num_free != 1024) //1024 is the init value.
>                 BUG_ON(1);
>         vdev del_vqs();
> }
> 
> BUG_ON triggered the dump, the analysis is as follows:
> 
> There is one request left in request_queue.
> crash_arm64> struct request ffffff81f0560000 | grep -e state -e __data_len
>   __data_len = 20480,
>   state = MQ_RQ_IN_FLIGHT,
> 
> crash_arm64> vring_virtqueue.packed,last_used_idx,broken,vq 0xffffff8086f92900 |
> grep -e num -e used_wrap_counter -e last_used_idx -e broken -e
> num_free -e desc_state -e "desc ="
>         num = 1024,
>         desc = 0xffffff8085ff8000,
>       used_wrap_counter = false,
>       desc_state = 0xffffff8085610000,
>   last_used_idx = 487,
>   broken = false,
>     num_free = 1017,
> 
> Find desc based on last_used_idx. Through flags, we can know that the request
> has been processed by the device, but it is still in flight state
> because it has not
> had time to run virtblk_done().
> crash_arm> vring_packed_desc ffffff8085ff9e70
> struct vring_packed_desc {
>   addr = 10474619192,
>   len = 20481,
>   id = 667,
>   flags = 2
> }
> 
> I'm using a closed source virtual machine, so I can't see the source
> code for it,
> but I'm guessing it's similar to qemu.
> 
> After the device completes the request, we must also ensure that the driver can
> complete the request in virtblk_done().
> 

Okay, I think your approach of waiting for requests before
virtio_device_reset() makes sense. blk_mq_complete_request() is async
(might be deferred to an IPI or softirq) so it's not enough for
virtblk_done() to run before virtio_device_reset() returns. There is no
guarantee that virtblk_request_done() runs before virtio_device_reset()
returns.

A separate issue about virtio_device_reset():

Are you using virtio-mmio? virtio-mmio's vm_reset() doesn't offer the
same guarantees as virtio-pci's reset functions. virtio-pci guarantees
that irqs sent by the device during the reset operation complete and the
irq handlers run before virtio_device_reset() returns. virtio-mmio does
not.

(On top of this, virtio_device_reset() now has
CONFIG_VIRTIO_HARDEN_NOTIFICATION which changes the semantics. Drivers
cannot expect to complete any in-flight requests in
virtio_device_reset() when complied with this config option.)

Other drivers may be affected by these inconsistent
virtio_device_reset() semantics. I haven't audited the code.

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

  reply	other threads:[~2024-01-23 15:09 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-22 11:07 [PATCH 0/2] Fix requests loss during virtio-blk device suspend Yi Sun
2024-01-22 11:07 ` [PATCH 1/2] blk-mq: introduce blk_mq_tagset_wait_request_completed() Yi Sun
2024-01-23 18:45   ` kernel test robot
2024-01-23 19:14   ` Keith Busch
2024-01-24 11:22     ` yi sun
2024-01-24 17:17       ` Keith Busch
2024-01-22 11:07 ` [PATCH 2/2] virtio-blk: Ensure no requests in virtqueues before deleting vqs Yi Sun
2024-01-22 15:42   ` Stefan Hajnoczi
2024-01-23  3:27     ` yi sun
2024-01-23 15:09       ` Stefan Hajnoczi [this message]
2024-01-24  7:38         ` yi sun

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=20240123150924.GD484337@fedora \
    --to=stefanha@redhat.com \
    --cc=axboe@kernel.dk \
    --cc=hongyu.jin@unisoc.com \
    --cc=jasowang@redhat.com \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=sunyibuaa@gmail.com \
    --cc=virtualization@lists.linux.dev \
    --cc=xuanzhuo@linux.alibaba.com \
    --cc=yi.sun@unisoc.com \
    --cc=zhiguo.niu@unisoc.com \
    /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.