1 | The following changes since commit 0a301624c2f4ced3331ffd5bce85b4274fe132af: | 1 | The following changes since commit ee59483267de29056b5b2ee2421ef3844e5c9932: |
---|---|---|---|
2 | 2 | ||
3 | Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20220208' into staging (2022-02-08 11:40:08 +0000) | 3 | Merge tag 'qemu-openbios-20230307' of https://github.com/mcayland/qemu into staging (2023-03-09 16:55:03 +0000) |
4 | 4 | ||
5 | are available in the Git repository at: | 5 | are available in the Git repository at: |
6 | 6 | ||
7 | https://gitlab.com/kmwolf/qemu.git tags/for-upstream | 7 | https://repo.or.cz/qemu/kevin.git tags/for-upstream |
8 | 8 | ||
9 | for you to fetch changes up to fdb8541b2e4f6ff60f435fbb5a5e1df20c275a86: | 9 | for you to fetch changes up to ecf8191314798391b1df80bcb829c0ead4f8acc9: |
10 | 10 | ||
11 | hw/block/fdc-isa: Respect QOM properties when building AML (2022-02-11 17:37:26 +0100) | 11 | qed: remove spurious BDRV_POLL_WHILE() (2023-03-10 15:14:46 +0100) |
12 | 12 | ||
13 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
14 | Block layer patches | 14 | Block layer patches |
15 | 15 | ||
16 | - Fix crash in blockdev-reopen with iothreads | 16 | - fuse: Fix fallocate(PUNCH_HOLE) to zero out the range |
17 | - fdc-isa: Respect QOM properties when building AML | 17 | - qed: remove spurious BDRV_POLL_WHILE() |
18 | 18 | ||
19 | ---------------------------------------------------------------- | 19 | ---------------------------------------------------------------- |
20 | Bernhard Beschow (1): | 20 | Hanna Czenczek (2): |
21 | hw/block/fdc-isa: Respect QOM properties when building AML | 21 | block/fuse: Let PUNCH_HOLE write zeroes |
22 | iotests/308: Add test for 'write -zu' | ||
22 | 23 | ||
23 | Kevin Wolf (2): | 24 | Stefan Hajnoczi (1): |
24 | block: Lock AioContext for drain_end in blockdev-reopen | 25 | qed: remove spurious BDRV_POLL_WHILE() |
25 | iotests: Test blockdev-reopen with iothreads and throttling | ||
26 | 26 | ||
27 | blockdev.c | 11 ++++++++++- | 27 | block/export/fuse.c | 11 ++++++++++- |
28 | hw/block/fdc-isa.c | 11 +++++++---- | 28 | block/qed.c | 1 - |
29 | tests/qemu-iotests/245 | 36 +++++++++++++++++++++++++++++++++--- | 29 | tests/qemu-iotests/308 | 43 +++++++++++++++++++++++++++++++++++++++++++ |
30 | tests/qemu-iotests/245.out | 4 ++-- | 30 | tests/qemu-iotests/308.out | 35 +++++++++++++++++++++++++++++++++++ |
31 | 4 files changed, 52 insertions(+), 10 deletions(-) | 31 | 4 files changed, 88 insertions(+), 2 deletions(-) |
32 | |||
33 | diff view generated by jsdifflib |
1 | From: Bernhard Beschow <shentey@gmail.com> | 1 | From: Hanna Czenczek <hreitz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | Other ISA devices such as serial-isa use the properties in their | 3 | fallocate(2) says about PUNCH_HOLE: "After a successful call, subsequent |
4 | build_aml functions. fdc-isa not using them is probably an oversight. | 4 | reads from this range will return zeros." As it is, PUNCH_HOLE is |
5 | implemented as a call to blk_pdiscard(), which does not guarantee this. | ||
5 | 6 | ||
6 | Signed-off-by: Bernhard Beschow <shentey@gmail.com> | 7 | We must call blk_pwrite_zeroes() instead. The difference to ZERO_RANGE |
7 | Message-Id: <20220209191558.30393-1-shentey@gmail.com> | 8 | is that we pass the `BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK` flags to |
8 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | 9 | the call -- the storage is supposed to be unmapped, and a slow fallback |
10 | by actually writing zeroes as data is not allowed. | ||
11 | |||
12 | Closes: https://gitlab.com/qemu-project/qemu/-/issues/1507 | ||
13 | Signed-off-by: Hanna Czenczek <hreitz@redhat.com> | ||
14 | Message-Id: <20230227104725.33511-2-hreitz@redhat.com> | ||
15 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | ||
9 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 16 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
10 | --- | 17 | --- |
11 | hw/block/fdc-isa.c | 11 +++++++---- | 18 | block/export/fuse.c | 11 ++++++++++- |
12 | 1 file changed, 7 insertions(+), 4 deletions(-) | 19 | 1 file changed, 10 insertions(+), 1 deletion(-) |
13 | 20 | ||
14 | diff --git a/hw/block/fdc-isa.c b/hw/block/fdc-isa.c | 21 | diff --git a/block/export/fuse.c b/block/export/fuse.c |
15 | index XXXXXXX..XXXXXXX 100644 | 22 | index XXXXXXX..XXXXXXX 100644 |
16 | --- a/hw/block/fdc-isa.c | 23 | --- a/block/export/fuse.c |
17 | +++ b/hw/block/fdc-isa.c | 24 | +++ b/block/export/fuse.c |
18 | @@ -XXX,XX +XXX,XX @@ int cmos_get_fd_drive_type(FloppyDriveType fd0) | 25 | @@ -XXX,XX +XXX,XX @@ static void fuse_fallocate(fuse_req_t req, fuse_ino_t inode, int mode, |
19 | 26 | do { | |
20 | static void fdc_isa_build_aml(ISADevice *isadev, Aml *scope) | 27 | int size = MIN(length, BDRV_REQUEST_MAX_BYTES); |
21 | { | 28 | |
22 | + FDCtrlISABus *isa = ISA_FDC(isadev); | 29 | - ret = blk_pdiscard(exp->common.blk, offset, size); |
23 | Aml *dev; | 30 | + ret = blk_pwrite_zeroes(exp->common.blk, offset, size, |
24 | Aml *crs; | 31 | + BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK); |
25 | int i; | 32 | + if (ret == -ENOTSUP) { |
26 | @@ -XXX,XX +XXX,XX @@ static void fdc_isa_build_aml(ISADevice *isadev, Aml *scope) | 33 | + /* |
27 | }; | 34 | + * fallocate() specifies to return EOPNOTSUPP for unsupported |
28 | 35 | + * operations | |
29 | crs = aml_resource_template(); | 36 | + */ |
30 | - aml_append(crs, aml_io(AML_DECODE16, 0x03F2, 0x03F2, 0x00, 0x04)); | 37 | + ret = -EOPNOTSUPP; |
31 | - aml_append(crs, aml_io(AML_DECODE16, 0x03F7, 0x03F7, 0x00, 0x01)); | 38 | + } |
32 | - aml_append(crs, aml_irq_no_flags(6)); | 39 | + |
33 | aml_append(crs, | 40 | offset += size; |
34 | - aml_dma(AML_COMPATIBILITY, AML_NOTBUSMASTER, AML_TRANSFER8, 2)); | 41 | length -= size; |
35 | + aml_io(AML_DECODE16, isa->iobase + 2, isa->iobase + 2, 0x00, 0x04)); | 42 | } while (ret == 0 && length > 0); |
36 | + aml_append(crs, | ||
37 | + aml_io(AML_DECODE16, isa->iobase + 7, isa->iobase + 7, 0x00, 0x01)); | ||
38 | + aml_append(crs, aml_irq_no_flags(isa->irq)); | ||
39 | + aml_append(crs, | ||
40 | + aml_dma(AML_COMPATIBILITY, AML_NOTBUSMASTER, AML_TRANSFER8, isa->dma)); | ||
41 | |||
42 | dev = aml_device("FDC0"); | ||
43 | aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0700"))); | ||
44 | -- | 43 | -- |
45 | 2.34.1 | 44 | 2.39.2 |
46 | |||
47 | diff view generated by jsdifflib |
1 | The 'throttle' block driver implements .bdrv_co_drain_end, so | 1 | From: Hanna Czenczek <hreitz@redhat.com> |
---|---|---|---|
2 | blockdev-reopen will have to wait for it to complete in the polling | ||
3 | loop at the end of qmp_blockdev_reopen(). This makes AIO_WAIT_WHILE() | ||
4 | release the AioContext lock, which causes a crash if the lock hasn't | ||
5 | correctly been taken. | ||
6 | 2 | ||
7 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 3 | Try writing zeroes to a FUSE export while allowing the area to be |
8 | Message-Id: <20220203140534.36522-3-kwolf@redhat.com> | 4 | unmapped; block/file-posix.c generally implements writing zeroes with |
9 | Reviewed-by: Hanna Reitz <hreitz@redhat.com> | 5 | BDRV_REQ_MAY_UNMAP ('write -zu') by calling fallocate(PUNCH_HOLE). This |
6 | used to lead to a blk_pdiscard() in the FUSE export, which may or may | ||
7 | not lead to the area being zeroed. HEAD^ fixed this to use | ||
8 | blk_pwrite_zeroes() instead (again with BDRV_REQ_MAY_UNMAP), so verify | ||
9 | that running `qemu-io 'write -zu'` on a FUSE exports always results in | ||
10 | zeroes being written. | ||
11 | |||
12 | Signed-off-by: Hanna Czenczek <hreitz@redhat.com> | ||
13 | Message-Id: <20230227104725.33511-3-hreitz@redhat.com> | ||
14 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | ||
10 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 15 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
11 | --- | 16 | --- |
12 | tests/qemu-iotests/245 | 36 +++++++++++++++++++++++++++++++++--- | 17 | tests/qemu-iotests/308 | 43 ++++++++++++++++++++++++++++++++++++++ |
13 | tests/qemu-iotests/245.out | 4 ++-- | 18 | tests/qemu-iotests/308.out | 35 +++++++++++++++++++++++++++++++ |
14 | 2 files changed, 35 insertions(+), 5 deletions(-) | 19 | 2 files changed, 78 insertions(+) |
15 | 20 | ||
16 | diff --git a/tests/qemu-iotests/245 b/tests/qemu-iotests/245 | 21 | diff --git a/tests/qemu-iotests/308 b/tests/qemu-iotests/308 |
17 | index XXXXXXX..XXXXXXX 100755 | 22 | index XXXXXXX..XXXXXXX 100755 |
18 | --- a/tests/qemu-iotests/245 | 23 | --- a/tests/qemu-iotests/308 |
19 | +++ b/tests/qemu-iotests/245 | 24 | +++ b/tests/qemu-iotests/308 |
20 | @@ -XXX,XX +XXX,XX @@ class TestBlockdevReopen(iotests.QMPTestCase): | 25 | @@ -XXX,XX +XXX,XX @@ echo |
21 | self.assertEqual(self.get_node('hd1'), None) | 26 | echo '=== Compare copy with original ===' |
22 | self.assert_qmp(self.get_node('hd2'), 'ro', True) | 27 | |
23 | 28 | $QEMU_IMG compare -f raw -F $IMGFMT "$COPIED_IMG" "$TEST_IMG" | |
24 | - def run_test_iothreads(self, iothread_a, iothread_b, errmsg = None): | 29 | +_cleanup_test_img |
25 | - opts = hd_opts(0) | ||
26 | + def run_test_iothreads(self, iothread_a, iothread_b, errmsg = None, | ||
27 | + opts_a = None, opts_b = None): | ||
28 | + opts = opts_a or hd_opts(0) | ||
29 | result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) | ||
30 | self.assert_qmp(result, 'return', {}) | ||
31 | |||
32 | - opts2 = hd_opts(2) | ||
33 | + opts2 = opts_b or hd_opts(2) | ||
34 | result = self.vm.qmp('blockdev-add', conv_keys = False, **opts2) | ||
35 | self.assert_qmp(result, 'return', {}) | ||
36 | |||
37 | @@ -XXX,XX +XXX,XX @@ class TestBlockdevReopen(iotests.QMPTestCase): | ||
38 | def test_iothreads_switch_overlay(self): | ||
39 | self.run_test_iothreads('', 'iothread0') | ||
40 | |||
41 | + def test_iothreads_with_throttling(self): | ||
42 | + # Create a throttle-group object | ||
43 | + opts = { 'qom-type': 'throttle-group', 'id': 'group0', | ||
44 | + 'limits': { 'iops-total': 1000 } } | ||
45 | + result = self.vm.qmp('object-add', conv_keys = False, **opts) | ||
46 | + self.assert_qmp(result, 'return', {}) | ||
47 | + | 30 | + |
48 | + # Options with a throttle filter between format and protocol | 31 | +echo |
49 | + opts = [ | 32 | +echo '=== Writing zeroes while unmapping ===' |
50 | + { | 33 | +# Regression test for https://gitlab.com/qemu-project/qemu/-/issues/1507 |
51 | + 'driver': iotests.imgfmt, | 34 | +_make_test_img 64M |
52 | + 'node-name': f'hd{idx}', | 35 | +$QEMU_IO -c 'write -s /dev/urandom 0 64M' "$TEST_IMG" | _filter_qemu_io |
53 | + 'file' : { | ||
54 | + 'node-name': f'hd{idx}-throttle', | ||
55 | + 'driver': 'throttle', | ||
56 | + 'throttle-group': 'group0', | ||
57 | + 'file': { | ||
58 | + 'driver': 'file', | ||
59 | + 'node-name': f'hd{idx}-file', | ||
60 | + 'filename': hd_path[idx], | ||
61 | + }, | ||
62 | + }, | ||
63 | + } | ||
64 | + for idx in (0, 2) | ||
65 | + ] | ||
66 | + | 36 | + |
67 | + self.run_test_iothreads('iothread0', 'iothread0', None, | 37 | +_launch_qemu |
68 | + opts[0], opts[1]) | 38 | +_send_qemu_cmd $QEMU_HANDLE \ |
39 | + "{'execute': 'qmp_capabilities'}" \ | ||
40 | + 'return' | ||
69 | + | 41 | + |
70 | if __name__ == '__main__': | 42 | +_send_qemu_cmd $QEMU_HANDLE \ |
71 | iotests.activate_logging() | 43 | + "{'execute': 'blockdev-add', |
72 | iotests.main(supported_fmts=["qcow2"], | 44 | + 'arguments': { |
73 | diff --git a/tests/qemu-iotests/245.out b/tests/qemu-iotests/245.out | 45 | + 'driver': '$IMGFMT', |
46 | + 'node-name': 'node-format', | ||
47 | + 'file': { | ||
48 | + 'driver': 'file', | ||
49 | + 'filename': '$TEST_IMG' | ||
50 | + } | ||
51 | + } }" \ | ||
52 | + 'return' | ||
53 | + | ||
54 | +fuse_export_add 'export' "'mountpoint': '$EXT_MP', 'writable': true" | ||
55 | + | ||
56 | +# Try writing zeroes by unmapping | ||
57 | +$QEMU_IO -f raw -c 'write -zu 0 64M' "$EXT_MP" | _filter_qemu_io | ||
58 | + | ||
59 | +# Check the result | ||
60 | +$QEMU_IO -f raw -c 'read -P 0 0 64M' "$EXT_MP" | _filter_qemu_io | ||
61 | + | ||
62 | +_send_qemu_cmd $QEMU_HANDLE \ | ||
63 | + "{'execute': 'quit'}" \ | ||
64 | + 'return' | ||
65 | + | ||
66 | +wait=yes _cleanup_qemu | ||
67 | + | ||
68 | +# Check the original image | ||
69 | +$QEMU_IO -c 'read -P 0 0 64M' "$TEST_IMG" | _filter_qemu_io | ||
70 | + | ||
71 | +_cleanup_test_img | ||
72 | |||
73 | # success, all done | ||
74 | echo "*** done" | ||
75 | diff --git a/tests/qemu-iotests/308.out b/tests/qemu-iotests/308.out | ||
74 | index XXXXXXX..XXXXXXX 100644 | 76 | index XXXXXXX..XXXXXXX 100644 |
75 | --- a/tests/qemu-iotests/245.out | 77 | --- a/tests/qemu-iotests/308.out |
76 | +++ b/tests/qemu-iotests/245.out | 78 | +++ b/tests/qemu-iotests/308.out |
77 | @@ -XXX,XX +XXX,XX @@ read 1/1 bytes at offset 262152 | 79 | @@ -XXX,XX +XXX,XX @@ OK: Post-truncate image size is as expected |
78 | read 1/1 bytes at offset 262160 | 80 | |
79 | 1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | 81 | === Compare copy with original === |
80 | 82 | Images are identical. | |
81 | -............... | 83 | + |
82 | +................ | 84 | +=== Writing zeroes while unmapping === |
83 | ---------------------------------------------------------------------- | 85 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 |
84 | -Ran 25 tests | 86 | +wrote 67108864/67108864 bytes at offset 0 |
85 | +Ran 26 tests | 87 | +64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) |
86 | 88 | +{'execute': 'qmp_capabilities'} | |
87 | OK | 89 | +{"return": {}} |
90 | +{'execute': 'blockdev-add', | ||
91 | + 'arguments': { | ||
92 | + 'driver': 'IMGFMT', | ||
93 | + 'node-name': 'node-format', | ||
94 | + 'file': { | ||
95 | + 'driver': 'file', | ||
96 | + 'filename': 'TEST_DIR/t.IMGFMT' | ||
97 | + } | ||
98 | + } } | ||
99 | +{"return": {}} | ||
100 | +{'execute': 'block-export-add', | ||
101 | + 'arguments': { | ||
102 | + 'type': 'fuse', | ||
103 | + 'id': 'export', | ||
104 | + 'node-name': 'node-format', | ||
105 | + 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse', 'writable': true | ||
106 | + } } | ||
107 | +{"return": {}} | ||
108 | +wrote 67108864/67108864 bytes at offset 0 | ||
109 | +64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
110 | +read 67108864/67108864 bytes at offset 0 | ||
111 | +64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
112 | +{'execute': 'quit'} | ||
113 | +{"return": {}} | ||
114 | +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} | ||
115 | +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "export"}} | ||
116 | +read 67108864/67108864 bytes at offset 0 | ||
117 | +64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
118 | *** done | ||
88 | -- | 119 | -- |
89 | 2.34.1 | 120 | 2.39.2 |
90 | |||
91 | diff view generated by jsdifflib |
1 | bdrv_subtree_drained_end() requires the caller to hold the AioContext | 1 | From: Stefan Hajnoczi <stefanha@redhat.com> |
---|---|---|---|
2 | lock for the drained node. Not doing this for nodes outside of the main | ||
3 | AioContext leads to crashes when AIO_WAIT_WHILE() needs to wait and | ||
4 | tries to temporarily release the lock. | ||
5 | 2 | ||
6 | Fixes: 3908b7a8994fa5ef7a89aa58cd5a02fc58141592 | 3 | This looks like a copy-paste or merge error. BDRV_POLL_WHILE() is |
7 | Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2046659 | 4 | already called above. It's not needed in the qemu_in_coroutine() case. |
8 | Reported-by: Qing Wang <qinwang@redhat.com> | 5 | |
9 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 6 | Fixes: 9fb4dfc570ce ("qed: make bdrv_qed_do_open a coroutine_fn") |
10 | Message-Id: <20220203140534.36522-2-kwolf@redhat.com> | 7 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> |
11 | Reviewed-by: Hanna Reitz <hreitz@redhat.com> | 8 | Message-Id: <20230309163134.398707-1-stefanha@redhat.com> |
9 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | ||
12 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 10 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
13 | --- | 11 | --- |
14 | blockdev.c | 11 ++++++++++- | 12 | block/qed.c | 1 - |
15 | 1 file changed, 10 insertions(+), 1 deletion(-) | 13 | 1 file changed, 1 deletion(-) |
16 | 14 | ||
17 | diff --git a/blockdev.c b/blockdev.c | 15 | diff --git a/block/qed.c b/block/qed.c |
18 | index XXXXXXX..XXXXXXX 100644 | 16 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/blockdev.c | 17 | --- a/block/qed.c |
20 | +++ b/blockdev.c | 18 | +++ b/block/qed.c |
21 | @@ -XXX,XX +XXX,XX @@ void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp) | 19 | @@ -XXX,XX +XXX,XX @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags, |
22 | { | 20 | qemu_coroutine_enter(qemu_coroutine_create(bdrv_qed_open_entry, &qoc)); |
23 | BlockReopenQueue *queue = NULL; | 21 | BDRV_POLL_WHILE(bs, qoc.ret == -EINPROGRESS); |
24 | GSList *drained = NULL; | 22 | } |
25 | + GSList *p; | 23 | - BDRV_POLL_WHILE(bs, qoc.ret == -EINPROGRESS); |
26 | 24 | return qoc.ret; | |
27 | /* Add each one of the BDS that we want to reopen to the queue */ | ||
28 | for (; reopen_list != NULL; reopen_list = reopen_list->next) { | ||
29 | @@ -XXX,XX +XXX,XX @@ void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp) | ||
30 | |||
31 | fail: | ||
32 | bdrv_reopen_queue_free(queue); | ||
33 | - g_slist_free_full(drained, (GDestroyNotify) bdrv_subtree_drained_end); | ||
34 | + for (p = drained; p; p = p->next) { | ||
35 | + BlockDriverState *bs = p->data; | ||
36 | + AioContext *ctx = bdrv_get_aio_context(bs); | ||
37 | + | ||
38 | + aio_context_acquire(ctx); | ||
39 | + bdrv_subtree_drained_end(bs); | ||
40 | + aio_context_release(ctx); | ||
41 | + } | ||
42 | + g_slist_free(drained); | ||
43 | } | 25 | } |
44 | 26 | ||
45 | void qmp_blockdev_del(const char *node_name, Error **errp) | ||
46 | -- | 27 | -- |
47 | 2.34.1 | 28 | 2.39.2 |
48 | |||
49 | diff view generated by jsdifflib |