summary refs log tree commit diff stats
path: root/include
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-07-19 14:59:13 +0100
committerPeter Maydell <peter.maydell@linaro.org>2019-07-19 14:59:13 +0100
commit4a10982c320740d2d0565180d901a69b043dc282 (patch)
treefd0b6faa8052913ff855ade033d286efb7b6d480 /include
parente2b47666fe1544959c89bd3ed159e9e37cc9fc73 (diff)
parent49278ec065da3fbf90f7effcde3b39ac606b2e9e (diff)
downloadfocaccia-qemu-4a10982c320740d2d0565180d901a69b043dc282.tar.gz
focaccia-qemu-4a10982c320740d2d0565180d901a69b043dc282.zip
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.h42
-rw-r--r--include/block/block_int.h15
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;
 };