1
The following changes since commit 55a19ad8b2d0797e3a8fe90ab99a9bb713824059:
1
The following changes since commit ca61fa4b803e5d0abaf6f1ceb690f23bb78a4def:
2
2
3
Update version for v2.9.0-rc1 release (2017-03-21 17:13:29 +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
https://github.com/codyprime/qemu-kvm-jtc.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 600ac6a0ef5c06418446ef2f37407bddcc51b21c:
9
for you to fetch changes up to 1cc7eada97914f090125e588497986f6f7900514:
10
10
11
blockjob: add devops to blockjob backends (2017-03-22 13:26:27 -0400)
11
iothread: use IOThreadParamInfo in iothread_[set|get]_param() (2021-10-07 15:29:50 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block patches for 2.9
14
Pull request
15
15
----------------------------------------------------------------
16
----------------------------------------------------------------
16
17
17
John Snow (3):
18
Stefano Garzarella (2):
18
blockjob: add block_job_start_shim
19
iothread: rename PollParamInfo to IOThreadParamInfo
19
block-backend: add drained_begin / drained_end ops
20
iothread: use IOThreadParamInfo in iothread_[set|get]_param()
20
blockjob: add devops to blockjob backends
21
21
22
Paolo Bonzini (1):
22
iothread.c | 28 +++++++++++++++-------------
23
blockjob: avoid recursive AioContext locking
23
1 file changed, 15 insertions(+), 13 deletions(-)
24
25
block/block-backend.c | 24 ++++++++++++++--
26
blockjob.c | 63 ++++++++++++++++++++++++++++++++----------
27
include/sysemu/block-backend.h | 8 ++++++
28
3 files changed, 79 insertions(+), 16 deletions(-)
29
24
30
--
25
--
31
2.9.3
26
2.31.1
32
27
33
28
29
diff view generated by jsdifflib
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
2
3
Streaming or any other block job hangs when performed on a block device
3
Commit 1793ad0247 ("iothread: add aio-max-batch parameter") added
4
that has a non-default iothread. This happens because the AioContext
4
a new parameter (aio-max-batch) to IOThread and used PollParamInfo
5
is acquired twice by block_job_defer_to_main_loop_bh and then released
5
structure to handle it.
6
only once by BDRV_POLL_WHILE. (Insert rants on recursive mutexes, which
7
unfortunately are a temporary but necessary evil for iothreads at the
8
moment).
9
6
10
Luckily, the reason for the double acquisition is simple; the function
7
Since it is not a parameter of the polling mechanism, we rename the
11
acquires the AioContext for both the job iothread and the BDS iothread,
8
structure to a more generic IOThreadParamInfo.
12
in case the BDS iothread was changed while the job was running. It
13
is therefore enough to skip the second acquisition when the two
14
AioContexts are one and the same.
15
9
16
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
10
Suggested-by: Kevin Wolf <kwolf@redhat.com>
17
Reviewed-by: Eric Blake <eblake@redhat.com>
11
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
18
Reviewed-by: Jeff Cody <jcody@redhat.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
19
Message-id: 1490118490-5597-1-git-send-email-pbonzini@redhat.com
13
Message-id: 20210727145936.147032-2-sgarzare@redhat.com
20
Signed-off-by: Jeff Cody <jcody@redhat.com>
14
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
21
---
15
---
22
blockjob.c | 8 ++++++--
16
iothread.c | 14 +++++++-------
23
1 file changed, 6 insertions(+), 2 deletions(-)
17
1 file changed, 7 insertions(+), 7 deletions(-)
24
18
25
diff --git a/blockjob.c b/blockjob.c
19
diff --git a/iothread.c b/iothread.c
26
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
27
--- a/blockjob.c
21
--- a/iothread.c
28
+++ b/blockjob.c
22
+++ b/iothread.c
29
@@ -XXX,XX +XXX,XX @@ static void block_job_defer_to_main_loop_bh(void *opaque)
23
@@ -XXX,XX +XXX,XX @@ static void iothread_complete(UserCreatable *obj, Error **errp)
30
24
typedef struct {
31
/* Fetch BDS AioContext again, in case it has changed */
25
const char *name;
32
aio_context = blk_get_aio_context(data->job->blk);
26
ptrdiff_t offset; /* field's byte offset in IOThread struct */
33
- aio_context_acquire(aio_context);
27
-} PollParamInfo;
34
+ if (aio_context != data->aio_context) {
28
+} IOThreadParamInfo;
35
+ aio_context_acquire(aio_context);
29
36
+ }
30
-static PollParamInfo poll_max_ns_info = {
37
31
+static IOThreadParamInfo poll_max_ns_info = {
38
data->job->deferred_to_main_loop = false;
32
"poll-max-ns", offsetof(IOThread, poll_max_ns),
39
data->fn(data->job, data->opaque);
33
};
40
34
-static PollParamInfo poll_grow_info = {
41
- aio_context_release(aio_context);
35
+static IOThreadParamInfo poll_grow_info = {
42
+ if (aio_context != data->aio_context) {
36
"poll-grow", offsetof(IOThread, poll_grow),
43
+ aio_context_release(aio_context);
37
};
44
+ }
38
-static PollParamInfo poll_shrink_info = {
45
39
+static IOThreadParamInfo poll_shrink_info = {
46
aio_context_release(data->aio_context);
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;
47
64
48
--
65
--
49
2.9.3
66
2.31.1
50
67
51
68
diff view generated by jsdifflib
Deleted patch
1
From: John Snow <jsnow@redhat.com>
2
1
3
The purpose of this shim is to allow us to pause pre-started jobs.
4
The purpose of *that* is to allow us to buffer a pause request that
5
will be able to take effect before the job ever does any work, allowing
6
us to create jobs during a quiescent state (under which they will be
7
automatically paused), then resuming the jobs after the critical section
8
in any order, either:
9
10
(1) -block_job_start
11
-block_job_resume (via e.g. drained_end)
12
13
(2) -block_job_resume (via e.g. drained_end)
14
-block_job_start
15
16
The problem that requires a startup wrapper is the idea that a job must
17
start in the busy=true state only its first time-- all subsequent entries
18
require busy to be false, and the toggling of this state is otherwise
19
handled during existing pause and yield points.
20
21
The wrapper simply allows us to mandate that a job can "start," set busy
22
to true, then immediately pause only if necessary. We could avoid
23
requiring a wrapper, but all jobs would need to do it, so it's been
24
factored out here.
25
26
Signed-off-by: John Snow <jsnow@redhat.com>
27
Reviewed-by: Jeff Cody <jcody@redhat.com>
28
Message-id: 20170316212351.13797-2-jsnow@redhat.com
29
Signed-off-by: Jeff Cody <jcody@redhat.com>
30
---
31
blockjob.c | 26 +++++++++++++++++++-------
32
1 file changed, 19 insertions(+), 7 deletions(-)
33
34
diff --git a/blockjob.c b/blockjob.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/blockjob.c
37
+++ b/blockjob.c
38
@@ -XXX,XX +XXX,XX @@ static bool block_job_started(BlockJob *job)
39
return job->co;
40
}
41
42
+/**
43
+ * All jobs must allow a pause point before entering their job proper. This
44
+ * ensures that jobs can be paused prior to being started, then resumed later.
45
+ */
46
+static void coroutine_fn block_job_co_entry(void *opaque)
47
+{
48
+ BlockJob *job = opaque;
49
+
50
+ assert(job && job->driver && job->driver->start);
51
+ block_job_pause_point(job);
52
+ job->driver->start(job);
53
+}
54
+
55
void block_job_start(BlockJob *job)
56
{
57
assert(job && !block_job_started(job) && job->paused &&
58
- !job->busy && job->driver->start);
59
- job->co = qemu_coroutine_create(job->driver->start, job);
60
- if (--job->pause_count == 0) {
61
- job->paused = false;
62
- job->busy = true;
63
- qemu_coroutine_enter(job->co);
64
- }
65
+ job->driver && job->driver->start);
66
+ job->co = qemu_coroutine_create(block_job_co_entry, job);
67
+ job->pause_count--;
68
+ job->busy = true;
69
+ job->paused = false;
70
+ qemu_coroutine_enter(job->co);
71
}
72
73
void block_job_ref(BlockJob *job)
74
--
75
2.9.3
76
77
diff view generated by jsdifflib
Deleted patch
1
From: John Snow <jsnow@redhat.com>
2
1
3
Allow block backends to forward drain requests to their devices/users.
4
The initial intended purpose for this patch is to allow BBs to forward
5
requests along to BlockJobs, which will want to pause if their associated
6
BB has entered a drained region.
7
8
Signed-off-by: John Snow <jsnow@redhat.com>
9
Reviewed-by: Jeff Cody <jcody@redhat.com>
10
Message-id: 20170316212351.13797-3-jsnow@redhat.com
11
Signed-off-by: Jeff Cody <jcody@redhat.com>
12
---
13
block/block-backend.c | 24 ++++++++++++++++++++++--
14
include/sysemu/block-backend.h | 8 ++++++++
15
2 files changed, 30 insertions(+), 2 deletions(-)
16
17
diff --git a/block/block-backend.c b/block/block-backend.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block/block-backend.c
20
+++ b/block/block-backend.c
21
@@ -XXX,XX +XXX,XX @@ struct BlockBackend {
22
bool allow_write_beyond_eof;
23
24
NotifierList remove_bs_notifiers, insert_bs_notifiers;
25
+
26
+ int quiesce_counter;
27
};
28
29
typedef struct BlockBackendAIOCB {
30
@@ -XXX,XX +XXX,XX @@ void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops,
31
void *opaque)
32
{
33
/* All drivers that use blk_set_dev_ops() are qdevified and we want to keep
34
- * it that way, so we can assume blk->dev is a DeviceState if blk->dev_ops
35
- * is set. */
36
+ * it that way, so we can assume blk->dev, if present, is a DeviceState if
37
+ * blk->dev_ops is set. Non-device users may use dev_ops without device. */
38
assert(!blk->legacy_dev);
39
40
blk->dev_ops = ops;
41
blk->dev_opaque = opaque;
42
+
43
+ /* Are we currently quiesced? Should we enforce this right now? */
44
+ if (blk->quiesce_counter && ops->drained_begin) {
45
+ ops->drained_begin(opaque);
46
+ }
47
}
48
49
/*
50
@@ -XXX,XX +XXX,XX @@ static void blk_root_drained_begin(BdrvChild *child)
51
{
52
BlockBackend *blk = child->opaque;
53
54
+ if (++blk->quiesce_counter == 1) {
55
+ if (blk->dev_ops && blk->dev_ops->drained_begin) {
56
+ blk->dev_ops->drained_begin(blk->dev_opaque);
57
+ }
58
+ }
59
+
60
/* Note that blk->root may not be accessible here yet if we are just
61
* attaching to a BlockDriverState that is drained. Use child instead. */
62
63
@@ -XXX,XX +XXX,XX @@ static void blk_root_drained_begin(BdrvChild *child)
64
static void blk_root_drained_end(BdrvChild *child)
65
{
66
BlockBackend *blk = child->opaque;
67
+ assert(blk->quiesce_counter);
68
69
assert(blk->public.io_limits_disabled);
70
--blk->public.io_limits_disabled;
71
+
72
+ if (--blk->quiesce_counter == 0) {
73
+ if (blk->dev_ops && blk->dev_ops->drained_end) {
74
+ blk->dev_ops->drained_end(blk->dev_opaque);
75
+ }
76
+ }
77
}
78
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
79
index XXXXXXX..XXXXXXX 100644
80
--- a/include/sysemu/block-backend.h
81
+++ b/include/sysemu/block-backend.h
82
@@ -XXX,XX +XXX,XX @@ typedef struct BlockDevOps {
83
* Runs when the size changed (e.g. monitor command block_resize)
84
*/
85
void (*resize_cb)(void *opaque);
86
+ /*
87
+ * Runs when the backend receives a drain request.
88
+ */
89
+ void (*drained_begin)(void *opaque);
90
+ /*
91
+ * Runs when the backend's last drain request ends.
92
+ */
93
+ void (*drained_end)(void *opaque);
94
} BlockDevOps;
95
96
/* This struct is embedded in (the private) BlockBackend struct and contains
97
--
98
2.9.3
99
100
diff view generated by jsdifflib
1
From: John Snow <jsnow@redhat.com>
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
2
3
This lets us hook into drained_begin and drained_end requests from the
3
Commit 0445409d74 ("iothread: generalize
4
backend level, which is particularly useful for making sure that all
4
iothread_set_param/iothread_get_param") moved common code to set and
5
jobs associated with a particular node (whether the source or the target)
5
get IOThread parameters in two new functions.
6
receive a drain request.
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`.
7
10
8
Suggested-by: Kevin Wolf <kwolf@redhat.com>
11
Suggested-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: John Snow <jsnow@redhat.com>
12
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
10
Reviewed-by: Jeff Cody <jcody@redhat.com>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Message-id: 20170316212351.13797-4-jsnow@redhat.com
14
Message-id: 20210727145936.147032-3-sgarzare@redhat.com
12
Signed-off-by: Jeff Cody <jcody@redhat.com>
15
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
---
16
---
14
blockjob.c | 29 ++++++++++++++++++++++++-----
17
iothread.c | 18 ++++++++++--------
15
1 file changed, 24 insertions(+), 5 deletions(-)
18
1 file changed, 10 insertions(+), 8 deletions(-)
16
19
17
diff --git a/blockjob.c b/blockjob.c
20
diff --git a/iothread.c b/iothread.c
18
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
19
--- a/blockjob.c
22
--- a/iothread.c
20
+++ b/blockjob.c
23
+++ b/iothread.c
21
@@ -XXX,XX +XXX,XX @@ static const BdrvChildRole child_job = {
24
@@ -XXX,XX +XXX,XX @@ static IOThreadParamInfo aio_max_batch_info = {
22
.stay_at_node = true,
23
};
25
};
24
26
25
+static void block_job_drained_begin(void *opaque)
27
static void iothread_get_param(Object *obj, Visitor *v,
26
+{
28
- const char *name, void *opaque, Error **errp)
27
+ BlockJob *job = opaque;
29
+ const char *name, IOThreadParamInfo *info, Error **errp)
28
+ block_job_pause(job);
29
+}
30
+
31
+static void block_job_drained_end(void *opaque)
32
+{
33
+ BlockJob *job = opaque;
34
+ block_job_resume(job);
35
+}
36
+
37
+static const BlockDevOps block_job_dev_ops = {
38
+ .drained_begin = block_job_drained_begin,
39
+ .drained_end = block_job_drained_end,
40
+};
41
+
42
BlockJob *block_job_next(BlockJob *job)
43
{
30
{
44
if (!job) {
31
IOThread *iothread = IOTHREAD(obj);
45
@@ -XXX,XX +XXX,XX @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
32
- IOThreadParamInfo *info = opaque;
33
int64_t *field = (void *)iothread + info->offset;
34
35
visit_type_int64(v, name, field, errp);
36
}
37
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;
46
}
66
}
47
67
48
job = g_malloc0(driver->instance_size);
68
@@ -XXX,XX +XXX,XX @@ static void iothread_set_poll_param(Object *obj, Visitor *v,
49
- error_setg(&job->blocker, "block device is in use by block job: %s",
69
static void iothread_get_aio_param(Object *obj, Visitor *v,
50
- BlockJobType_lookup[driver->job_type]);
70
const char *name, void *opaque, Error **errp)
51
- block_job_add_bdrv(job, "main node", bs, 0, BLK_PERM_ALL, &error_abort);
71
{
52
- bdrv_op_unblock(bs, BLOCK_OP_TYPE_DATAPLANE, job->blocker);
72
+ IOThreadParamInfo *info = opaque;
53
-
73
54
job->driver = driver;
74
- iothread_get_param(obj, v, name, opaque, errp);
55
job->id = g_strdup(job_id);
75
+ iothread_get_param(obj, v, name, info, errp);
56
job->blk = blk;
76
}
57
@@ -XXX,XX +XXX,XX @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
77
58
job->paused = true;
78
static void iothread_set_aio_param(Object *obj, Visitor *v,
59
job->pause_count = 1;
79
const char *name, void *opaque, Error **errp)
60
job->refcnt = 1;
80
{
61
+
81
IOThread *iothread = IOTHREAD(obj);
62
+ error_setg(&job->blocker, "block device is in use by block job: %s",
82
+ IOThreadParamInfo *info = opaque;
63
+ BlockJobType_lookup[driver->job_type]);
83
64
+ block_job_add_bdrv(job, "main node", bs, 0, BLK_PERM_ALL, &error_abort);
84
- if (!iothread_set_param(obj, v, name, opaque, errp)) {
65
bs->job = job;
85
+ if (!iothread_set_param(obj, v, name, info, errp)) {
66
86
return;
67
+ blk_set_dev_ops(blk, &block_job_dev_ops, job);
87
}
68
+ bdrv_op_unblock(bs, BLOCK_OP_TYPE_DATAPLANE, job->blocker);
88
69
+
70
QLIST_INSERT_HEAD(&block_jobs, job, job_list);
71
72
blk_add_aio_context_notifier(blk, block_job_attached_aio_context,
73
--
89
--
74
2.9.3
90
2.31.1
75
91
76
92
diff view generated by jsdifflib