diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2019-07-19 14:59:13 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2019-07-19 14:59:13 +0100 |
commit | 4a10982c320740d2d0565180d901a69b043dc282 (patch) | |
tree | fd0b6faa8052913ff855ade033d286efb7b6d480 /include | |
parent | e2b47666fe1544959c89bd3ed159e9e37cc9fc73 (diff) | |
parent | 49278ec065da3fbf90f7effcde3b39ac606b2e9e (diff) |
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches:
- block: Fix forbidden use of polling in drained_end
- block: Don't wait for I/O throttling while exiting QEMU
- iotests: Use read-zeroes for the null driver to be Valgrind-friendly
# gpg: Signature made Fri 19 Jul 2019 14:30:14 BST
# gpg: using RSA key 7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full]
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6
* remotes/kevin/tags/for-upstream:
iotests: Test quitting with job on throttled node
vl: Drain before (block) job cancel when quitting
iotests: Test commit with a filter on the chain
iotests: Add @has_quit to vm.shutdown()
block: Loop unsafely in bdrv*drained_end()
tests: Extend commit by drained_end test
block: Do not poll in bdrv_do_drained_end()
tests: Lock AioContexts in test-block-iothread
block: Make bdrv_parent_drained_[^_]*() static
block: Add @drained_end_counter
tests: Add job commit by drained_end test
block: Introduce BdrvChild.parent_quiesce_counter
iotests: Set read-zeroes on in null block driver for Valgrind
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/block/block.h | 42 | ||||
-rw-r--r-- | include/block/block_int.h | 15 |
2 files changed, 42 insertions, 15 deletions
diff --git a/include/block/block.h b/include/block/block.h index 734c9d2f76..60f00479e0 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -601,15 +601,6 @@ void bdrv_io_plug(BlockDriverState *bs); void bdrv_io_unplug(BlockDriverState *bs); /** - * bdrv_parent_drained_begin: - * - * Begin a quiesced section of all users of @bs. This is part of - * bdrv_drained_begin. - */ -void bdrv_parent_drained_begin(BlockDriverState *bs, BdrvChild *ignore, - bool ignore_bds_parents); - -/** * bdrv_parent_drained_begin_single: * * Begin a quiesced section for the parent of @c. If @poll is true, wait for @@ -618,13 +609,14 @@ void bdrv_parent_drained_begin(BlockDriverState *bs, BdrvChild *ignore, void bdrv_parent_drained_begin_single(BdrvChild *c, bool poll); /** - * bdrv_parent_drained_end: + * bdrv_parent_drained_end_single: + * + * End a quiesced section for the parent of @c. * - * End a quiesced section of all users of @bs. This is part of - * bdrv_drained_end. + * This polls @bs's AioContext until all scheduled sub-drained_ends + * have settled, which may result in graph changes. */ -void bdrv_parent_drained_end(BlockDriverState *bs, BdrvChild *ignore, - bool ignore_bds_parents); +void bdrv_parent_drained_end_single(BdrvChild *c); /** * bdrv_drain_poll: @@ -672,10 +664,32 @@ void bdrv_subtree_drained_begin(BlockDriverState *bs); * bdrv_drained_end: * * End a quiescent section started by bdrv_drained_begin(). + * + * This polls @bs's AioContext until all scheduled sub-drained_ends + * have settled. On one hand, that may result in graph changes. On + * the other, this requires that all involved nodes (@bs and all of + * its parents) are in the same AioContext, and that the caller has + * acquired it. + * If there are any nodes that are in different contexts from @bs, + * these contexts must not be acquired. */ void bdrv_drained_end(BlockDriverState *bs); /** + * bdrv_drained_end_no_poll: + * + * Same as bdrv_drained_end(), but do not poll for the subgraph to + * actually become unquiesced. Therefore, no graph changes will occur + * with this function. + * + * *drained_end_counter is incremented for every background operation + * that is scheduled, and will be decremented for every operation once + * it settles. The caller must poll until it reaches 0. The counter + * should be accessed using atomic operations only. + */ +void bdrv_drained_end_no_poll(BlockDriverState *bs, int *drained_end_counter); + +/** * End a quiescent section started by bdrv_subtree_drained_begin(). */ void bdrv_subtree_drained_end(BlockDriverState *bs); diff --git a/include/block/block_int.h b/include/block/block_int.h index 50902531b7..3aa1e832a8 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -664,11 +664,15 @@ struct BdrvChildRole { * These functions must not change the graph (and therefore also must not * call aio_poll(), which could change the graph indirectly). * + * If drained_end() schedules background operations, it must atomically + * increment *drained_end_counter for each such operation and atomically + * decrement it once the operation has settled. + * * Note that this can be nested. If drained_begin() was called twice, new * I/O is allowed only after drained_end() was called twice, too. */ void (*drained_begin)(BdrvChild *child); - void (*drained_end)(BdrvChild *child); + void (*drained_end)(BdrvChild *child, int *drained_end_counter); /* * Returns whether the parent has pending requests for the child. This @@ -729,6 +733,15 @@ struct BdrvChild { */ bool frozen; + /* + * How many times the parent of this child has been drained + * (through role->drained_*). + * Usually, this is equal to bs->quiesce_counter (potentially + * reduced by bdrv_drain_all_count). It may differ while the + * child is entering or leaving a drained section. + */ + int parent_quiesce_counter; + QLIST_ENTRY(BdrvChild) next; QLIST_ENTRY(BdrvChild) next_parent; }; |