async.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /*
  2. * QEMU System Emulator
  3. *
  4. * Copyright (c) 2003-2008 Fabrice Bellard
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. */
  24. #include "qemu-common.h"
  25. #include "qemu-aio.h"
  26. /*
  27. * An AsyncContext protects the callbacks of AIO requests and Bottom Halves
  28. * against interfering with each other. A typical example is qcow2 that accepts
  29. * asynchronous requests, but relies for manipulation of its metadata on
  30. * synchronous bdrv_read/write that doesn't trigger any callbacks.
  31. *
  32. * However, these functions are often emulated using AIO which means that AIO
  33. * callbacks must be run - but at the same time we must not run callbacks of
  34. * other requests as they might start to modify metadata and corrupt the
  35. * internal state of the caller of bdrv_read/write.
  36. *
  37. * To achieve the desired semantics we switch into a new AsyncContext.
  38. * Callbacks must only be run if they belong to the current AsyncContext.
  39. * Otherwise they need to be queued until their own context is active again.
  40. * This is how you can make qemu_aio_wait() wait only for your own callbacks.
  41. *
  42. * The AsyncContexts form a stack. When you leave a AsyncContexts, you always
  43. * return to the old ("parent") context.
  44. */
  45. struct AsyncContext {
  46. /* Consecutive number of the AsyncContext (position in the stack) */
  47. int id;
  48. /* Anchor of the list of Bottom Halves belonging to the context */
  49. struct QEMUBH *first_bh;
  50. /* Link to parent context */
  51. struct AsyncContext *parent;
  52. };
  53. /* The currently active AsyncContext */
  54. static struct AsyncContext *async_context = &(struct AsyncContext) { 0 };
  55. /*
  56. * Enter a new AsyncContext. Already scheduled Bottom Halves and AIO callbacks
  57. * won't be called until this context is left again.
  58. */
  59. void async_context_push(void)
  60. {
  61. struct AsyncContext *new = qemu_mallocz(sizeof(*new));
  62. new->parent = async_context;
  63. new->id = async_context->id + 1;
  64. async_context = new;
  65. }
  66. /* Run queued AIO completions and destroy Bottom Half */
  67. static void bh_run_aio_completions(void *opaque)
  68. {
  69. QEMUBH **bh = opaque;
  70. qemu_bh_delete(*bh);
  71. qemu_free(bh);
  72. qemu_aio_process_queue();
  73. }
  74. /*
  75. * Leave the currently active AsyncContext. All Bottom Halves belonging to the
  76. * old context are executed before changing the context.
  77. */
  78. void async_context_pop(void)
  79. {
  80. struct AsyncContext *old = async_context;
  81. QEMUBH **bh;
  82. /* Flush the bottom halves, we don't want to lose them */
  83. while (qemu_bh_poll());
  84. /* Switch back to the parent context */
  85. async_context = async_context->parent;
  86. qemu_free(old);
  87. if (async_context == NULL) {
  88. abort();
  89. }
  90. /* Schedule BH to run any queued AIO completions as soon as possible */
  91. bh = qemu_malloc(sizeof(*bh));
  92. *bh = qemu_bh_new(bh_run_aio_completions, bh);
  93. qemu_bh_schedule(*bh);
  94. }
  95. /*
  96. * Returns the ID of the currently active AsyncContext
  97. */
  98. int get_async_context_id(void)
  99. {
  100. return async_context->id;
  101. }
  102. /***********************************************************/
  103. /* bottom halves (can be seen as timers which expire ASAP) */
  104. struct QEMUBH {
  105. QEMUBHFunc *cb;
  106. void *opaque;
  107. int scheduled;
  108. int idle;
  109. int deleted;
  110. QEMUBH *next;
  111. };
  112. QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
  113. {
  114. QEMUBH *bh;
  115. bh = qemu_mallocz(sizeof(QEMUBH));
  116. bh->cb = cb;
  117. bh->opaque = opaque;
  118. bh->next = async_context->first_bh;
  119. async_context->first_bh = bh;
  120. return bh;
  121. }
  122. int qemu_bh_poll(void)
  123. {
  124. QEMUBH *bh, **bhp, *next;
  125. int ret;
  126. ret = 0;
  127. for (bh = async_context->first_bh; bh; bh = next) {
  128. next = bh->next;
  129. if (!bh->deleted && bh->scheduled) {
  130. bh->scheduled = 0;
  131. if (!bh->idle)
  132. ret = 1;
  133. bh->idle = 0;
  134. bh->cb(bh->opaque);
  135. }
  136. }
  137. /* remove deleted bhs */
  138. bhp = &async_context->first_bh;
  139. while (*bhp) {
  140. bh = *bhp;
  141. if (bh->deleted) {
  142. *bhp = bh->next;
  143. qemu_free(bh);
  144. } else
  145. bhp = &bh->next;
  146. }
  147. return ret;
  148. }
  149. void qemu_bh_schedule_idle(QEMUBH *bh)
  150. {
  151. if (bh->scheduled)
  152. return;
  153. bh->scheduled = 1;
  154. bh->idle = 1;
  155. }
  156. void qemu_bh_schedule(QEMUBH *bh)
  157. {
  158. if (bh->scheduled)
  159. return;
  160. bh->scheduled = 1;
  161. bh->idle = 0;
  162. /* stop the currently executing CPU to execute the BH ASAP */
  163. qemu_notify_event();
  164. }
  165. void qemu_bh_cancel(QEMUBH *bh)
  166. {
  167. bh->scheduled = 0;
  168. }
  169. void qemu_bh_delete(QEMUBH *bh)
  170. {
  171. bh->scheduled = 0;
  172. bh->deleted = 1;
  173. }
  174. void qemu_bh_update_timeout(int *timeout)
  175. {
  176. QEMUBH *bh;
  177. for (bh = async_context->first_bh; bh; bh = bh->next) {
  178. if (!bh->deleted && bh->scheduled) {
  179. if (bh->idle) {
  180. /* idle bottom halves will be polled at least
  181. * every 10ms */
  182. *timeout = MIN(10, *timeout);
  183. } else {
  184. /* non-idle bottom halves will be executed
  185. * immediately */
  186. *timeout = 0;
  187. break;
  188. }
  189. }
  190. }
  191. }