1
The following changes since commit f90ea7ba7c5ae7010ee0ce062207ae42530f57d6:
1
The following changes since commit 3521ade3510eb5cefb2e27a101667f25dad89935:
2
2
3
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20171012' into staging (2017-10-12 17:06:50 +0100)
3
Merge remote-tracking branch 'remotes/thuth-gitlab/tags/pull-request-2021-07-29' into staging (2021-07-29 13:17:20 +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 b867eaa17b3940760f51134e409cb0580dd3dde3:
9
for you to fetch changes up to cc8eecd7f105a1dff5876adeb238a14696061a4a:
10
10
11
block/throttle.c: add bdrv_co_drain_begin/end callbacks (2017-10-13 12:38:41 +0100)
11
MAINTAINERS: Added myself as a reviewer for the NVMe Block Driver (2021-07-29 17:17:34 +0100)
12
13
----------------------------------------------------------------
14
Pull request
15
16
The main fix here is for io_uring. Spurious -EAGAIN errors can happen and the
17
request needs to be resubmitted.
18
19
The MAINTAINERS changes carry no risk and we might as well include them in QEMU
20
6.1.
12
21
13
----------------------------------------------------------------
22
----------------------------------------------------------------
14
23
15
----------------------------------------------------------------
24
Fabian Ebner (1):
25
block/io_uring: resubmit when result is -EAGAIN
16
26
17
Manos Pitsidianakis (3):
27
Philippe Mathieu-Daudé (1):
18
block: add bdrv_co_drain_end callback
28
MAINTAINERS: Added myself as a reviewer for the NVMe Block Driver
19
block: rename bdrv_co_drain to bdrv_co_drain_begin
20
block/throttle.c: add bdrv_co_drain_begin/end callbacks
21
29
22
include/block/block_int.h | 13 ++++++++++---
30
Stefano Garzarella (1):
23
block/io.c | 48 +++++++++++++++++++++++++++++++++--------------
31
MAINTAINERS: add Stefano Garzarella as io_uring reviewer
24
block/qed.c | 6 +++---
32
25
block/throttle.c | 18 ++++++++++++++++++
33
MAINTAINERS | 2 ++
26
4 files changed, 65 insertions(+), 20 deletions(-)
34
block/io_uring.c | 16 +++++++++++++++-
35
2 files changed, 17 insertions(+), 1 deletion(-)
27
36
28
--
37
--
29
2.13.6
38
2.31.1
30
39
31
diff view generated by jsdifflib
1
From: Manos Pitsidianakis <el13635@mail.ntua.gr>
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
2
3
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
3
I've been working with io_uring for a while so I'd like to help
4
Reviewed-by: Fam Zheng <famz@redhat.com>
4
with reviews.
5
Signed-off-by: Manos Pitsidianakis <el13635@mail.ntua.gr>
5
6
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
7
Message-Id: <20210728131515.131045-1-sgarzare@redhat.com>
6
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
7
---
9
---
8
block/throttle.c | 18 ++++++++++++++++++
10
MAINTAINERS | 1 +
9
1 file changed, 18 insertions(+)
11
1 file changed, 1 insertion(+)
10
12
11
diff --git a/block/throttle.c b/block/throttle.c
13
diff --git a/MAINTAINERS b/MAINTAINERS
12
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
13
--- a/block/throttle.c
15
--- a/MAINTAINERS
14
+++ b/block/throttle.c
16
+++ b/MAINTAINERS
15
@@ -XXX,XX +XXX,XX @@ static bool throttle_recurse_is_first_non_filter(BlockDriverState *bs,
17
@@ -XXX,XX +XXX,XX @@ Linux io_uring
16
return bdrv_recurse_is_first_non_filter(bs->file->bs, candidate);
18
M: Aarushi Mehta <mehta.aaru20@gmail.com>
17
}
19
M: Julia Suvorova <jusual@redhat.com>
18
20
M: Stefan Hajnoczi <stefanha@redhat.com>
19
+static void coroutine_fn throttle_co_drain_begin(BlockDriverState *bs)
21
+R: Stefano Garzarella <sgarzare@redhat.com>
20
+{
22
L: qemu-block@nongnu.org
21
+ ThrottleGroupMember *tgm = bs->opaque;
23
S: Maintained
22
+ if (atomic_fetch_inc(&tgm->io_limits_disabled) == 0) {
24
F: block/io_uring.c
23
+ throttle_group_restart_tgm(tgm);
24
+ }
25
+}
26
+
27
+static void coroutine_fn throttle_co_drain_end(BlockDriverState *bs)
28
+{
29
+ ThrottleGroupMember *tgm = bs->opaque;
30
+ assert(tgm->io_limits_disabled);
31
+ atomic_dec(&tgm->io_limits_disabled);
32
+}
33
+
34
static BlockDriver bdrv_throttle = {
35
.format_name = "throttle",
36
.protocol_name = "throttle",
37
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_throttle = {
38
.bdrv_reopen_abort = throttle_reopen_abort,
39
.bdrv_co_get_block_status = bdrv_co_get_block_status_from_file,
40
41
+ .bdrv_co_drain_begin = throttle_co_drain_begin,
42
+ .bdrv_co_drain_end = throttle_co_drain_end,
43
+
44
.is_filter = true,
45
};
46
47
--
25
--
48
2.13.6
26
2.31.1
49
27
50
diff view generated by jsdifflib
1
From: Manos Pitsidianakis <el13635@mail.ntua.gr>
1
From: Fabian Ebner <f.ebner@proxmox.com>
2
2
3
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
3
Linux SCSI can throw spurious -EAGAIN in some corner cases in its
4
Reviewed-by: Fam Zheng <famz@redhat.com>
4
completion path, which will end up being the result in the completed
5
Signed-off-by: Manos Pitsidianakis <el13635@mail.ntua.gr>
5
io_uring request.
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
6
7
Resubmitting such requests should allow block jobs to complete, even
8
if such spurious errors are encountered.
9
10
Co-authored-by: Stefan Hajnoczi <stefanha@gmail.com>
11
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
12
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
13
Message-id: 20210729091029.65369-1-f.ebner@proxmox.com
7
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
14
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
8
---
15
---
9
include/block/block_int.h | 4 ++--
16
block/io_uring.c | 16 +++++++++++++++-
10
block/io.c | 4 ++--
17
1 file changed, 15 insertions(+), 1 deletion(-)
11
block/qed.c | 6 +++---
12
3 files changed, 7 insertions(+), 7 deletions(-)
13
18
14
diff --git a/include/block/block_int.h b/include/block/block_int.h
19
diff --git a/block/io_uring.c b/block/io_uring.c
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/include/block/block_int.h
21
--- a/block/io_uring.c
17
+++ b/include/block/block_int.h
22
+++ b/block/io_uring.c
18
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
23
@@ -XXX,XX +XXX,XX @@ static void luring_process_completions(LuringState *s)
19
int (*bdrv_probe_geometry)(BlockDriverState *bs, HDGeometry *geo);
24
total_bytes = ret + luringcb->total_read;
20
25
21
/**
26
if (ret < 0) {
22
- * bdrv_co_drain is called if implemented in the beginning of a
27
- if (ret == -EINTR) {
23
+ * bdrv_co_drain_begin is called if implemented in the beginning of a
28
+ /*
24
* drain operation to drain and stop any internal sources of requests in
29
+ * Only writev/readv/fsync requests on regular files or host block
25
* the driver.
30
+ * devices are submitted. Therefore -EAGAIN is not expected but it's
26
* bdrv_co_drain_end is called if implemented at the end of the drain.
31
+ * known to happen sometimes with Linux SCSI. Submit again and hope
27
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
32
+ * the request completes successfully.
28
* requests, or toggle an internal state. After the end of the drain new
33
+ *
29
* requests will continue normally.
34
+ * For more information, see:
30
*/
35
+ * https://lore.kernel.org/io-uring/20210727165811.284510-3-axboe@kernel.dk/T/#u
31
- void coroutine_fn (*bdrv_co_drain)(BlockDriverState *bs);
36
+ *
32
+ void coroutine_fn (*bdrv_co_drain_begin)(BlockDriverState *bs);
37
+ * If the code is changed to submit other types of requests in the
33
void coroutine_fn (*bdrv_co_drain_end)(BlockDriverState *bs);
38
+ * future, then this workaround may need to be extended to deal with
34
39
+ * genuine -EAGAIN results that should not be resubmitted
35
void (*bdrv_add_child)(BlockDriverState *parent, BlockDriverState *child,
40
+ * immediately.
36
diff --git a/block/io.c b/block/io.c
41
+ */
37
index XXXXXXX..XXXXXXX 100644
42
+ if (ret == -EINTR || ret == -EAGAIN) {
38
--- a/block/io.c
43
luring_resubmit(s, luringcb);
39
+++ b/block/io.c
44
continue;
40
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_drain_invoke_entry(void *opaque)
45
}
41
BlockDriverState *bs = data->bs;
42
43
if (data->begin) {
44
- bs->drv->bdrv_co_drain(bs);
45
+ bs->drv->bdrv_co_drain_begin(bs);
46
} else {
47
bs->drv->bdrv_co_drain_end(bs);
48
}
49
@@ -XXX,XX +XXX,XX @@ static void bdrv_drain_invoke(BlockDriverState *bs, bool begin)
50
{
51
BdrvCoDrainData data = { .bs = bs, .done = false, .begin = begin};
52
53
- if (!bs->drv || (begin && !bs->drv->bdrv_co_drain) ||
54
+ if (!bs->drv || (begin && !bs->drv->bdrv_co_drain_begin) ||
55
(!begin && !bs->drv->bdrv_co_drain_end)) {
56
return;
57
}
58
diff --git a/block/qed.c b/block/qed.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/block/qed.c
61
+++ b/block/qed.c
62
@@ -XXX,XX +XXX,XX @@ static bool qed_plug_allocating_write_reqs(BDRVQEDState *s)
63
assert(!s->allocating_write_reqs_plugged);
64
if (s->allocating_acb != NULL) {
65
/* Another allocating write came concurrently. This cannot happen
66
- * from bdrv_qed_co_drain, but it can happen when the timer runs.
67
+ * from bdrv_qed_co_drain_begin, but it can happen when the timer runs.
68
*/
69
qemu_co_mutex_unlock(&s->table_lock);
70
return false;
71
@@ -XXX,XX +XXX,XX @@ static void bdrv_qed_attach_aio_context(BlockDriverState *bs,
72
}
73
}
74
75
-static void coroutine_fn bdrv_qed_co_drain(BlockDriverState *bs)
76
+static void coroutine_fn bdrv_qed_co_drain_begin(BlockDriverState *bs)
77
{
78
BDRVQEDState *s = bs->opaque;
79
80
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_qed = {
81
.bdrv_check = bdrv_qed_check,
82
.bdrv_detach_aio_context = bdrv_qed_detach_aio_context,
83
.bdrv_attach_aio_context = bdrv_qed_attach_aio_context,
84
- .bdrv_co_drain = bdrv_qed_co_drain,
85
+ .bdrv_co_drain_begin = bdrv_qed_co_drain_begin,
86
};
87
88
static void bdrv_qed_init(void)
89
--
46
--
90
2.13.6
47
2.31.1
91
48
92
diff view generated by jsdifflib
1
From: Manos Pitsidianakis <el13635@mail.ntua.gr>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
BlockDriverState has a bdrv_co_drain() callback but no equivalent for
3
I'm interested in following the activity around the NVMe bdrv.
4
the end of the drain. The throttle driver (block/throttle.c) needs a way
5
to mark the end of the drain in order to toggle io_limits_disabled
6
correctly, thus bdrv_co_drain_end is needed.
7
4
8
Signed-off-by: Manos Pitsidianakis <el13635@mail.ntua.gr>
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
6
Message-id: 20210728183340.2018313-1-philmd@redhat.com
10
Reviewed-by: Fam Zheng <famz@redhat.com>
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
7
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
8
---
13
include/block/block_int.h | 11 +++++++++--
9
MAINTAINERS | 1 +
14
block/io.c | 48 +++++++++++++++++++++++++++++++++--------------
10
1 file changed, 1 insertion(+)
15
2 files changed, 43 insertions(+), 16 deletions(-)
16
11
17
diff --git a/include/block/block_int.h b/include/block/block_int.h
12
diff --git a/MAINTAINERS b/MAINTAINERS
18
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
19
--- a/include/block/block_int.h
14
--- a/MAINTAINERS
20
+++ b/include/block/block_int.h
15
+++ b/MAINTAINERS
21
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
16
@@ -XXX,XX +XXX,XX @@ F: block/null.c
22
int (*bdrv_probe_geometry)(BlockDriverState *bs, HDGeometry *geo);
17
NVMe Block Driver
23
18
M: Stefan Hajnoczi <stefanha@redhat.com>
24
/**
19
R: Fam Zheng <fam@euphon.net>
25
- * Drain and stop any internal sources of requests in the driver, and
20
+R: Philippe Mathieu-Daudé <philmd@redhat.com>
26
- * remain so until next I/O callback (e.g. bdrv_co_writev) is called.
21
L: qemu-block@nongnu.org
27
+ * bdrv_co_drain is called if implemented in the beginning of a
22
S: Supported
28
+ * drain operation to drain and stop any internal sources of requests in
23
F: block/nvme*
29
+ * the driver.
30
+ * bdrv_co_drain_end is called if implemented at the end of the drain.
31
+ *
32
+ * They should be used by the driver to e.g. manage scheduled I/O
33
+ * requests, or toggle an internal state. After the end of the drain new
34
+ * requests will continue normally.
35
*/
36
void coroutine_fn (*bdrv_co_drain)(BlockDriverState *bs);
37
+ void coroutine_fn (*bdrv_co_drain_end)(BlockDriverState *bs);
38
39
void (*bdrv_add_child)(BlockDriverState *parent, BlockDriverState *child,
40
Error **errp);
41
diff --git a/block/io.c b/block/io.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/block/io.c
44
+++ b/block/io.c
45
@@ -XXX,XX +XXX,XX @@ typedef struct {
46
Coroutine *co;
47
BlockDriverState *bs;
48
bool done;
49
+ bool begin;
50
} BdrvCoDrainData;
51
52
static void coroutine_fn bdrv_drain_invoke_entry(void *opaque)
53
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_drain_invoke_entry(void *opaque)
54
BdrvCoDrainData *data = opaque;
55
BlockDriverState *bs = data->bs;
56
57
- bs->drv->bdrv_co_drain(bs);
58
+ if (data->begin) {
59
+ bs->drv->bdrv_co_drain(bs);
60
+ } else {
61
+ bs->drv->bdrv_co_drain_end(bs);
62
+ }
63
64
/* Set data->done before reading bs->wakeup. */
65
atomic_mb_set(&data->done, true);
66
bdrv_wakeup(bs);
67
}
68
69
-static void bdrv_drain_invoke(BlockDriverState *bs)
70
+static void bdrv_drain_invoke(BlockDriverState *bs, bool begin)
71
{
72
- BdrvCoDrainData data = { .bs = bs, .done = false };
73
+ BdrvCoDrainData data = { .bs = bs, .done = false, .begin = begin};
74
75
- if (!bs->drv || !bs->drv->bdrv_co_drain) {
76
+ if (!bs->drv || (begin && !bs->drv->bdrv_co_drain) ||
77
+ (!begin && !bs->drv->bdrv_co_drain_end)) {
78
return;
79
}
80
81
@@ -XXX,XX +XXX,XX @@ static void bdrv_drain_invoke(BlockDriverState *bs)
82
BDRV_POLL_WHILE(bs, !data.done);
83
}
84
85
-static bool bdrv_drain_recurse(BlockDriverState *bs)
86
+static bool bdrv_drain_recurse(BlockDriverState *bs, bool begin)
87
{
88
BdrvChild *child, *tmp;
89
bool waited;
90
91
- waited = BDRV_POLL_WHILE(bs, atomic_read(&bs->in_flight) > 0);
92
-
93
/* Ensure any pending metadata writes are submitted to bs->file. */
94
- bdrv_drain_invoke(bs);
95
+ bdrv_drain_invoke(bs, begin);
96
+
97
+ /* Wait for drained requests to finish */
98
+ waited = BDRV_POLL_WHILE(bs, atomic_read(&bs->in_flight) > 0);
99
100
QLIST_FOREACH_SAFE(child, &bs->children, next, tmp) {
101
BlockDriverState *bs = child->bs;
102
@@ -XXX,XX +XXX,XX @@ static bool bdrv_drain_recurse(BlockDriverState *bs)
103
*/
104
bdrv_ref(bs);
105
}
106
- waited |= bdrv_drain_recurse(bs);
107
+ waited |= bdrv_drain_recurse(bs, begin);
108
if (in_main_loop) {
109
bdrv_unref(bs);
110
}
111
@@ -XXX,XX +XXX,XX @@ static void bdrv_co_drain_bh_cb(void *opaque)
112
BlockDriverState *bs = data->bs;
113
114
bdrv_dec_in_flight(bs);
115
- bdrv_drained_begin(bs);
116
+ if (data->begin) {
117
+ bdrv_drained_begin(bs);
118
+ } else {
119
+ bdrv_drained_end(bs);
120
+ }
121
+
122
data->done = true;
123
aio_co_wake(co);
124
}
125
126
-static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs)
127
+static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs,
128
+ bool begin)
129
{
130
BdrvCoDrainData data;
131
132
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs)
133
.co = qemu_coroutine_self(),
134
.bs = bs,
135
.done = false,
136
+ .begin = begin,
137
};
138
bdrv_inc_in_flight(bs);
139
aio_bh_schedule_oneshot(bdrv_get_aio_context(bs),
140
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs)
141
void bdrv_drained_begin(BlockDriverState *bs)
142
{
143
if (qemu_in_coroutine()) {
144
- bdrv_co_yield_to_drain(bs);
145
+ bdrv_co_yield_to_drain(bs, true);
146
return;
147
}
148
149
@@ -XXX,XX +XXX,XX @@ void bdrv_drained_begin(BlockDriverState *bs)
150
bdrv_parent_drained_begin(bs);
151
}
152
153
- bdrv_drain_recurse(bs);
154
+ bdrv_drain_recurse(bs, true);
155
}
156
157
void bdrv_drained_end(BlockDriverState *bs)
158
{
159
+ if (qemu_in_coroutine()) {
160
+ bdrv_co_yield_to_drain(bs, false);
161
+ return;
162
+ }
163
assert(bs->quiesce_counter > 0);
164
if (atomic_fetch_dec(&bs->quiesce_counter) > 1) {
165
return;
166
}
167
168
bdrv_parent_drained_end(bs);
169
+ bdrv_drain_recurse(bs, false);
170
aio_enable_external(bdrv_get_aio_context(bs));
171
}
172
173
@@ -XXX,XX +XXX,XX @@ void bdrv_drain_all_begin(void)
174
aio_context_acquire(aio_context);
175
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
176
if (aio_context == bdrv_get_aio_context(bs)) {
177
- waited |= bdrv_drain_recurse(bs);
178
+ waited |= bdrv_drain_recurse(bs, true);
179
}
180
}
181
aio_context_release(aio_context);
182
@@ -XXX,XX +XXX,XX @@ void bdrv_drain_all_end(void)
183
aio_context_acquire(aio_context);
184
aio_enable_external(aio_context);
185
bdrv_parent_drained_end(bs);
186
+ bdrv_drain_recurse(bs, false);
187
aio_context_release(aio_context);
188
}
189
190
--
24
--
191
2.13.6
25
2.31.1
192
26
193
diff view generated by jsdifflib