1 | The following changes since commit 6cb4f6db4f4367faa33da85b15f75bbbd2bed2a6: | 1 | The following changes since commit 6c769690ac845fa62642a5f93b4e4bd906adab95: |
---|---|---|---|
2 | 2 | ||
3 | Merge remote-tracking branch 'remotes/cleber/tags/python-next-pull-request' into staging (2019-03-07 16:16:02 +0000) | 3 | Merge remote-tracking branch 'remotes/vsementsov/tags/pull-simplebench-2021-05-04' into staging (2021-05-21 12:02:34 +0100) |
4 | 4 | ||
5 | are available in the Git repository at: | 5 | are available in the Git repository at: |
6 | 6 | ||
7 | git://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 6ca206204fa773c8626d59caf2a5676d6cc35f52: | 9 | for you to fetch changes up to 0a6f0c76a030710780ce10d6347a70f098024d21: |
10 | 10 | ||
11 | iothread: document about why we need explicit aio_poll() (2019-03-08 10:20:57 +0000) | 11 | coroutine-sleep: introduce qemu_co_sleep (2021-05-21 18:22:33 +0100) |
12 | 12 | ||
13 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
14 | Pull request | 14 | Pull request |
15 | 15 | ||
16 | ---------------------------------------------------------------- | 16 | ---------------------------------------------------------------- |
17 | 17 | ||
18 | Anastasiia Rusakova (1): | 18 | Paolo Bonzini (6): |
19 | hw/block/virtio-blk: Clean req->dev repetitions | 19 | coroutine-sleep: use a stack-allocated timer |
20 | coroutine-sleep: disallow NULL QemuCoSleepState** argument | ||
21 | coroutine-sleep: allow qemu_co_sleep_wake that wakes nothing | ||
22 | coroutine-sleep: move timer out of QemuCoSleepState | ||
23 | coroutine-sleep: replace QemuCoSleepState pointer with struct in the | ||
24 | API | ||
25 | coroutine-sleep: introduce qemu_co_sleep | ||
20 | 26 | ||
21 | Peter Xu (5): | 27 | Philippe Mathieu-Daudé (1): |
22 | iothread: replace init_done_cond with a semaphore | 28 | bitops.h: Improve find_xxx_bit() documentation |
23 | iothread: create the gcontext unconditionally | ||
24 | iothread: create main loop unconditionally | ||
25 | iothread: push gcontext earlier in the thread_fn | ||
26 | iothread: document about why we need explicit aio_poll() | ||
27 | 29 | ||
28 | Stefan Hajnoczi (1): | 30 | Zenghui Yu (1): |
29 | MAINTAINERS: add missing support status fields | 31 | multi-process: Initialize variables declared with g_auto* |
30 | 32 | ||
31 | MAINTAINERS | 3 ++ | 33 | include/qemu/bitops.h | 15 ++++++-- |
32 | include/sysemu/iothread.h | 5 +-- | 34 | include/qemu/coroutine.h | 27 ++++++++----- |
33 | hw/block/virtio-blk.c | 16 ++++--- | 35 | block/block-copy.c | 10 ++--- |
34 | iothread.c | 90 +++++++++++++++++++-------------------- | 36 | block/nbd.c | 14 +++---- |
35 | 4 files changed, 57 insertions(+), 57 deletions(-) | 37 | hw/remote/memory.c | 5 +-- |
38 | hw/remote/proxy.c | 3 +- | ||
39 | util/qemu-coroutine-sleep.c | 75 +++++++++++++++++++------------------ | ||
40 | 7 files changed, 79 insertions(+), 70 deletions(-) | ||
36 | 41 | ||
37 | -- | 42 | -- |
38 | 2.20.1 | 43 | 2.31.1 |
39 | 44 | ||
40 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | This patch adds the "S:" line for areas of the codebase that currently | ||
2 | lack a support status field. | ||
3 | 1 | ||
4 | Note that there are a few more areas that are more abstract and do not | ||
5 | correspond to a specific set of files. They have not been modified. | ||
6 | |||
7 | Cc: Alex Bennée <alex.bennee@linaro.org> | ||
8 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
9 | Reviewed-by: Thomas Huth <thuth@redhat.com> | ||
10 | Reviewed-by: Alex Bennée <alex.bennee@linaro.org> | ||
11 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
12 | Message-id: 20190301163518.20702-1-stefanha@redhat.com | ||
13 | Message-Id: <20190301163518.20702-1-stefanha@redhat.com> | ||
14 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
15 | --- | ||
16 | MAINTAINERS | 3 +++ | ||
17 | 1 file changed, 3 insertions(+) | ||
18 | |||
19 | diff --git a/MAINTAINERS b/MAINTAINERS | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/MAINTAINERS | ||
22 | +++ b/MAINTAINERS | ||
23 | @@ -XXX,XX +XXX,XX @@ F: include/hw/tricore/ | ||
24 | |||
25 | Multiarch Linux User Tests | ||
26 | M: Alex Bennée <alex.bennee@linaro.org> | ||
27 | +S: Maintained | ||
28 | F: tests/tcg/multiarch/ | ||
29 | |||
30 | Guest CPU Cores (KVM): | ||
31 | @@ -XXX,XX +XXX,XX @@ F: qemu.sasl | ||
32 | Coroutines | ||
33 | M: Stefan Hajnoczi <stefanha@redhat.com> | ||
34 | M: Kevin Wolf <kwolf@redhat.com> | ||
35 | +S: Maintained | ||
36 | F: util/*coroutine* | ||
37 | F: include/qemu/coroutine* | ||
38 | F: tests/test-coroutine.c | ||
39 | @@ -XXX,XX +XXX,XX @@ F: .gitlab-ci.yml | ||
40 | Guest Test Compilation Support | ||
41 | M: Alex Bennée <alex.bennee@linaro.org> | ||
42 | R: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
43 | +S: Maintained | ||
44 | F: tests/tcg/Makefile | ||
45 | F: tests/tcg/Makefile.include | ||
46 | L: qemu-devel@nongnu.org | ||
47 | -- | ||
48 | 2.20.1 | ||
49 | |||
50 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Anastasiia Rusakova <arusakova917@gmail.com> | ||
2 | 1 | ||
3 | Some functions sometimes uses req->dev even though a local variable | ||
4 | VirtIOBlock* s = req->dev has already been defined. | ||
5 | Updated places to use s everywhere in the file. | ||
6 | |||
7 | Signed-off-by: Anastasiia Rusakova <arusakova917@gmail.com> | ||
8 | Message-id: 20190307161925.4158-1-rusakova.nastasia@icloud.com | ||
9 | Message-Id: <20190307161925.4158-1-rusakova.nastasia@icloud.com> | ||
10 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
11 | --- | ||
12 | hw/block/virtio-blk.c | 16 +++++++++------- | ||
13 | 1 file changed, 9 insertions(+), 7 deletions(-) | ||
14 | |||
15 | diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/hw/block/virtio-blk.c | ||
18 | +++ b/hw/block/virtio-blk.c | ||
19 | @@ -XXX,XX +XXX,XX @@ static void virtio_blk_rw_complete(void *opaque, int ret) | ||
20 | } | ||
21 | |||
22 | if (ret) { | ||
23 | - int p = virtio_ldl_p(VIRTIO_DEVICE(req->dev), &req->out.type); | ||
24 | + int p = virtio_ldl_p(VIRTIO_DEVICE(s), &req->out.type); | ||
25 | bool is_read = !(p & VIRTIO_BLK_T_OUT); | ||
26 | /* Note that memory may be dirtied on read failure. If the | ||
27 | * virtio request is not completed here, as is the case for | ||
28 | @@ -XXX,XX +XXX,XX @@ static void virtio_blk_rw_complete(void *opaque, int ret) | ||
29 | } | ||
30 | |||
31 | virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); | ||
32 | - block_acct_done(blk_get_stats(req->dev->blk), &req->acct); | ||
33 | + block_acct_done(blk_get_stats(s->blk), &req->acct); | ||
34 | virtio_blk_free_request(req); | ||
35 | } | ||
36 | aio_context_release(blk_get_aio_context(s->conf.conf.blk)); | ||
37 | @@ -XXX,XX +XXX,XX @@ static int virtio_blk_handle_scsi_req(VirtIOBlockReq *req) | ||
38 | { | ||
39 | int status = VIRTIO_BLK_S_OK; | ||
40 | struct virtio_scsi_inhdr *scsi = NULL; | ||
41 | - VirtIODevice *vdev = VIRTIO_DEVICE(req->dev); | ||
42 | - VirtQueueElement *elem = &req->elem; | ||
43 | VirtIOBlock *blk = req->dev; | ||
44 | + VirtIODevice *vdev = VIRTIO_DEVICE(blk); | ||
45 | + VirtQueueElement *elem = &req->elem; | ||
46 | |||
47 | #ifdef __linux__ | ||
48 | int i; | ||
49 | @@ -XXX,XX +XXX,XX @@ static void virtio_blk_submit_multireq(BlockBackend *blk, MultiReqBuffer *mrb) | ||
50 | |||
51 | static void virtio_blk_handle_flush(VirtIOBlockReq *req, MultiReqBuffer *mrb) | ||
52 | { | ||
53 | - block_acct_start(blk_get_stats(req->dev->blk), &req->acct, 0, | ||
54 | + VirtIOBlock *s = req->dev; | ||
55 | + | ||
56 | + block_acct_start(blk_get_stats(s->blk), &req->acct, 0, | ||
57 | BLOCK_ACCT_FLUSH); | ||
58 | |||
59 | /* | ||
60 | * Make sure all outstanding writes are posted to the backing device. | ||
61 | */ | ||
62 | if (mrb->is_write && mrb->num_reqs > 0) { | ||
63 | - virtio_blk_submit_multireq(req->dev->blk, mrb); | ||
64 | + virtio_blk_submit_multireq(s->blk, mrb); | ||
65 | } | ||
66 | - blk_aio_flush(req->dev->blk, virtio_blk_flush_complete, req); | ||
67 | + blk_aio_flush(s->blk, virtio_blk_flush_complete, req); | ||
68 | } | ||
69 | |||
70 | static bool virtio_blk_sect_range_ok(VirtIOBlock *dev, | ||
71 | -- | ||
72 | 2.20.1 | ||
73 | |||
74 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Peter Xu <peterx@redhat.com> | ||
2 | 1 | ||
3 | Only sending an init-done message using lock+cond seems an overkill to | ||
4 | me. Replacing it with a simpler semaphore. | ||
5 | |||
6 | Meanwhile, init the semaphore unconditionally, then we can destroy it | ||
7 | unconditionally too in finalize which seems cleaner. | ||
8 | |||
9 | Signed-off-by: Peter Xu <peterx@redhat.com> | ||
10 | Message-id: 20190306115532.23025-2-peterx@redhat.com | ||
11 | Message-Id: <20190306115532.23025-2-peterx@redhat.com> | ||
12 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
13 | --- | ||
14 | include/sysemu/iothread.h | 3 +-- | ||
15 | iothread.c | 17 ++++------------- | ||
16 | 2 files changed, 5 insertions(+), 15 deletions(-) | ||
17 | |||
18 | diff --git a/include/sysemu/iothread.h b/include/sysemu/iothread.h | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/include/sysemu/iothread.h | ||
21 | +++ b/include/sysemu/iothread.h | ||
22 | @@ -XXX,XX +XXX,XX @@ typedef struct { | ||
23 | GMainContext *worker_context; | ||
24 | GMainLoop *main_loop; | ||
25 | GOnce once; | ||
26 | - QemuMutex init_done_lock; | ||
27 | - QemuCond init_done_cond; /* is thread initialization done? */ | ||
28 | + QemuSemaphore init_done_sem; /* is thread init done? */ | ||
29 | bool stopping; /* has iothread_stop() been called? */ | ||
30 | bool running; /* should iothread_run() continue? */ | ||
31 | int thread_id; | ||
32 | diff --git a/iothread.c b/iothread.c | ||
33 | index XXXXXXX..XXXXXXX 100644 | ||
34 | --- a/iothread.c | ||
35 | +++ b/iothread.c | ||
36 | @@ -XXX,XX +XXX,XX @@ static void *iothread_run(void *opaque) | ||
37 | rcu_register_thread(); | ||
38 | |||
39 | my_iothread = iothread; | ||
40 | - qemu_mutex_lock(&iothread->init_done_lock); | ||
41 | iothread->thread_id = qemu_get_thread_id(); | ||
42 | - qemu_cond_signal(&iothread->init_done_cond); | ||
43 | - qemu_mutex_unlock(&iothread->init_done_lock); | ||
44 | + qemu_sem_post(&iothread->init_done_sem); | ||
45 | |||
46 | while (iothread->running) { | ||
47 | aio_poll(iothread->ctx, true); | ||
48 | @@ -XXX,XX +XXX,XX @@ static void iothread_instance_init(Object *obj) | ||
49 | |||
50 | iothread->poll_max_ns = IOTHREAD_POLL_MAX_NS_DEFAULT; | ||
51 | iothread->thread_id = -1; | ||
52 | + qemu_sem_init(&iothread->init_done_sem, 0); | ||
53 | } | ||
54 | |||
55 | static void iothread_instance_finalize(Object *obj) | ||
56 | @@ -XXX,XX +XXX,XX @@ static void iothread_instance_finalize(Object *obj) | ||
57 | |||
58 | iothread_stop(iothread); | ||
59 | |||
60 | - if (iothread->thread_id != -1) { | ||
61 | - qemu_cond_destroy(&iothread->init_done_cond); | ||
62 | - qemu_mutex_destroy(&iothread->init_done_lock); | ||
63 | - } | ||
64 | /* | ||
65 | * Before glib2 2.33.10, there is a glib2 bug that GSource context | ||
66 | * pointer may not be cleared even if the context has already been | ||
67 | @@ -XXX,XX +XXX,XX @@ static void iothread_instance_finalize(Object *obj) | ||
68 | g_main_context_unref(iothread->worker_context); | ||
69 | iothread->worker_context = NULL; | ||
70 | } | ||
71 | + qemu_sem_destroy(&iothread->init_done_sem); | ||
72 | } | ||
73 | |||
74 | static void iothread_complete(UserCreatable *obj, Error **errp) | ||
75 | @@ -XXX,XX +XXX,XX @@ static void iothread_complete(UserCreatable *obj, Error **errp) | ||
76 | return; | ||
77 | } | ||
78 | |||
79 | - qemu_mutex_init(&iothread->init_done_lock); | ||
80 | - qemu_cond_init(&iothread->init_done_cond); | ||
81 | iothread->once = (GOnce) G_ONCE_INIT; | ||
82 | |||
83 | /* This assumes we are called from a thread with useful CPU affinity for us | ||
84 | @@ -XXX,XX +XXX,XX @@ static void iothread_complete(UserCreatable *obj, Error **errp) | ||
85 | g_free(name); | ||
86 | |||
87 | /* Wait for initialization to complete */ | ||
88 | - qemu_mutex_lock(&iothread->init_done_lock); | ||
89 | while (iothread->thread_id == -1) { | ||
90 | - qemu_cond_wait(&iothread->init_done_cond, | ||
91 | - &iothread->init_done_lock); | ||
92 | + qemu_sem_wait(&iothread->init_done_sem); | ||
93 | } | ||
94 | - qemu_mutex_unlock(&iothread->init_done_lock); | ||
95 | } | ||
96 | |||
97 | typedef struct { | ||
98 | -- | ||
99 | 2.20.1 | ||
100 | |||
101 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Peter Xu <peterx@redhat.com> | ||
2 | 1 | ||
3 | In existing code we create the gcontext dynamically at the first | ||
4 | access of the gcontext from caller. That can bring some complexity | ||
5 | and potential races during using iothread. Since the context itself | ||
6 | is not that big a resource, and we won't have millions of iothread, | ||
7 | let's simply create the gcontext unconditionally. | ||
8 | |||
9 | This will also be a preparation work further to move the thread | ||
10 | context push operation earlier than before (now it's only pushed right | ||
11 | before we want to start running the gmainloop). | ||
12 | |||
13 | Removing the g_once since it's not necessary, while introducing a new | ||
14 | run_gcontext boolean to show whether we want to run the gcontext. | ||
15 | |||
16 | Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> | ||
17 | Signed-off-by: Peter Xu <peterx@redhat.com> | ||
18 | Message-id: 20190306115532.23025-3-peterx@redhat.com | ||
19 | Message-Id: <20190306115532.23025-3-peterx@redhat.com> | ||
20 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
21 | --- | ||
22 | include/sysemu/iothread.h | 2 +- | ||
23 | iothread.c | 43 +++++++++++++++++++-------------------- | ||
24 | 2 files changed, 22 insertions(+), 23 deletions(-) | ||
25 | |||
26 | diff --git a/include/sysemu/iothread.h b/include/sysemu/iothread.h | ||
27 | index XXXXXXX..XXXXXXX 100644 | ||
28 | --- a/include/sysemu/iothread.h | ||
29 | +++ b/include/sysemu/iothread.h | ||
30 | @@ -XXX,XX +XXX,XX @@ typedef struct { | ||
31 | |||
32 | QemuThread thread; | ||
33 | AioContext *ctx; | ||
34 | + bool run_gcontext; /* whether we should run gcontext */ | ||
35 | GMainContext *worker_context; | ||
36 | GMainLoop *main_loop; | ||
37 | - GOnce once; | ||
38 | QemuSemaphore init_done_sem; /* is thread init done? */ | ||
39 | bool stopping; /* has iothread_stop() been called? */ | ||
40 | bool running; /* should iothread_run() continue? */ | ||
41 | diff --git a/iothread.c b/iothread.c | ||
42 | index XXXXXXX..XXXXXXX 100644 | ||
43 | --- a/iothread.c | ||
44 | +++ b/iothread.c | ||
45 | @@ -XXX,XX +XXX,XX @@ static void *iothread_run(void *opaque) | ||
46 | * We must check the running state again in case it was | ||
47 | * changed in previous aio_poll() | ||
48 | */ | ||
49 | - if (iothread->running && atomic_read(&iothread->worker_context)) { | ||
50 | + if (iothread->running && atomic_read(&iothread->run_gcontext)) { | ||
51 | GMainLoop *loop; | ||
52 | |||
53 | g_main_context_push_thread_default(iothread->worker_context); | ||
54 | @@ -XXX,XX +XXX,XX @@ static void iothread_instance_init(Object *obj) | ||
55 | iothread->poll_max_ns = IOTHREAD_POLL_MAX_NS_DEFAULT; | ||
56 | iothread->thread_id = -1; | ||
57 | qemu_sem_init(&iothread->init_done_sem, 0); | ||
58 | + /* By default, we don't run gcontext */ | ||
59 | + atomic_set(&iothread->run_gcontext, 0); | ||
60 | } | ||
61 | |||
62 | static void iothread_instance_finalize(Object *obj) | ||
63 | @@ -XXX,XX +XXX,XX @@ static void iothread_instance_finalize(Object *obj) | ||
64 | qemu_sem_destroy(&iothread->init_done_sem); | ||
65 | } | ||
66 | |||
67 | +static void iothread_init_gcontext(IOThread *iothread) | ||
68 | +{ | ||
69 | + GSource *source; | ||
70 | + | ||
71 | + iothread->worker_context = g_main_context_new(); | ||
72 | + source = aio_get_g_source(iothread_get_aio_context(iothread)); | ||
73 | + g_source_attach(source, iothread->worker_context); | ||
74 | + g_source_unref(source); | ||
75 | +} | ||
76 | + | ||
77 | static void iothread_complete(UserCreatable *obj, Error **errp) | ||
78 | { | ||
79 | Error *local_error = NULL; | ||
80 | @@ -XXX,XX +XXX,XX @@ static void iothread_complete(UserCreatable *obj, Error **errp) | ||
81 | return; | ||
82 | } | ||
83 | |||
84 | + /* | ||
85 | + * Init one GMainContext for the iothread unconditionally, even if | ||
86 | + * it's not used | ||
87 | + */ | ||
88 | + iothread_init_gcontext(iothread); | ||
89 | + | ||
90 | aio_context_set_poll_params(iothread->ctx, | ||
91 | iothread->poll_max_ns, | ||
92 | iothread->poll_grow, | ||
93 | @@ -XXX,XX +XXX,XX @@ static void iothread_complete(UserCreatable *obj, Error **errp) | ||
94 | return; | ||
95 | } | ||
96 | |||
97 | - iothread->once = (GOnce) G_ONCE_INIT; | ||
98 | - | ||
99 | /* This assumes we are called from a thread with useful CPU affinity for us | ||
100 | * to inherit. | ||
101 | */ | ||
102 | @@ -XXX,XX +XXX,XX @@ IOThreadInfoList *qmp_query_iothreads(Error **errp) | ||
103 | return head; | ||
104 | } | ||
105 | |||
106 | -static gpointer iothread_g_main_context_init(gpointer opaque) | ||
107 | -{ | ||
108 | - AioContext *ctx; | ||
109 | - IOThread *iothread = opaque; | ||
110 | - GSource *source; | ||
111 | - | ||
112 | - iothread->worker_context = g_main_context_new(); | ||
113 | - | ||
114 | - ctx = iothread_get_aio_context(iothread); | ||
115 | - source = aio_get_g_source(ctx); | ||
116 | - g_source_attach(source, iothread->worker_context); | ||
117 | - g_source_unref(source); | ||
118 | - | ||
119 | - aio_notify(iothread->ctx); | ||
120 | - return NULL; | ||
121 | -} | ||
122 | - | ||
123 | GMainContext *iothread_get_g_main_context(IOThread *iothread) | ||
124 | { | ||
125 | - g_once(&iothread->once, iothread_g_main_context_init, iothread); | ||
126 | - | ||
127 | + atomic_set(&iothread->run_gcontext, 1); | ||
128 | + aio_notify(iothread->ctx); | ||
129 | return iothread->worker_context; | ||
130 | } | ||
131 | |||
132 | -- | ||
133 | 2.20.1 | ||
134 | |||
135 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Peter Xu <peterx@redhat.com> | ||
2 | 1 | ||
3 | Since we've have the gcontext always there, create the main loop | ||
4 | altogether. The iothread_run() is even cleaner. | ||
5 | |||
6 | Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> | ||
7 | Signed-off-by: Peter Xu <peterx@redhat.com> | ||
8 | Message-id: 20190306115532.23025-4-peterx@redhat.com | ||
9 | Message-Id: <20190306115532.23025-4-peterx@redhat.com> | ||
10 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
11 | --- | ||
12 | iothread.c | 12 +++--------- | ||
13 | 1 file changed, 3 insertions(+), 9 deletions(-) | ||
14 | |||
15 | diff --git a/iothread.c b/iothread.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/iothread.c | ||
18 | +++ b/iothread.c | ||
19 | @@ -XXX,XX +XXX,XX @@ static void *iothread_run(void *opaque) | ||
20 | * changed in previous aio_poll() | ||
21 | */ | ||
22 | if (iothread->running && atomic_read(&iothread->run_gcontext)) { | ||
23 | - GMainLoop *loop; | ||
24 | - | ||
25 | g_main_context_push_thread_default(iothread->worker_context); | ||
26 | - iothread->main_loop = | ||
27 | - g_main_loop_new(iothread->worker_context, TRUE); | ||
28 | - loop = iothread->main_loop; | ||
29 | - | ||
30 | g_main_loop_run(iothread->main_loop); | ||
31 | - iothread->main_loop = NULL; | ||
32 | - g_main_loop_unref(loop); | ||
33 | - | ||
34 | g_main_context_pop_thread_default(iothread->worker_context); | ||
35 | } | ||
36 | } | ||
37 | @@ -XXX,XX +XXX,XX @@ static void iothread_instance_finalize(Object *obj) | ||
38 | if (iothread->worker_context) { | ||
39 | g_main_context_unref(iothread->worker_context); | ||
40 | iothread->worker_context = NULL; | ||
41 | + g_main_loop_unref(iothread->main_loop); | ||
42 | + iothread->main_loop = NULL; | ||
43 | } | ||
44 | qemu_sem_destroy(&iothread->init_done_sem); | ||
45 | } | ||
46 | @@ -XXX,XX +XXX,XX @@ static void iothread_init_gcontext(IOThread *iothread) | ||
47 | source = aio_get_g_source(iothread_get_aio_context(iothread)); | ||
48 | g_source_attach(source, iothread->worker_context); | ||
49 | g_source_unref(source); | ||
50 | + iothread->main_loop = g_main_loop_new(iothread->worker_context, TRUE); | ||
51 | } | ||
52 | |||
53 | static void iothread_complete(UserCreatable *obj, Error **errp) | ||
54 | -- | ||
55 | 2.20.1 | ||
56 | |||
57 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Peter Xu <peterx@redhat.com> | ||
2 | 1 | ||
3 | We were pushing the context until right before running the gmainloop. | ||
4 | Now since we have everything unconditionally, we can move this | ||
5 | earlier. | ||
6 | |||
7 | One benefit is that now it's done even before init_done_sem, so as | ||
8 | long as the iothread user calls iothread_create() and completes, we | ||
9 | know that the thread stack is ready. | ||
10 | |||
11 | Signed-off-by: Peter Xu <peterx@redhat.com> | ||
12 | Message-id: 20190306115532.23025-5-peterx@redhat.com | ||
13 | Message-Id: <20190306115532.23025-5-peterx@redhat.com> | ||
14 | |||
15 | [Tweaked comment wording as discussed with Peter Xu. | ||
16 | --Stefan] | ||
17 | |||
18 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
19 | --- | ||
20 | iothread.c | 9 ++++++--- | ||
21 | 1 file changed, 6 insertions(+), 3 deletions(-) | ||
22 | |||
23 | diff --git a/iothread.c b/iothread.c | ||
24 | index XXXXXXX..XXXXXXX 100644 | ||
25 | --- a/iothread.c | ||
26 | +++ b/iothread.c | ||
27 | @@ -XXX,XX +XXX,XX @@ static void *iothread_run(void *opaque) | ||
28 | IOThread *iothread = opaque; | ||
29 | |||
30 | rcu_register_thread(); | ||
31 | - | ||
32 | + /* | ||
33 | + * g_main_context_push_thread_default() must be called before anything | ||
34 | + * in this new thread uses glib. | ||
35 | + */ | ||
36 | + g_main_context_push_thread_default(iothread->worker_context); | ||
37 | my_iothread = iothread; | ||
38 | iothread->thread_id = qemu_get_thread_id(); | ||
39 | qemu_sem_post(&iothread->init_done_sem); | ||
40 | @@ -XXX,XX +XXX,XX @@ static void *iothread_run(void *opaque) | ||
41 | * changed in previous aio_poll() | ||
42 | */ | ||
43 | if (iothread->running && atomic_read(&iothread->run_gcontext)) { | ||
44 | - g_main_context_push_thread_default(iothread->worker_context); | ||
45 | g_main_loop_run(iothread->main_loop); | ||
46 | - g_main_context_pop_thread_default(iothread->worker_context); | ||
47 | } | ||
48 | } | ||
49 | |||
50 | + g_main_context_pop_thread_default(iothread->worker_context); | ||
51 | rcu_unregister_thread(); | ||
52 | return NULL; | ||
53 | } | ||
54 | -- | ||
55 | 2.20.1 | ||
56 | |||
57 | diff view generated by jsdifflib |
1 | From: Peter Xu <peterx@redhat.com> | 1 | From: Zenghui Yu <yuzenghui@huawei.com> |
---|---|---|---|
2 | 2 | ||
3 | After consulting Paolo I know why we'd better keep the explicit | 3 | Quote docs/devel/style.rst (section "Automatic memory deallocation"): |
4 | aio_poll() in iothread_run(). Document it directly into the code so | ||
5 | that future readers will know the answer from day one. | ||
6 | 4 | ||
7 | Signed-off-by: Peter Xu <peterx@redhat.com> | 5 | * Variables declared with g_auto* MUST always be initialized, |
8 | Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> | 6 | otherwise the cleanup function will use uninitialized stack memory |
9 | Message-id: 20190306115532.23025-6-peterx@redhat.com | 7 | |
10 | Message-Id: <20190306115532.23025-6-peterx@redhat.com> | 8 | Initialize @name properly to get rid of the compilation error (using |
9 | gcc-7.3.0 on CentOS): | ||
10 | |||
11 | ../hw/remote/proxy.c: In function 'pci_proxy_dev_realize': | ||
12 | /usr/include/glib-2.0/glib/glib-autocleanups.h:28:3: error: 'name' may be used uninitialized in this function [-Werror=maybe-uninitialized] | ||
13 | g_free (*pp); | ||
14 | ^~~~~~~~~~~~ | ||
15 | ../hw/remote/proxy.c:350:30: note: 'name' was declared here | ||
16 | g_autofree char *name; | ||
17 | ^~~~ | ||
18 | |||
19 | Signed-off-by: Zenghui Yu <yuzenghui@huawei.com> | ||
20 | Reviewed-by: Jagannathan Raman <jag.raman@oracle.com> | ||
21 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
22 | Reviewed-by: Miroslav Rezanina <mrezanin@redhat.com> | ||
23 | Message-id: 20210312112143.1369-1-yuzenghui@huawei.com | ||
11 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | 24 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> |
12 | --- | 25 | --- |
13 | iothread.c | 9 +++++++++ | 26 | hw/remote/memory.c | 5 ++--- |
14 | 1 file changed, 9 insertions(+) | 27 | hw/remote/proxy.c | 3 +-- |
28 | 2 files changed, 3 insertions(+), 5 deletions(-) | ||
15 | 29 | ||
16 | diff --git a/iothread.c b/iothread.c | 30 | diff --git a/hw/remote/memory.c b/hw/remote/memory.c |
17 | index XXXXXXX..XXXXXXX 100644 | 31 | index XXXXXXX..XXXXXXX 100644 |
18 | --- a/iothread.c | 32 | --- a/hw/remote/memory.c |
19 | +++ b/iothread.c | 33 | +++ b/hw/remote/memory.c |
20 | @@ -XXX,XX +XXX,XX @@ static void *iothread_run(void *opaque) | 34 | @@ -XXX,XX +XXX,XX @@ void remote_sysmem_reconfig(MPQemuMsg *msg, Error **errp) |
21 | qemu_sem_post(&iothread->init_done_sem); | 35 | |
22 | 36 | remote_sysmem_reset(); | |
23 | while (iothread->running) { | 37 | |
24 | + /* | 38 | - for (region = 0; region < msg->num_fds; region++) { |
25 | + * Note: from functional-wise the g_main_loop_run() below can | 39 | - g_autofree char *name; |
26 | + * already cover the aio_poll() events, but we can't run the | 40 | + for (region = 0; region < msg->num_fds; region++, suffix++) { |
27 | + * main loop unconditionally because explicit aio_poll() here | 41 | + g_autofree char *name = g_strdup_printf("remote-mem-%u", suffix); |
28 | + * is faster than g_main_loop_run() when we do not need the | 42 | subregion = g_new(MemoryRegion, 1); |
29 | + * gcontext at all (e.g., pure block layer iothreads). In | 43 | - name = g_strdup_printf("remote-mem-%u", suffix++); |
30 | + * other words, when we want to run the gcontext with the | 44 | memory_region_init_ram_from_fd(subregion, NULL, |
31 | + * iothread we need to pay some performance for functionality. | 45 | name, sysmem_info->sizes[region], |
32 | + */ | 46 | true, msg->fds[region], |
33 | aio_poll(iothread->ctx, true); | 47 | diff --git a/hw/remote/proxy.c b/hw/remote/proxy.c |
34 | 48 | index XXXXXXX..XXXXXXX 100644 | |
35 | /* | 49 | --- a/hw/remote/proxy.c |
50 | +++ b/hw/remote/proxy.c | ||
51 | @@ -XXX,XX +XXX,XX @@ static void probe_pci_info(PCIDevice *dev, Error **errp) | ||
52 | PCI_BASE_ADDRESS_SPACE_IO : PCI_BASE_ADDRESS_SPACE_MEMORY; | ||
53 | |||
54 | if (size) { | ||
55 | - g_autofree char *name; | ||
56 | + g_autofree char *name = g_strdup_printf("bar-region-%d", i); | ||
57 | pdev->region[i].dev = pdev; | ||
58 | pdev->region[i].present = true; | ||
59 | if (type == PCI_BASE_ADDRESS_SPACE_MEMORY) { | ||
60 | pdev->region[i].memory = true; | ||
61 | } | ||
62 | - name = g_strdup_printf("bar-region-%d", i); | ||
63 | memory_region_init_io(&pdev->region[i].mr, OBJECT(pdev), | ||
64 | &proxy_mr_ops, &pdev->region[i], | ||
65 | name, size); | ||
36 | -- | 66 | -- |
37 | 2.20.1 | 67 | 2.31.1 |
38 | 68 | ||
39 | diff view generated by jsdifflib |