xref: /openbmc/qemu/util/aio-posix.c (revision cbb45ff0)
1 /*
2  * QEMU aio implementation
3  *
4  * Copyright IBM, Corp. 2008
5  *
6  * Authors:
7  *  Anthony Liguori   <aliguori@us.ibm.com>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2.  See
10  * the COPYING file in the top-level directory.
11  *
12  * Contributions after 2012-01-13 are licensed under the terms of the
13  * GNU GPL, version 2 or (at your option) any later version.
14  */
15 
16 #include "qemu/osdep.h"
17 #include "block/block.h"
18 #include "qemu/main-loop.h"
19 #include "qemu/rcu.h"
20 #include "qemu/rcu_queue.h"
21 #include "qemu/sockets.h"
22 #include "qemu/cutils.h"
23 #include "trace.h"
24 #include "aio-posix.h"
25 
26 /*
27  * G_IO_IN and G_IO_OUT are not appropriate revents values for polling, since
28  * the handler may not need to access the file descriptor. For example, the
29  * handler doesn't need to read from an EventNotifier if it polled a memory
30  * location and a read syscall would be slow. Define our own unique revents
31  * value to indicate that polling determined this AioHandler is ready.
32  */
33 #define REVENTS_POLL_READY 0
34 
35 /* Stop userspace polling on a handler if it isn't active for some time */
36 #define POLL_IDLE_INTERVAL_NS (7 * NANOSECONDS_PER_SECOND)
37 
38 bool aio_poll_disabled(AioContext *ctx)
39 {
40     return qatomic_read(&ctx->poll_disable_cnt);
41 }
42 
43 void aio_add_ready_handler(AioHandlerList *ready_list,
44                            AioHandler *node,
45                            int revents)
46 {
47     QLIST_SAFE_REMOVE(node, node_ready); /* remove from nested parent's list */
48     node->pfd.revents = revents;
49     QLIST_INSERT_HEAD(ready_list, node, node_ready);
50 }
51 
52 static AioHandler *find_aio_handler(AioContext *ctx, int fd)
53 {
54     AioHandler *node;
55 
56     QLIST_FOREACH(node, &ctx->aio_handlers, node) {
57         if (node->pfd.fd == fd) {
58             if (!QLIST_IS_INSERTED(node, node_deleted)) {
59                 return node;
60             }
61         }
62     }
63 
64     return NULL;
65 }
66 
67 static bool aio_remove_fd_handler(AioContext *ctx, AioHandler *node)
68 {
69     /* If the GSource is in the process of being destroyed then
70      * g_source_remove_poll() causes an assertion failure.  Skip
71      * removal in that case, because glib cleans up its state during
72      * destruction anyway.
73      */
74     if (!g_source_is_destroyed(&ctx->source)) {
75         g_source_remove_poll(&ctx->source, &node->pfd);
76     }
77 
78     node->pfd.revents = 0;
79 
80     /* If the fd monitor has already marked it deleted, leave it alone */
81     if (QLIST_IS_INSERTED(node, node_deleted)) {
82         return false;
83     }
84 
85     /* If a read is in progress, just mark the node as deleted */
86     if (qemu_lockcnt_count(&ctx->list_lock)) {
87         QLIST_INSERT_HEAD_RCU(&ctx->deleted_aio_handlers, node, node_deleted);
88         return false;
89     }
90     /* Otherwise, delete it for real.  We can't just mark it as
91      * deleted because deleted nodes are only cleaned up while
92      * no one is walking the handlers list.
93      */
94     QLIST_SAFE_REMOVE(node, node_poll);
95     QLIST_REMOVE(node, node);
96     return true;
97 }
98 
99 void aio_set_fd_handler(AioContext *ctx,
100                         int fd,
101                         bool is_external,
102                         IOHandler *io_read,
103                         IOHandler *io_write,
104                         AioPollFn *io_poll,
105                         IOHandler *io_poll_ready,
106                         void *opaque)
107 {
108     AioHandler *node;
109     AioHandler *new_node = NULL;
110     bool is_new = false;
111     bool deleted = false;
112     int poll_disable_change;
113 
114     if (io_poll && !io_poll_ready) {
115         io_poll = NULL; /* polling only makes sense if there is a handler */
116     }
117 
118     qemu_lockcnt_lock(&ctx->list_lock);
119 
120     node = find_aio_handler(ctx, fd);
121 
122     /* Are we deleting the fd handler? */
123     if (!io_read && !io_write && !io_poll) {
124         if (node == NULL) {
125             qemu_lockcnt_unlock(&ctx->list_lock);
126             return;
127         }
128         /* Clean events in order to unregister fd from the ctx epoll. */
129         node->pfd.events = 0;
130 
131         poll_disable_change = -!node->io_poll;
132     } else {
133         poll_disable_change = !io_poll - (node && !node->io_poll);
134         if (node == NULL) {
135             is_new = true;
136         }
137         /* Alloc and insert if it's not already there */
138         new_node = g_new0(AioHandler, 1);
139 
140         /* Update handler with latest information */
141         new_node->io_read = io_read;
142         new_node->io_write = io_write;
143         new_node->io_poll = io_poll;
144         new_node->io_poll_ready = io_poll_ready;
145         new_node->opaque = opaque;
146         new_node->is_external = is_external;
147 
148         if (is_new) {
149             new_node->pfd.fd = fd;
150         } else {
151             new_node->pfd = node->pfd;
152         }
153         g_source_add_poll(&ctx->source, &new_node->pfd);
154 
155         new_node->pfd.events = (io_read ? G_IO_IN | G_IO_HUP | G_IO_ERR : 0);
156         new_node->pfd.events |= (io_write ? G_IO_OUT | G_IO_ERR : 0);
157 
158         QLIST_INSERT_HEAD_RCU(&ctx->aio_handlers, new_node, node);
159     }
160 
161     /* No need to order poll_disable_cnt writes against other updates;
162      * the counter is only used to avoid wasting time and latency on
163      * iterated polling when the system call will be ultimately necessary.
164      * Changing handlers is a rare event, and a little wasted polling until
165      * the aio_notify below is not an issue.
166      */
167     qatomic_set(&ctx->poll_disable_cnt,
168                qatomic_read(&ctx->poll_disable_cnt) + poll_disable_change);
169 
170     ctx->fdmon_ops->update(ctx, node, new_node);
171     if (node) {
172         deleted = aio_remove_fd_handler(ctx, node);
173     }
174     qemu_lockcnt_unlock(&ctx->list_lock);
175     aio_notify(ctx);
176 
177     if (deleted) {
178         g_free(node);
179     }
180 }
181 
182 void aio_set_fd_poll(AioContext *ctx, int fd,
183                      IOHandler *io_poll_begin,
184                      IOHandler *io_poll_end)
185 {
186     AioHandler *node = find_aio_handler(ctx, fd);
187 
188     if (!node) {
189         return;
190     }
191 
192     node->io_poll_begin = io_poll_begin;
193     node->io_poll_end = io_poll_end;
194 }
195 
196 void aio_set_event_notifier(AioContext *ctx,
197                             EventNotifier *notifier,
198                             bool is_external,
199                             EventNotifierHandler *io_read,
200                             AioPollFn *io_poll,
201                             EventNotifierHandler *io_poll_ready)
202 {
203     aio_set_fd_handler(ctx, event_notifier_get_fd(notifier), is_external,
204                        (IOHandler *)io_read, NULL, io_poll,
205                        (IOHandler *)io_poll_ready, notifier);
206 }
207 
208 void aio_set_event_notifier_poll(AioContext *ctx,
209                                  EventNotifier *notifier,
210                                  EventNotifierHandler *io_poll_begin,
211                                  EventNotifierHandler *io_poll_end)
212 {
213     aio_set_fd_poll(ctx, event_notifier_get_fd(notifier),
214                     (IOHandler *)io_poll_begin,
215                     (IOHandler *)io_poll_end);
216 }
217 
218 static bool poll_set_started(AioContext *ctx, AioHandlerList *ready_list,
219                              bool started)
220 {
221     AioHandler *node;
222     bool progress = false;
223 
224     if (started == ctx->poll_started) {
225         return false;
226     }
227 
228     ctx->poll_started = started;
229 
230     qemu_lockcnt_inc(&ctx->list_lock);
231     QLIST_FOREACH(node, &ctx->poll_aio_handlers, node_poll) {
232         IOHandler *fn;
233 
234         if (QLIST_IS_INSERTED(node, node_deleted)) {
235             continue;
236         }
237 
238         if (started) {
239             fn = node->io_poll_begin;
240         } else {
241             fn = node->io_poll_end;
242         }
243 
244         if (fn) {
245             fn(node->opaque);
246         }
247 
248         /* Poll one last time in case ->io_poll_end() raced with the event */
249         if (!started && node->io_poll(node->opaque)) {
250             aio_add_ready_handler(ready_list, node, REVENTS_POLL_READY);
251             progress = true;
252         }
253     }
254     qemu_lockcnt_dec(&ctx->list_lock);
255 
256     return progress;
257 }
258 
259 
260 bool aio_prepare(AioContext *ctx)
261 {
262     AioHandlerList ready_list = QLIST_HEAD_INITIALIZER(ready_list);
263 
264     /* Poll mode cannot be used with glib's event loop, disable it. */
265     poll_set_started(ctx, &ready_list, false);
266     /* TODO what to do with this list? */
267 
268     return false;
269 }
270 
271 bool aio_pending(AioContext *ctx)
272 {
273     AioHandler *node;
274     bool result = false;
275 
276     /*
277      * We have to walk very carefully in case aio_set_fd_handler is
278      * called while we're walking.
279      */
280     qemu_lockcnt_inc(&ctx->list_lock);
281 
282     QLIST_FOREACH_RCU(node, &ctx->aio_handlers, node) {
283         int revents;
284 
285         revents = node->pfd.revents & node->pfd.events;
286         if (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR) && node->io_read &&
287             aio_node_check(ctx, node->is_external)) {
288             result = true;
289             break;
290         }
291         if (revents & (G_IO_OUT | G_IO_ERR) && node->io_write &&
292             aio_node_check(ctx, node->is_external)) {
293             result = true;
294             break;
295         }
296     }
297     qemu_lockcnt_dec(&ctx->list_lock);
298 
299     return result;
300 }
301 
302 static void aio_free_deleted_handlers(AioContext *ctx)
303 {
304     AioHandler *node;
305 
306     if (QLIST_EMPTY_RCU(&ctx->deleted_aio_handlers)) {
307         return;
308     }
309     if (!qemu_lockcnt_dec_if_lock(&ctx->list_lock)) {
310         return; /* we are nested, let the parent do the freeing */
311     }
312 
313     while ((node = QLIST_FIRST_RCU(&ctx->deleted_aio_handlers))) {
314         QLIST_REMOVE(node, node);
315         QLIST_REMOVE(node, node_deleted);
316         QLIST_SAFE_REMOVE(node, node_poll);
317         g_free(node);
318     }
319 
320     qemu_lockcnt_inc_and_unlock(&ctx->list_lock);
321 }
322 
323 static bool aio_dispatch_handler(AioContext *ctx, AioHandler *node)
324 {
325     bool progress = false;
326     int revents;
327 
328     revents = node->pfd.revents & node->pfd.events;
329     node->pfd.revents = 0;
330 
331     /*
332      * Start polling AioHandlers when they become ready because activity is
333      * likely to continue.  Note that starvation is theoretically possible when
334      * fdmon_supports_polling(), but only until the fd fires for the first
335      * time.
336      */
337     if (!QLIST_IS_INSERTED(node, node_deleted) &&
338         !QLIST_IS_INSERTED(node, node_poll) &&
339         node->io_poll) {
340         trace_poll_add(ctx, node, node->pfd.fd, revents);
341         if (ctx->poll_started && node->io_poll_begin) {
342             node->io_poll_begin(node->opaque);
343         }
344         QLIST_INSERT_HEAD(&ctx->poll_aio_handlers, node, node_poll);
345     }
346     if (!QLIST_IS_INSERTED(node, node_deleted) &&
347         revents == 0 &&
348         aio_node_check(ctx, node->is_external) &&
349         node->io_poll_ready) {
350         node->io_poll_ready(node->opaque);
351 
352         /*
353          * Return early since revents was zero. aio_notify() does not count as
354          * progress.
355          */
356         return node->opaque != &ctx->notifier;
357     }
358 
359     if (!QLIST_IS_INSERTED(node, node_deleted) &&
360         (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR)) &&
361         aio_node_check(ctx, node->is_external) &&
362         node->io_read) {
363         node->io_read(node->opaque);
364 
365         /* aio_notify() does not count as progress */
366         if (node->opaque != &ctx->notifier) {
367             progress = true;
368         }
369     }
370     if (!QLIST_IS_INSERTED(node, node_deleted) &&
371         (revents & (G_IO_OUT | G_IO_ERR)) &&
372         aio_node_check(ctx, node->is_external) &&
373         node->io_write) {
374         node->io_write(node->opaque);
375         progress = true;
376     }
377 
378     return progress;
379 }
380 
381 /*
382  * If we have a list of ready handlers then this is more efficient than
383  * scanning all handlers with aio_dispatch_handlers().
384  */
385 static bool aio_dispatch_ready_handlers(AioContext *ctx,
386                                         AioHandlerList *ready_list)
387 {
388     bool progress = false;
389     AioHandler *node;
390 
391     while ((node = QLIST_FIRST(ready_list))) {
392         QLIST_REMOVE(node, node_ready);
393         progress = aio_dispatch_handler(ctx, node) || progress;
394     }
395 
396     return progress;
397 }
398 
399 /* Slower than aio_dispatch_ready_handlers() but only used via glib */
400 static bool aio_dispatch_handlers(AioContext *ctx)
401 {
402     AioHandler *node, *tmp;
403     bool progress = false;
404 
405     QLIST_FOREACH_SAFE_RCU(node, &ctx->aio_handlers, node, tmp) {
406         progress = aio_dispatch_handler(ctx, node) || progress;
407     }
408 
409     return progress;
410 }
411 
412 void aio_dispatch(AioContext *ctx)
413 {
414     qemu_lockcnt_inc(&ctx->list_lock);
415     aio_bh_poll(ctx);
416     aio_dispatch_handlers(ctx);
417     aio_free_deleted_handlers(ctx);
418     qemu_lockcnt_dec(&ctx->list_lock);
419 
420     timerlistgroup_run_timers(&ctx->tlg);
421 }
422 
423 static bool run_poll_handlers_once(AioContext *ctx,
424                                    AioHandlerList *ready_list,
425                                    int64_t now,
426                                    int64_t *timeout)
427 {
428     bool progress = false;
429     AioHandler *node;
430     AioHandler *tmp;
431 
432     QLIST_FOREACH_SAFE(node, &ctx->poll_aio_handlers, node_poll, tmp) {
433         if (aio_node_check(ctx, node->is_external) &&
434             node->io_poll(node->opaque)) {
435             aio_add_ready_handler(ready_list, node, REVENTS_POLL_READY);
436 
437             node->poll_idle_timeout = now + POLL_IDLE_INTERVAL_NS;
438 
439             /*
440              * Polling was successful, exit try_poll_mode immediately
441              * to adjust the next polling time.
442              */
443             *timeout = 0;
444             if (node->opaque != &ctx->notifier) {
445                 progress = true;
446             }
447         }
448 
449         /* Caller handles freeing deleted nodes.  Don't do it here. */
450     }
451 
452     return progress;
453 }
454 
455 static bool fdmon_supports_polling(AioContext *ctx)
456 {
457     return ctx->fdmon_ops->need_wait != aio_poll_disabled;
458 }
459 
460 static bool remove_idle_poll_handlers(AioContext *ctx,
461                                       AioHandlerList *ready_list,
462                                       int64_t now)
463 {
464     AioHandler *node;
465     AioHandler *tmp;
466     bool progress = false;
467 
468     /*
469      * File descriptor monitoring implementations without userspace polling
470      * support suffer from starvation when a subset of handlers is polled
471      * because fds will not be processed in a timely fashion.  Don't remove
472      * idle poll handlers.
473      */
474     if (!fdmon_supports_polling(ctx)) {
475         return false;
476     }
477 
478     QLIST_FOREACH_SAFE(node, &ctx->poll_aio_handlers, node_poll, tmp) {
479         if (node->poll_idle_timeout == 0LL) {
480             node->poll_idle_timeout = now + POLL_IDLE_INTERVAL_NS;
481         } else if (now >= node->poll_idle_timeout) {
482             trace_poll_remove(ctx, node, node->pfd.fd);
483             node->poll_idle_timeout = 0LL;
484             QLIST_SAFE_REMOVE(node, node_poll);
485             if (ctx->poll_started && node->io_poll_end) {
486                 node->io_poll_end(node->opaque);
487 
488                 /*
489                  * Final poll in case ->io_poll_end() races with an event.
490                  * Nevermind about re-adding the handler in the rare case where
491                  * this causes progress.
492                  */
493                 if (node->io_poll(node->opaque)) {
494                     aio_add_ready_handler(ready_list, node,
495                                           REVENTS_POLL_READY);
496                     progress = true;
497                 }
498             }
499         }
500     }
501 
502     return progress;
503 }
504 
505 /* run_poll_handlers:
506  * @ctx: the AioContext
507  * @ready_list: the list to place ready handlers on
508  * @max_ns: maximum time to poll for, in nanoseconds
509  *
510  * Polls for a given time.
511  *
512  * Note that the caller must have incremented ctx->list_lock.
513  *
514  * Returns: true if progress was made, false otherwise
515  */
516 static bool run_poll_handlers(AioContext *ctx, AioHandlerList *ready_list,
517                               int64_t max_ns, int64_t *timeout)
518 {
519     bool progress;
520     int64_t start_time, elapsed_time;
521 
522     assert(qemu_lockcnt_count(&ctx->list_lock) > 0);
523 
524     trace_run_poll_handlers_begin(ctx, max_ns, *timeout);
525 
526     /*
527      * Optimization: ->io_poll() handlers often contain RCU read critical
528      * sections and we therefore see many rcu_read_lock() -> rcu_read_unlock()
529      * -> rcu_read_lock() -> ... sequences with expensive memory
530      * synchronization primitives.  Make the entire polling loop an RCU
531      * critical section because nested rcu_read_lock()/rcu_read_unlock() calls
532      * are cheap.
533      */
534     RCU_READ_LOCK_GUARD();
535 
536     start_time = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
537     do {
538         progress = run_poll_handlers_once(ctx, ready_list,
539                                           start_time, timeout);
540         elapsed_time = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - start_time;
541         max_ns = qemu_soonest_timeout(*timeout, max_ns);
542         assert(!(max_ns && progress));
543     } while (elapsed_time < max_ns && !ctx->fdmon_ops->need_wait(ctx));
544 
545     if (remove_idle_poll_handlers(ctx, ready_list,
546                                   start_time + elapsed_time)) {
547         *timeout = 0;
548         progress = true;
549     }
550 
551     /* If time has passed with no successful polling, adjust *timeout to
552      * keep the same ending time.
553      */
554     if (*timeout != -1) {
555         *timeout -= MIN(*timeout, elapsed_time);
556     }
557 
558     trace_run_poll_handlers_end(ctx, progress, *timeout);
559     return progress;
560 }
561 
562 /* try_poll_mode:
563  * @ctx: the AioContext
564  * @ready_list: list to add handlers that need to be run
565  * @timeout: timeout for blocking wait, computed by the caller and updated if
566  *    polling succeeds.
567  *
568  * Note that the caller must have incremented ctx->list_lock.
569  *
570  * Returns: true if progress was made, false otherwise
571  */
572 static bool try_poll_mode(AioContext *ctx, AioHandlerList *ready_list,
573                           int64_t *timeout)
574 {
575     int64_t max_ns;
576 
577     if (QLIST_EMPTY_RCU(&ctx->poll_aio_handlers)) {
578         return false;
579     }
580 
581     max_ns = qemu_soonest_timeout(*timeout, ctx->poll_ns);
582     if (max_ns && !ctx->fdmon_ops->need_wait(ctx)) {
583         poll_set_started(ctx, ready_list, true);
584 
585         if (run_poll_handlers(ctx, ready_list, max_ns, timeout)) {
586             return true;
587         }
588     }
589 
590     if (poll_set_started(ctx, ready_list, false)) {
591         *timeout = 0;
592         return true;
593     }
594 
595     return false;
596 }
597 
598 bool aio_poll(AioContext *ctx, bool blocking)
599 {
600     AioHandlerList ready_list = QLIST_HEAD_INITIALIZER(ready_list);
601     bool progress;
602     bool use_notify_me;
603     int64_t timeout;
604     int64_t start = 0;
605 
606     /*
607      * There cannot be two concurrent aio_poll calls for the same AioContext (or
608      * an aio_poll concurrent with a GSource prepare/check/dispatch callback).
609      * We rely on this below to avoid slow locked accesses to ctx->notify_me.
610      *
611      * aio_poll() may only be called in the AioContext's thread. iohandler_ctx
612      * is special in that it runs in the main thread, but that thread's context
613      * is qemu_aio_context.
614      */
615     assert(in_aio_context_home_thread(ctx == iohandler_get_aio_context() ?
616                                       qemu_get_aio_context() : ctx));
617 
618     qemu_lockcnt_inc(&ctx->list_lock);
619 
620     if (ctx->poll_max_ns) {
621         start = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
622     }
623 
624     timeout = blocking ? aio_compute_timeout(ctx) : 0;
625     progress = try_poll_mode(ctx, &ready_list, &timeout);
626     assert(!(timeout && progress));
627 
628     /*
629      * aio_notify can avoid the expensive event_notifier_set if
630      * everything (file descriptors, bottom halves, timers) will
631      * be re-evaluated before the next blocking poll().  This is
632      * already true when aio_poll is called with blocking == false;
633      * if blocking == true, it is only true after poll() returns,
634      * so disable the optimization now.
635      */
636     use_notify_me = timeout != 0;
637     if (use_notify_me) {
638         qatomic_set(&ctx->notify_me, qatomic_read(&ctx->notify_me) + 2);
639         /*
640          * Write ctx->notify_me before reading ctx->notified.  Pairs with
641          * smp_mb in aio_notify().
642          */
643         smp_mb();
644 
645         /* Don't block if aio_notify() was called */
646         if (qatomic_read(&ctx->notified)) {
647             timeout = 0;
648         }
649     }
650 
651     /* If polling is allowed, non-blocking aio_poll does not need the
652      * system call---a single round of run_poll_handlers_once suffices.
653      */
654     if (timeout || ctx->fdmon_ops->need_wait(ctx)) {
655         ctx->fdmon_ops->wait(ctx, &ready_list, timeout);
656     }
657 
658     if (use_notify_me) {
659         /* Finish the poll before clearing the flag.  */
660         qatomic_store_release(&ctx->notify_me,
661                              qatomic_read(&ctx->notify_me) - 2);
662     }
663 
664     aio_notify_accept(ctx);
665 
666     /* Adjust polling time */
667     if (ctx->poll_max_ns) {
668         int64_t block_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - start;
669 
670         if (block_ns <= ctx->poll_ns) {
671             /* This is the sweet spot, no adjustment needed */
672         } else if (block_ns > ctx->poll_max_ns) {
673             /* We'd have to poll for too long, poll less */
674             int64_t old = ctx->poll_ns;
675 
676             if (ctx->poll_shrink) {
677                 ctx->poll_ns /= ctx->poll_shrink;
678             } else {
679                 ctx->poll_ns = 0;
680             }
681 
682             trace_poll_shrink(ctx, old, ctx->poll_ns);
683         } else if (ctx->poll_ns < ctx->poll_max_ns &&
684                    block_ns < ctx->poll_max_ns) {
685             /* There is room to grow, poll longer */
686             int64_t old = ctx->poll_ns;
687             int64_t grow = ctx->poll_grow;
688 
689             if (grow == 0) {
690                 grow = 2;
691             }
692 
693             if (ctx->poll_ns) {
694                 ctx->poll_ns *= grow;
695             } else {
696                 ctx->poll_ns = 4000; /* start polling at 4 microseconds */
697             }
698 
699             if (ctx->poll_ns > ctx->poll_max_ns) {
700                 ctx->poll_ns = ctx->poll_max_ns;
701             }
702 
703             trace_poll_grow(ctx, old, ctx->poll_ns);
704         }
705     }
706 
707     progress |= aio_bh_poll(ctx);
708     progress |= aio_dispatch_ready_handlers(ctx, &ready_list);
709 
710     aio_free_deleted_handlers(ctx);
711 
712     qemu_lockcnt_dec(&ctx->list_lock);
713 
714     progress |= timerlistgroup_run_timers(&ctx->tlg);
715 
716     return progress;
717 }
718 
719 void aio_context_setup(AioContext *ctx)
720 {
721     ctx->fdmon_ops = &fdmon_poll_ops;
722     ctx->epollfd = -1;
723 
724     /* Use the fastest fd monitoring implementation if available */
725     if (fdmon_io_uring_setup(ctx)) {
726         return;
727     }
728 
729     fdmon_epoll_setup(ctx);
730 }
731 
732 void aio_context_destroy(AioContext *ctx)
733 {
734     fdmon_io_uring_destroy(ctx);
735     fdmon_epoll_disable(ctx);
736     aio_free_deleted_handlers(ctx);
737 }
738 
739 void aio_context_use_g_source(AioContext *ctx)
740 {
741     /*
742      * Disable io_uring when the glib main loop is used because it doesn't
743      * support mixed glib/aio_poll() usage. It relies on aio_poll() being
744      * called regularly so that changes to the monitored file descriptors are
745      * submitted, otherwise a list of pending fd handlers builds up.
746      */
747     fdmon_io_uring_destroy(ctx);
748     aio_free_deleted_handlers(ctx);
749 }
750 
751 void aio_context_set_poll_params(AioContext *ctx, int64_t max_ns,
752                                  int64_t grow, int64_t shrink, Error **errp)
753 {
754     /* No thread synchronization here, it doesn't matter if an incorrect value
755      * is used once.
756      */
757     ctx->poll_max_ns = max_ns;
758     ctx->poll_ns = 0;
759     ctx->poll_grow = grow;
760     ctx->poll_shrink = shrink;
761 
762     aio_notify(ctx);
763 }
764 
765 void aio_context_set_aio_params(AioContext *ctx, int64_t max_batch,
766                                 Error **errp)
767 {
768     /*
769      * No thread synchronization here, it doesn't matter if an incorrect value
770      * is used once.
771      */
772     ctx->aio_max_batch = max_batch;
773 
774     aio_notify(ctx);
775 }
776