1 | The following changes since commit 61c265f0660ee476985808c8aa7915617c44fd53: | 1 | The following changes since commit ed8ad9728a9c0eec34db9dff61dfa2f1dd625637: |
---|---|---|---|
2 | 2 | ||
3 | Merge remote-tracking branch 'remotes/dgilbert/tags/pull-migration-20200313a' into staging (2020-03-13 10:33:04 +0000) | 3 | Merge tag 'pull-tpm-2023-07-14-1' of https://github.com/stefanberger/qemu-tpm into staging (2023-07-15 14:54:04 +0100) |
4 | 4 | ||
5 | are available in the Git repository at: | 5 | are available in the Git repository at: |
6 | 6 | ||
7 | https://github.com/stefanha/qemu.git tags/block-pull-request | 7 | https://gitlab.com/stefanha/qemu.git tags/block-pull-request |
8 | 8 | ||
9 | for you to fetch changes up to 4ab78b19189a81038e744728ed949d09aa477550: | 9 | for you to fetch changes up to 66547f416a61e0cb711dc76821890242432ba193: |
10 | 10 | ||
11 | block/io: fix bdrv_co_do_copy_on_readv (2020-03-16 11:46:11 +0000) | 11 | block/nvme: invoke blk_io_plug_call() outside q->lock (2023-07-17 09:17:41 -0400) |
12 | 12 | ||
13 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
14 | Pull request | 14 | Pull request |
15 | 15 | ||
16 | Fix the hang in the nvme:// block driver during startup. | ||
17 | |||
16 | ---------------------------------------------------------------- | 18 | ---------------------------------------------------------------- |
17 | 19 | ||
18 | Vladimir Sementsov-Ogievskiy (1): | 20 | Stefan Hajnoczi (1): |
19 | block/io: fix bdrv_co_do_copy_on_readv | 21 | block/nvme: invoke blk_io_plug_call() outside q->lock |
20 | 22 | ||
21 | block/io.c | 2 +- | 23 | block/nvme.c | 3 ++- |
22 | 1 file changed, 1 insertion(+), 1 deletion(-) | 24 | 1 file changed, 2 insertions(+), 1 deletion(-) |
23 | 25 | ||
24 | -- | 26 | -- |
25 | 2.24.1 | 27 | 2.40.1 |
26 | diff view generated by jsdifflib |
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | 1 | blk_io_plug_call() is invoked outside a blk_io_plug()/blk_io_unplug() |
---|---|---|---|
2 | section while opening the NVMe drive from: | ||
2 | 3 | ||
3 | Prior to 1143ec5ebf4 it was OK to qemu_iovec_from_buf() from aligned-up | 4 | nvme_file_open() -> |
4 | buffer to original qiov, as qemu_iovec_from_buf() will stop at qiov end | 5 | nvme_init() -> |
5 | anyway. | 6 | nvme_identify() -> |
7 | nvme_admin_cmd_sync() -> | ||
8 | nvme_submit_command() -> | ||
9 | blk_io_plug_call() | ||
6 | 10 | ||
7 | But after 1143ec5ebf4 we assume that bdrv_co_do_copy_on_readv works on | 11 | blk_io_plug_call() immediately invokes the given callback when the |
8 | part of original qiov, defined by qiov_offset and bytes. So we must not | 12 | current thread is not plugged, as is the case during nvme_file_open(). |
9 | touch qiov behind qiov_offset+bytes bound. Fix it. | ||
10 | 13 | ||
11 | Cc: qemu-stable@nongnu.org # v4.2 | 14 | Unfortunately, nvme_submit_command() calls blk_io_plug_call() with |
12 | Fixes: 1143ec5ebf4 | 15 | q->lock still held: |
13 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | 16 | |
14 | Reviewed-by: John Snow <jsnow@redhat.com> | 17 | ... |
15 | Message-id: 20200312081949.5350-1-vsementsov@virtuozzo.com | 18 | q->sq.tail = (q->sq.tail + 1) % NVME_QUEUE_SIZE; |
19 | q->need_kick++; | ||
20 | blk_io_plug_call(nvme_unplug_fn, q); | ||
21 | qemu_mutex_unlock(&q->lock); | ||
22 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
23 | |||
24 | nvme_unplug_fn() deadlocks trying to acquire q->lock because the lock is | ||
25 | already acquired by the same thread. The symptom is that QEMU hangs | ||
26 | during startup while opening the NVMe drive. | ||
27 | |||
28 | Fix this by moving the blk_io_plug_call() outside q->lock. This is safe | ||
29 | because no other thread runs code related to this queue and | ||
30 | blk_io_plug_call()'s internal state is immune to thread safety issues | ||
31 | since it is thread-local. | ||
32 | |||
33 | Reported-by: Lukáš Doktor <ldoktor@redhat.com> | ||
34 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
35 | Tested-by: Lukas Doktor <ldoktor@redhat.com> | ||
36 | Message-id: 20230712191628.252806-1-stefanha@redhat.com | ||
37 | Fixes: f2e590002bd6 ("block/nvme: convert to blk_io_plug_call() API") | ||
16 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | 38 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> |
17 | --- | 39 | --- |
18 | block/io.c | 2 +- | 40 | block/nvme.c | 3 ++- |
19 | 1 file changed, 1 insertion(+), 1 deletion(-) | 41 | 1 file changed, 2 insertions(+), 1 deletion(-) |
20 | 42 | ||
21 | diff --git a/block/io.c b/block/io.c | 43 | diff --git a/block/nvme.c b/block/nvme.c |
22 | index XXXXXXX..XXXXXXX 100644 | 44 | index XXXXXXX..XXXXXXX 100644 |
23 | --- a/block/io.c | 45 | --- a/block/nvme.c |
24 | +++ b/block/io.c | 46 | +++ b/block/nvme.c |
25 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child, | 47 | @@ -XXX,XX +XXX,XX @@ static void nvme_submit_command(NVMeQueuePair *q, NVMeRequest *req, |
26 | if (!(flags & BDRV_REQ_PREFETCH)) { | 48 | q->sq.tail * NVME_SQ_ENTRY_BYTES, cmd, sizeof(*cmd)); |
27 | qemu_iovec_from_buf(qiov, qiov_offset + progress, | 49 | q->sq.tail = (q->sq.tail + 1) % NVME_QUEUE_SIZE; |
28 | bounce_buffer + skip_bytes, | 50 | q->need_kick++; |
29 | - pnum - skip_bytes); | 51 | + qemu_mutex_unlock(&q->lock); |
30 | + MIN(pnum - skip_bytes, bytes - progress)); | 52 | + |
31 | } | 53 | blk_io_plug_call(nvme_unplug_fn, q); |
32 | } else if (!(flags & BDRV_REQ_PREFETCH)) { | 54 | - qemu_mutex_unlock(&q->lock); |
33 | /* Read directly into the destination */ | 55 | } |
56 | |||
57 | static void nvme_admin_cmd_sync_cb(void *opaque, int ret) | ||
34 | -- | 58 | -- |
35 | 2.24.1 | 59 | 2.40.1 |
36 | 60 | ||
61 | diff view generated by jsdifflib |