1
The following changes since commit 22c5f446514a2a4bb0dbe1fea26713da92fc85fa:
1
The following changes since commit ca61fa4b803e5d0abaf6f1ceb690f23bb78a4def:
2
2
3
Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20190211' into staging (2019-02-11 17:04:57 +0000)
3
Merge remote-tracking branch 'remotes/quic/tags/pull-hex-20211006' into staging (2021-10-06 12:11:14 -0700)
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 9a6719d572e99a4e79f589d0b73f7475b86f982d:
9
for you to fetch changes up to 1cc7eada97914f090125e588497986f6f7900514:
10
10
11
virtio-blk: cleanup using VirtIOBlock *s and VirtIODevice *vdev (2019-02-12 11:49:17 +0800)
11
iothread: use IOThreadParamInfo in iothread_[set|get]_param() (2021-10-07 15:29:50 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Pull request
14
Pull request
15
15
16
----------------------------------------------------------------
16
----------------------------------------------------------------
17
17
18
Peter Xu (1):
18
Stefano Garzarella (2):
19
iothread: fix iothread hang when stop too soon
19
iothread: rename PollParamInfo to IOThreadParamInfo
20
iothread: use IOThreadParamInfo in iothread_[set|get]_param()
20
21
21
Stefano Garzarella (1):
22
iothread.c | 28 +++++++++++++++-------------
22
virtio-blk: cleanup using VirtIOBlock *s and VirtIODevice *vdev
23
1 file changed, 15 insertions(+), 13 deletions(-)
23
24
Vladimir Sementsov-Ogievskiy (1):
25
qemugdb/coroutine: fix arch_prctl has unknown return type
26
27
hw/block/virtio-blk.c | 22 +++++++++-------------
28
iothread.c | 6 +++++-
29
scripts/qemugdb/coroutine.py | 2 +-
30
3 files changed, 15 insertions(+), 15 deletions(-)
31
24
32
--
25
--
33
2.20.1
26
2.31.1
34
27
35
28
29
diff view generated by jsdifflib
1
From: Peter Xu <peterx@redhat.com>
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
2
3
Lukas reported an hard to reproduce QMP iothread hang on s390 that
3
Commit 1793ad0247 ("iothread: add aio-max-batch parameter") added
4
QEMU might hang at pthread_join() of the QMP monitor iothread before
4
a new parameter (aio-max-batch) to IOThread and used PollParamInfo
5
quitting:
5
structure to handle it.
6
6
7
Thread 1
7
Since it is not a parameter of the polling mechanism, we rename the
8
#0 0x000003ffad10932c in pthread_join
8
structure to a more generic IOThreadParamInfo.
9
#1 0x0000000109e95750 in qemu_thread_join
10
at /home/thuth/devel/qemu/util/qemu-thread-posix.c:570
11
#2 0x0000000109c95a1c in iothread_stop
12
#3 0x0000000109bb0874 in monitor_cleanup
13
#4 0x0000000109b55042 in main
14
9
15
While the iothread is still in the main loop:
10
Suggested-by: Kevin Wolf <kwolf@redhat.com>
16
11
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
17
Thread 4
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
18
#0 0x000003ffad0010e4 in ??
13
Message-id: 20210727145936.147032-2-sgarzare@redhat.com
19
#1 0x000003ffad553958 in g_main_context_iterate.isra.19
20
#2 0x000003ffad553d90 in g_main_loop_run
21
#3 0x0000000109c9585a in iothread_run
22
at /home/thuth/devel/qemu/iothread.c:74
23
#4 0x0000000109e94752 in qemu_thread_start
24
at /home/thuth/devel/qemu/util/qemu-thread-posix.c:502
25
#5 0x000003ffad10825a in start_thread
26
#6 0x000003ffad00dcf2 in thread_start
27
28
IMHO it's because there's a race between the main thread and iothread
29
when stopping the thread in following sequence:
30
31
main thread iothread
32
=========== ==============
33
aio_poll()
34
iothread_get_g_main_context
35
set iothread->worker_context
36
iothread_stop
37
schedule iothread_stop_bh
38
execute iothread_stop_bh [1]
39
set iothread->running=false
40
(since main_loop==NULL so
41
skip to quit main loop.
42
Note: although main_loop is
43
NULL but worker_context is
44
not!)
45
atomic_read(&iothread->worker_context) [2]
46
create main_loop object
47
g_main_loop_run() [3]
48
pthread_join() [4]
49
50
We can see that when execute iothread_stop_bh() at [1] it's possible
51
that main_loop is still NULL because it's only created until the first
52
check of the worker_context later at [2]. Then the iothread will hang
53
in the main loop [3] and it'll starve the main thread too [4].
54
55
Here the simple solution should be that we check again the "running"
56
variable before check against worker_context.
57
58
CC: Thomas Huth <thuth@redhat.com>
59
CC: Dr. David Alan Gilbert <dgilbert@redhat.com>
60
CC: Stefan Hajnoczi <stefanha@redhat.com>
61
CC: Lukáš Doktor <ldoktor@redhat.com>
62
CC: Markus Armbruster <armbru@redhat.com>
63
CC: Eric Blake <eblake@redhat.com>
64
CC: Paolo Bonzini <pbonzini@redhat.com>
65
Reported-by: Lukáš Doktor <ldoktor@redhat.com>
66
Signed-off-by: Peter Xu <peterx@redhat.com>
67
Tested-by: Thomas Huth <thuth@redhat.com>
68
Message-id: 20190129051432.22023-1-peterx@redhat.com
69
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
14
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
70
---
15
---
71
iothread.c | 6 +++++-
16
iothread.c | 14 +++++++-------
72
1 file changed, 5 insertions(+), 1 deletion(-)
17
1 file changed, 7 insertions(+), 7 deletions(-)
73
18
74
diff --git a/iothread.c b/iothread.c
19
diff --git a/iothread.c b/iothread.c
75
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
76
--- a/iothread.c
21
--- a/iothread.c
77
+++ b/iothread.c
22
+++ b/iothread.c
78
@@ -XXX,XX +XXX,XX @@ static void *iothread_run(void *opaque)
23
@@ -XXX,XX +XXX,XX @@ static void iothread_complete(UserCreatable *obj, Error **errp)
79
while (iothread->running) {
24
typedef struct {
80
aio_poll(iothread->ctx, true);
25
const char *name;
81
26
ptrdiff_t offset; /* field's byte offset in IOThread struct */
82
- if (atomic_read(&iothread->worker_context)) {
27
-} PollParamInfo;
83
+ /*
28
+} IOThreadParamInfo;
84
+ * We must check the running state again in case it was
29
85
+ * changed in previous aio_poll()
30
-static PollParamInfo poll_max_ns_info = {
86
+ */
31
+static IOThreadParamInfo poll_max_ns_info = {
87
+ if (iothread->running && atomic_read(&iothread->worker_context)) {
32
"poll-max-ns", offsetof(IOThread, poll_max_ns),
88
GMainLoop *loop;
33
};
89
34
-static PollParamInfo poll_grow_info = {
90
g_main_context_push_thread_default(iothread->worker_context);
35
+static IOThreadParamInfo poll_grow_info = {
36
"poll-grow", offsetof(IOThread, poll_grow),
37
};
38
-static PollParamInfo poll_shrink_info = {
39
+static IOThreadParamInfo poll_shrink_info = {
40
"poll-shrink", offsetof(IOThread, poll_shrink),
41
};
42
-static PollParamInfo aio_max_batch_info = {
43
+static IOThreadParamInfo aio_max_batch_info = {
44
"aio-max-batch", offsetof(IOThread, aio_max_batch),
45
};
46
47
@@ -XXX,XX +XXX,XX @@ static void iothread_get_param(Object *obj, Visitor *v,
48
const char *name, void *opaque, Error **errp)
49
{
50
IOThread *iothread = IOTHREAD(obj);
51
- PollParamInfo *info = opaque;
52
+ IOThreadParamInfo *info = opaque;
53
int64_t *field = (void *)iothread + info->offset;
54
55
visit_type_int64(v, name, field, errp);
56
@@ -XXX,XX +XXX,XX @@ static bool iothread_set_param(Object *obj, Visitor *v,
57
const char *name, void *opaque, Error **errp)
58
{
59
IOThread *iothread = IOTHREAD(obj);
60
- PollParamInfo *info = opaque;
61
+ IOThreadParamInfo *info = opaque;
62
int64_t *field = (void *)iothread + info->offset;
63
int64_t value;
64
91
--
65
--
92
2.20.1
66
2.31.1
93
67
94
68
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
qemu coroutine command results in following error output:
4
5
Python Exception <class 'gdb.error'> 'arch_prctl' has unknown return
6
type; cast the call to its declared return type: Error occurred in
7
Python command: 'arch_prctl' has unknown return type; cast the call to
8
its declared return type
9
10
Fix it by giving it what it wants: arch_prctl return type.
11
12
Information on the topic:
13
https://sourceware.org/gdb/onlinedocs/gdb/Calling.html
14
15
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
16
Message-id: 20190206151425.105871-1-vsementsov@virtuozzo.com
17
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
18
---
19
scripts/qemugdb/coroutine.py | 2 +-
20
1 file changed, 1 insertion(+), 1 deletion(-)
21
22
diff --git a/scripts/qemugdb/coroutine.py b/scripts/qemugdb/coroutine.py
23
index XXXXXXX..XXXXXXX 100644
24
--- a/scripts/qemugdb/coroutine.py
25
+++ b/scripts/qemugdb/coroutine.py
26
@@ -XXX,XX +XXX,XX @@ def get_fs_base():
27
pthread_self().'''
28
# %rsp - 120 is scratch space according to the SystemV ABI
29
old = gdb.parse_and_eval('*(uint64_t*)($rsp - 120)')
30
- gdb.execute('call arch_prctl(0x1003, $rsp - 120)', False, True)
31
+ gdb.execute('call (int)arch_prctl(0x1003, $rsp - 120)', False, True)
32
fs_base = gdb.parse_and_eval('*(uint64_t*)($rsp - 120)')
33
gdb.execute('set *(uint64_t*)($rsp - 120) = %s' % old, False, True)
34
return fs_base
35
--
36
2.20.1
37
38
diff view generated by jsdifflib
1
From: Stefano Garzarella <sgarzare@redhat.com>
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
2
3
In several part we still using req->dev or VIRTIO_DEVICE(req->dev)
3
Commit 0445409d74 ("iothread: generalize
4
when we have already defined s and vdev pointers:
4
iothread_set_param/iothread_get_param") moved common code to set and
5
VirtIOBlock *s = req->dev;
5
get IOThread parameters in two new functions.
6
VirtIODevice *vdev = VIRTIO_DEVICE(s);
7
6
7
These functions are called inside callbacks, so we don't need to use an
8
opaque pointer. Let's replace `void *opaque` parameter with
9
`IOThreadParamInfo *info`.
10
11
Suggested-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
12
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
9
Reviewed-by: Liam Merwick <liam.merwick@oracle.com>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Message-id: 20190208142347.214815-1-sgarzare@redhat.com
14
Message-id: 20210727145936.147032-3-sgarzare@redhat.com
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
15
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
16
---
13
hw/block/virtio-blk.c | 22 +++++++++-------------
17
iothread.c | 18 ++++++++++--------
14
1 file changed, 9 insertions(+), 13 deletions(-)
18
1 file changed, 10 insertions(+), 8 deletions(-)
15
19
16
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
20
diff --git a/iothread.c b/iothread.c
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/block/virtio-blk.c
22
--- a/iothread.c
19
+++ b/hw/block/virtio-blk.c
23
+++ b/iothread.c
20
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status)
24
@@ -XXX,XX +XXX,XX @@ static IOThreadParamInfo aio_max_batch_info = {
21
static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
25
};
22
bool is_read)
26
27
static void iothread_get_param(Object *obj, Visitor *v,
28
- const char *name, void *opaque, Error **errp)
29
+ const char *name, IOThreadParamInfo *info, Error **errp)
23
{
30
{
24
- BlockErrorAction action = blk_get_error_action(req->dev->blk,
31
IOThread *iothread = IOTHREAD(obj);
25
- is_read, error);
32
- IOThreadParamInfo *info = opaque;
26
VirtIOBlock *s = req->dev;
33
int64_t *field = (void *)iothread + info->offset;
27
+ BlockErrorAction action = blk_get_error_action(s->blk, is_read, error);
34
28
35
visit_type_int64(v, name, field, errp);
29
if (action == BLOCK_ERROR_ACTION_STOP) {
36
}
30
/* Break the link as the next request is going to be parsed from the
37
31
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_flush_complete(void *opaque, int ret)
38
static bool iothread_set_param(Object *obj, Visitor *v,
39
- const char *name, void *opaque, Error **errp)
40
+ const char *name, IOThreadParamInfo *info, Error **errp)
41
{
42
IOThread *iothread = IOTHREAD(obj);
43
- IOThreadParamInfo *info = opaque;
44
int64_t *field = (void *)iothread + info->offset;
45
int64_t value;
46
47
@@ -XXX,XX +XXX,XX @@ static bool iothread_set_param(Object *obj, Visitor *v,
48
static void iothread_get_poll_param(Object *obj, Visitor *v,
49
const char *name, void *opaque, Error **errp)
50
{
51
+ IOThreadParamInfo *info = opaque;
52
53
- iothread_get_param(obj, v, name, opaque, errp);
54
+ iothread_get_param(obj, v, name, info, errp);
55
}
56
57
static void iothread_set_poll_param(Object *obj, Visitor *v,
58
const char *name, void *opaque, Error **errp)
59
{
60
IOThread *iothread = IOTHREAD(obj);
61
+ IOThreadParamInfo *info = opaque;
62
63
- if (!iothread_set_param(obj, v, name, opaque, errp)) {
64
+ if (!iothread_set_param(obj, v, name, info, errp)) {
65
return;
32
}
66
}
33
67
34
virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
68
@@ -XXX,XX +XXX,XX @@ static void iothread_set_poll_param(Object *obj, Visitor *v,
35
- block_acct_done(blk_get_stats(req->dev->blk), &req->acct);
69
static void iothread_get_aio_param(Object *obj, Visitor *v,
36
+ block_acct_done(blk_get_stats(s->blk), &req->acct);
70
const char *name, void *opaque, Error **errp)
37
virtio_blk_free_request(req);
71
{
38
72
+ IOThreadParamInfo *info = opaque;
39
out:
73
40
@@ -XXX,XX +XXX,XX @@ static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
74
- iothread_get_param(obj, v, name, opaque, errp);
41
- sizeof(struct virtio_blk_inhdr);
75
+ iothread_get_param(obj, v, name, info, errp);
42
iov_discard_back(in_iov, &in_num, sizeof(struct virtio_blk_inhdr));
76
}
43
77
44
- type = virtio_ldl_p(VIRTIO_DEVICE(req->dev), &req->out.type);
78
static void iothread_set_aio_param(Object *obj, Visitor *v,
45
+ type = virtio_ldl_p(vdev, &req->out.type);
79
const char *name, void *opaque, Error **errp)
46
80
{
47
/* VIRTIO_BLK_T_OUT defines the command direction. VIRTIO_BLK_T_BARRIER
81
IOThread *iothread = IOTHREAD(obj);
48
* is an optional flag. Although a guest should not send this flag if
82
+ IOThreadParamInfo *info = opaque;
49
@@ -XXX,XX +XXX,XX @@ static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
83
50
case VIRTIO_BLK_T_IN:
84
- if (!iothread_set_param(obj, v, name, opaque, errp)) {
51
{
85
+ if (!iothread_set_param(obj, v, name, info, errp)) {
52
bool is_write = type & VIRTIO_BLK_T_OUT;
86
return;
53
- req->sector_num = virtio_ldq_p(VIRTIO_DEVICE(req->dev),
87
}
54
- &req->out.sector);
88
55
+ req->sector_num = virtio_ldq_p(vdev, &req->out.sector);
56
57
if (is_write) {
58
qemu_iovec_init_external(&req->qiov, out_iov, out_num);
59
@@ -XXX,XX +XXX,XX @@ static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
60
req->qiov.size / BDRV_SECTOR_SIZE);
61
}
62
63
- if (!virtio_blk_sect_range_ok(req->dev, req->sector_num,
64
- req->qiov.size)) {
65
+ if (!virtio_blk_sect_range_ok(s, req->sector_num, req->qiov.size)) {
66
virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
67
- block_acct_invalid(blk_get_stats(req->dev->blk),
68
+ block_acct_invalid(blk_get_stats(s->blk),
69
is_write ? BLOCK_ACCT_WRITE : BLOCK_ACCT_READ);
70
virtio_blk_free_request(req);
71
return 0;
72
}
73
74
- block_acct_start(blk_get_stats(req->dev->blk),
75
- &req->acct, req->qiov.size,
76
+ block_acct_start(blk_get_stats(s->blk), &req->acct, req->qiov.size,
77
is_write ? BLOCK_ACCT_WRITE : BLOCK_ACCT_READ);
78
79
/* merge would exceed maximum number of requests or IO direction
80
* changes */
81
if (mrb->num_reqs > 0 && (mrb->num_reqs == VIRTIO_BLK_MAX_MERGE_REQS ||
82
is_write != mrb->is_write ||
83
- !req->dev->conf.request_merging)) {
84
- virtio_blk_submit_multireq(req->dev->blk, mrb);
85
+ !s->conf.request_merging)) {
86
+ virtio_blk_submit_multireq(s->blk, mrb);
87
}
88
89
assert(mrb->num_reqs < VIRTIO_BLK_MAX_MERGE_REQS);
90
--
89
--
91
2.20.1
90
2.31.1
92
91
93
92
diff view generated by jsdifflib