1 | The following changes since commit 474f3938d79ab36b9231c9ad3b5a9314c2aeacde: | 1 | The following changes since commit 1d60bb4b14601e38ed17384277aa4c30c57925d3: |
---|---|---|---|
2 | 2 | ||
3 | Merge remote-tracking branch 'remotes/amarkovic/tags/mips-queue-jun-21-2019' into staging (2019-06-21 15:40:50 +0100) | 3 | Merge tag 'pull-request-2022-03-15v2' of https://gitlab.com/thuth/qemu into staging (2022-03-16 10:43:58 +0000) |
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 6c11dda922915aaaa032db4462294e8df45f7441: | 9 | for you to fetch changes up to fc8796465c6cd4091efe6a2f8b353f07324f49c7: |
10 | 10 | ||
11 | build: use $(DESTDIR)x instead of $(DESTDIR)/x (2019-06-28 14:12:14 +0100) | 11 | aio-posix: fix spurious ->poll_ready() callbacks in main loop (2022-03-17 11:23:18 +0000) |
12 | 12 | ||
13 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
14 | Pull request | 14 | Pull request |
15 | 15 | ||
16 | No user-visible changes. | 16 | Bug fixes for 7.0. |
17 | 17 | ||
18 | ---------------------------------------------------------------- | 18 | ---------------------------------------------------------------- |
19 | 19 | ||
20 | Haiyue Wang (1): | ||
21 | aio-posix: fix build failure io_uring 2.2 | ||
22 | |||
20 | Stefan Hajnoczi (1): | 23 | Stefan Hajnoczi (1): |
21 | build: use $(DESTDIR)x instead of $(DESTDIR)/x | 24 | aio-posix: fix spurious ->poll_ready() callbacks in main loop |
22 | 25 | ||
23 | Makefile | 16 ++++++++-------- | 26 | util/aio-posix.h | 1 + |
24 | 1 file changed, 8 insertions(+), 8 deletions(-) | 27 | util/aio-posix.c | 32 ++++++++++++++++++-------------- |
28 | util/fdmon-io_uring.c | 4 ++++ | ||
29 | 3 files changed, 23 insertions(+), 14 deletions(-) | ||
25 | 30 | ||
26 | -- | 31 | -- |
27 | 2.21.0 | 32 | 2.35.1 |
28 | 33 | ||
29 | diff view generated by jsdifflib |
1 | The GNU make manual[1] demonstrates $(DESTDIR)$(bindir)/foo and QEMU | 1 | From: Haiyue Wang <haiyue.wang@intel.com> |
---|---|---|---|
2 | mostly follows that. There are just a few instances of | ||
3 | $(DESTDIR)/$(bindir)/foo. Fix these inconsistencies. | ||
4 | 2 | ||
5 | [1] https://www.gnu.org/software/make/manual/html_node/DESTDIR.html | 3 | The io_uring fixed "Don't truncate addr fields to 32-bit on 32-bit": |
4 | https://git.kernel.dk/cgit/liburing/commit/?id=d84c29b19ed0b130000619cff40141bb1fc3615b | ||
6 | 5 | ||
7 | Cc: Daniel P. Berrange <berrange@redhat.com> | 6 | This leads to build failure: |
8 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | 7 | ../util/fdmon-io_uring.c: In function ‘add_poll_remove_sqe’: |
9 | Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> | 8 | ../util/fdmon-io_uring.c:182:36: error: passing argument 2 of ‘io_uring_prep_poll_remove’ makes integer from pointer without a cast [-Werror=int-conversion] |
10 | Message-id: 20190521145318.12787-1-stefanha@redhat.com | 9 | 182 | io_uring_prep_poll_remove(sqe, node); |
11 | Message-Id: <20190521145318.12787-1-stefanha@redhat.com> | 10 | | ^~~~ |
11 | | | | ||
12 | | AioHandler * | ||
13 | In file included from /root/io/qemu/include/block/aio.h:18, | ||
14 | from ../util/aio-posix.h:20, | ||
15 | from ../util/fdmon-io_uring.c:49: | ||
16 | /usr/include/liburing.h:415:17: note: expected ‘__u64’ {aka ‘long long unsigned int’} but argument is of type ‘AioHandler *’ | ||
17 | 415 | __u64 user_data) | ||
18 | | ~~~~~~^~~~~~~~~ | ||
19 | cc1: all warnings being treated as errors | ||
20 | |||
21 | Use LIBURING_HAVE_DATA64 to check whether the io_uring supports 64-bit | ||
22 | variants of the get/set userdata, to convert the paramter to the right | ||
23 | data type. | ||
24 | |||
25 | Signed-off-by: Haiyue Wang <haiyue.wang@intel.com> | ||
26 | Message-Id: <20220221162401.45415-1-haiyue.wang@intel.com> | ||
12 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | 27 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> |
13 | --- | 28 | --- |
14 | Makefile | 16 ++++++++-------- | 29 | util/fdmon-io_uring.c | 4 ++++ |
15 | 1 file changed, 8 insertions(+), 8 deletions(-) | 30 | 1 file changed, 4 insertions(+) |
16 | 31 | ||
17 | diff --git a/Makefile b/Makefile | 32 | diff --git a/util/fdmon-io_uring.c b/util/fdmon-io_uring.c |
18 | index XXXXXXX..XXXXXXX 100644 | 33 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/Makefile | 34 | --- a/util/fdmon-io_uring.c |
20 | +++ b/Makefile | 35 | +++ b/util/fdmon-io_uring.c |
21 | @@ -XXX,XX +XXX,XX @@ ifneq ($(DESCS),) | 36 | @@ -XXX,XX +XXX,XX @@ static void add_poll_remove_sqe(AioContext *ctx, AioHandler *node) |
22 | done | 37 | { |
23 | endif | 38 | struct io_uring_sqe *sqe = get_sqe(ctx); |
24 | for s in $(ICON_SIZES); do \ | 39 | |
25 | - mkdir -p "$(DESTDIR)/$(qemu_icondir)/hicolor/$${s}/apps"; \ | 40 | +#ifdef LIBURING_HAVE_DATA64 |
26 | + mkdir -p "$(DESTDIR)$(qemu_icondir)/hicolor/$${s}/apps"; \ | 41 | + io_uring_prep_poll_remove(sqe, (__u64)(uintptr_t)node); |
27 | $(INSTALL_DATA) $(SRC_PATH)/ui/icons/qemu_$${s}.png \ | 42 | +#else |
28 | - "$(DESTDIR)/$(qemu_icondir)/hicolor/$${s}/apps/qemu.png"; \ | 43 | io_uring_prep_poll_remove(sqe, node); |
29 | + "$(DESTDIR)$(qemu_icondir)/hicolor/$${s}/apps/qemu.png"; \ | 44 | +#endif |
30 | done; \ | 45 | } |
31 | - mkdir -p "$(DESTDIR)/$(qemu_icondir)/hicolor/32x32/apps"; \ | 46 | |
32 | + mkdir -p "$(DESTDIR)$(qemu_icondir)/hicolor/32x32/apps"; \ | 47 | /* Add a timeout that self-cancels when another cqe becomes ready */ |
33 | $(INSTALL_DATA) $(SRC_PATH)/ui/icons/qemu_32x32.bmp \ | ||
34 | - "$(DESTDIR)/$(qemu_icondir)/hicolor/32x32/apps/qemu.bmp"; \ | ||
35 | - mkdir -p "$(DESTDIR)/$(qemu_icondir)/hicolor/scalable/apps"; \ | ||
36 | + "$(DESTDIR)$(qemu_icondir)/hicolor/32x32/apps/qemu.bmp"; \ | ||
37 | + mkdir -p "$(DESTDIR)$(qemu_icondir)/hicolor/scalable/apps"; \ | ||
38 | $(INSTALL_DATA) $(SRC_PATH)/ui/icons/qemu.svg \ | ||
39 | - "$(DESTDIR)/$(qemu_icondir)/hicolor/scalable/apps/qemu.svg" | ||
40 | - mkdir -p "$(DESTDIR)/$(qemu_desktopdir)" | ||
41 | + "$(DESTDIR)$(qemu_icondir)/hicolor/scalable/apps/qemu.svg" | ||
42 | + mkdir -p "$(DESTDIR)$(qemu_desktopdir)" | ||
43 | $(INSTALL_DATA) $(SRC_PATH)/ui/qemu.desktop \ | ||
44 | - "$(DESTDIR)/$(qemu_desktopdir)/qemu.desktop" | ||
45 | + "$(DESTDIR)$(qemu_desktopdir)/qemu.desktop" | ||
46 | ifdef CONFIG_GTK | ||
47 | $(MAKE) -C po $@ | ||
48 | endif | ||
49 | -- | 48 | -- |
50 | 2.21.0 | 49 | 2.35.1 |
51 | 50 | ||
52 | 51 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | When ->poll() succeeds the AioHandler is placed on the ready list with | ||
2 | revents set to the magic value 0. This magic value causes | ||
3 | aio_dispatch_handler() to invoke ->poll_ready() instead of ->io_read() | ||
4 | for G_IO_IN or ->io_write() for G_IO_OUT. | ||
1 | 5 | ||
6 | This magic value 0 hack works for the IOThread where AioHandlers are | ||
7 | placed on ->ready_list and processed by aio_dispatch_ready_handlers(). | ||
8 | It does not work for the main loop where all AioHandlers are processed | ||
9 | by aio_dispatch_handlers(), even those that are not ready and have a | ||
10 | revents value of 0. | ||
11 | |||
12 | As a result the main loop invokes ->poll_ready() on AioHandlers that are | ||
13 | not ready. These spurious ->poll_ready() calls waste CPU cycles and | ||
14 | could lead to crashes if the code assumes ->poll() must have succeeded | ||
15 | before ->poll_ready() is called (a reasonable asumption but I haven't | ||
16 | seen it in practice). | ||
17 | |||
18 | Stop using revents to track whether ->poll_ready() will be called on an | ||
19 | AioHandler. Introduce a separate AioHandler->poll_ready field instead. | ||
20 | This eliminates spurious ->poll_ready() calls in the main loop. | ||
21 | |||
22 | Fixes: 826cc32423db2a99d184dbf4f507c737d7e7a4ae ("aio-posix: split poll check from ready handler") | ||
23 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
24 | Reported-by: Jason Wang <jasowang@redhat.com> | ||
25 | Tested-by: Jason Wang <jasowang@redhat.com> | ||
26 | Message-id: 20220223155703.136833-1-stefanha@redhat.com | ||
27 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
28 | --- | ||
29 | util/aio-posix.h | 1 + | ||
30 | util/aio-posix.c | 32 ++++++++++++++++++-------------- | ||
31 | 2 files changed, 19 insertions(+), 14 deletions(-) | ||
32 | |||
33 | diff --git a/util/aio-posix.h b/util/aio-posix.h | ||
34 | index XXXXXXX..XXXXXXX 100644 | ||
35 | --- a/util/aio-posix.h | ||
36 | +++ b/util/aio-posix.h | ||
37 | @@ -XXX,XX +XXX,XX @@ struct AioHandler { | ||
38 | unsigned flags; /* see fdmon-io_uring.c */ | ||
39 | #endif | ||
40 | int64_t poll_idle_timeout; /* when to stop userspace polling */ | ||
41 | + bool poll_ready; /* has polling detected an event? */ | ||
42 | bool is_external; | ||
43 | }; | ||
44 | |||
45 | diff --git a/util/aio-posix.c b/util/aio-posix.c | ||
46 | index XXXXXXX..XXXXXXX 100644 | ||
47 | --- a/util/aio-posix.c | ||
48 | +++ b/util/aio-posix.c | ||
49 | @@ -XXX,XX +XXX,XX @@ | ||
50 | #include "trace.h" | ||
51 | #include "aio-posix.h" | ||
52 | |||
53 | -/* | ||
54 | - * G_IO_IN and G_IO_OUT are not appropriate revents values for polling, since | ||
55 | - * the handler may not need to access the file descriptor. For example, the | ||
56 | - * handler doesn't need to read from an EventNotifier if it polled a memory | ||
57 | - * location and a read syscall would be slow. Define our own unique revents | ||
58 | - * value to indicate that polling determined this AioHandler is ready. | ||
59 | - */ | ||
60 | -#define REVENTS_POLL_READY 0 | ||
61 | - | ||
62 | /* Stop userspace polling on a handler if it isn't active for some time */ | ||
63 | #define POLL_IDLE_INTERVAL_NS (7 * NANOSECONDS_PER_SECOND) | ||
64 | |||
65 | @@ -XXX,XX +XXX,XX @@ void aio_add_ready_handler(AioHandlerList *ready_list, | ||
66 | QLIST_INSERT_HEAD(ready_list, node, node_ready); | ||
67 | } | ||
68 | |||
69 | +static void aio_add_poll_ready_handler(AioHandlerList *ready_list, | ||
70 | + AioHandler *node) | ||
71 | +{ | ||
72 | + QLIST_SAFE_REMOVE(node, node_ready); /* remove from nested parent's list */ | ||
73 | + node->poll_ready = true; | ||
74 | + QLIST_INSERT_HEAD(ready_list, node, node_ready); | ||
75 | +} | ||
76 | + | ||
77 | static AioHandler *find_aio_handler(AioContext *ctx, int fd) | ||
78 | { | ||
79 | AioHandler *node; | ||
80 | @@ -XXX,XX +XXX,XX @@ static bool aio_remove_fd_handler(AioContext *ctx, AioHandler *node) | ||
81 | } | ||
82 | |||
83 | node->pfd.revents = 0; | ||
84 | + node->poll_ready = false; | ||
85 | |||
86 | /* If the fd monitor has already marked it deleted, leave it alone */ | ||
87 | if (QLIST_IS_INSERTED(node, node_deleted)) { | ||
88 | @@ -XXX,XX +XXX,XX @@ static bool poll_set_started(AioContext *ctx, AioHandlerList *ready_list, | ||
89 | |||
90 | /* Poll one last time in case ->io_poll_end() raced with the event */ | ||
91 | if (!started && node->io_poll(node->opaque)) { | ||
92 | - aio_add_ready_handler(ready_list, node, REVENTS_POLL_READY); | ||
93 | + aio_add_poll_ready_handler(ready_list, node); | ||
94 | progress = true; | ||
95 | } | ||
96 | } | ||
97 | @@ -XXX,XX +XXX,XX @@ bool aio_pending(AioContext *ctx) | ||
98 | QLIST_FOREACH_RCU(node, &ctx->aio_handlers, node) { | ||
99 | int revents; | ||
100 | |||
101 | + /* TODO should this check poll ready? */ | ||
102 | revents = node->pfd.revents & node->pfd.events; | ||
103 | if (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR) && node->io_read && | ||
104 | aio_node_check(ctx, node->is_external)) { | ||
105 | @@ -XXX,XX +XXX,XX @@ static void aio_free_deleted_handlers(AioContext *ctx) | ||
106 | static bool aio_dispatch_handler(AioContext *ctx, AioHandler *node) | ||
107 | { | ||
108 | bool progress = false; | ||
109 | + bool poll_ready; | ||
110 | int revents; | ||
111 | |||
112 | revents = node->pfd.revents & node->pfd.events; | ||
113 | node->pfd.revents = 0; | ||
114 | |||
115 | + poll_ready = node->poll_ready; | ||
116 | + node->poll_ready = false; | ||
117 | + | ||
118 | /* | ||
119 | * Start polling AioHandlers when they become ready because activity is | ||
120 | * likely to continue. Note that starvation is theoretically possible when | ||
121 | @@ -XXX,XX +XXX,XX @@ static bool aio_dispatch_handler(AioContext *ctx, AioHandler *node) | ||
122 | QLIST_INSERT_HEAD(&ctx->poll_aio_handlers, node, node_poll); | ||
123 | } | ||
124 | if (!QLIST_IS_INSERTED(node, node_deleted) && | ||
125 | - revents == 0 && | ||
126 | + poll_ready && revents == 0 && | ||
127 | aio_node_check(ctx, node->is_external) && | ||
128 | node->io_poll_ready) { | ||
129 | node->io_poll_ready(node->opaque); | ||
130 | @@ -XXX,XX +XXX,XX @@ static bool run_poll_handlers_once(AioContext *ctx, | ||
131 | QLIST_FOREACH_SAFE(node, &ctx->poll_aio_handlers, node_poll, tmp) { | ||
132 | if (aio_node_check(ctx, node->is_external) && | ||
133 | node->io_poll(node->opaque)) { | ||
134 | - aio_add_ready_handler(ready_list, node, REVENTS_POLL_READY); | ||
135 | + aio_add_poll_ready_handler(ready_list, node); | ||
136 | |||
137 | node->poll_idle_timeout = now + POLL_IDLE_INTERVAL_NS; | ||
138 | |||
139 | @@ -XXX,XX +XXX,XX @@ static bool remove_idle_poll_handlers(AioContext *ctx, | ||
140 | * this causes progress. | ||
141 | */ | ||
142 | if (node->io_poll(node->opaque)) { | ||
143 | - aio_add_ready_handler(ready_list, node, | ||
144 | - REVENTS_POLL_READY); | ||
145 | + aio_add_poll_ready_handler(ready_list, node); | ||
146 | progress = true; | ||
147 | } | ||
148 | } | ||
149 | -- | ||
150 | 2.35.1 | diff view generated by jsdifflib |