xref: /openbmc/qemu/iothread.c (revision c3033fd372fdaf5b89190136a74b3d78880b85d6)
1  /*
2   * Event loop thread
3   *
4   * Copyright Red Hat Inc., 2013, 2020
5   *
6   * Authors:
7   *  Stefan Hajnoczi   <stefanha@redhat.com>
8   *
9   * This work is licensed under the terms of the GNU GPL, version 2 or later.
10   * See the COPYING file in the top-level directory.
11   *
12   */
13  
14  #include "qemu/osdep.h"
15  #include "qom/object.h"
16  #include "qom/object_interfaces.h"
17  #include "qemu/module.h"
18  #include "block/aio.h"
19  #include "block/block.h"
20  #include "sysemu/iothread.h"
21  #include "qapi/error.h"
22  #include "qapi/qapi-commands-misc.h"
23  #include "qemu/error-report.h"
24  #include "qemu/rcu.h"
25  #include "qemu/main-loop.h"
26  
27  typedef ObjectClass IOThreadClass;
28  
29  DECLARE_CLASS_CHECKERS(IOThreadClass, IOTHREAD,
30                         TYPE_IOTHREAD)
31  
32  #ifdef CONFIG_POSIX
33  /* Benchmark results from 2016 on NVMe SSD drives show max polling times around
34   * 16-32 microseconds yield IOPS improvements for both iodepth=1 and iodepth=32
35   * workloads.
36   */
37  #define IOTHREAD_POLL_MAX_NS_DEFAULT 32768ULL
38  #else
39  #define IOTHREAD_POLL_MAX_NS_DEFAULT 0ULL
40  #endif
41  
42  static __thread IOThread *my_iothread;
43  
44  AioContext *qemu_get_current_aio_context(void)
45  {
46      return my_iothread ? my_iothread->ctx : qemu_get_aio_context();
47  }
48  
49  static void *iothread_run(void *opaque)
50  {
51      IOThread *iothread = opaque;
52  
53      rcu_register_thread();
54      /*
55       * g_main_context_push_thread_default() must be called before anything
56       * in this new thread uses glib.
57       */
58      g_main_context_push_thread_default(iothread->worker_context);
59      my_iothread = iothread;
60      iothread->thread_id = qemu_get_thread_id();
61      qemu_sem_post(&iothread->init_done_sem);
62  
63      while (iothread->running) {
64          /*
65           * Note: from functional-wise the g_main_loop_run() below can
66           * already cover the aio_poll() events, but we can't run the
67           * main loop unconditionally because explicit aio_poll() here
68           * is faster than g_main_loop_run() when we do not need the
69           * gcontext at all (e.g., pure block layer iothreads).  In
70           * other words, when we want to run the gcontext with the
71           * iothread we need to pay some performance for functionality.
72           */
73          aio_poll(iothread->ctx, true);
74  
75          /*
76           * We must check the running state again in case it was
77           * changed in previous aio_poll()
78           */
79          if (iothread->running && qatomic_read(&iothread->run_gcontext)) {
80              g_main_loop_run(iothread->main_loop);
81          }
82      }
83  
84      g_main_context_pop_thread_default(iothread->worker_context);
85      rcu_unregister_thread();
86      return NULL;
87  }
88  
89  /* Runs in iothread_run() thread */
90  static void iothread_stop_bh(void *opaque)
91  {
92      IOThread *iothread = opaque;
93  
94      iothread->running = false; /* stop iothread_run() */
95  
96      if (iothread->main_loop) {
97          g_main_loop_quit(iothread->main_loop);
98      }
99  }
100  
101  void iothread_stop(IOThread *iothread)
102  {
103      if (!iothread->ctx || iothread->stopping) {
104          return;
105      }
106      iothread->stopping = true;
107      aio_bh_schedule_oneshot(iothread->ctx, iothread_stop_bh, iothread);
108      qemu_thread_join(&iothread->thread);
109  }
110  
111  static void iothread_instance_init(Object *obj)
112  {
113      IOThread *iothread = IOTHREAD(obj);
114  
115      iothread->poll_max_ns = IOTHREAD_POLL_MAX_NS_DEFAULT;
116      iothread->thread_id = -1;
117      qemu_sem_init(&iothread->init_done_sem, 0);
118      /* By default, we don't run gcontext */
119      qatomic_set(&iothread->run_gcontext, 0);
120  }
121  
122  static void iothread_instance_finalize(Object *obj)
123  {
124      IOThread *iothread = IOTHREAD(obj);
125  
126      iothread_stop(iothread);
127  
128      /*
129       * Before glib2 2.33.10, there is a glib2 bug that GSource context
130       * pointer may not be cleared even if the context has already been
131       * destroyed (while it should).  Here let's free the AIO context
132       * earlier to bypass that glib bug.
133       *
134       * We can remove this comment after the minimum supported glib2
135       * version boosts to 2.33.10.  Before that, let's free the
136       * GSources first before destroying any GMainContext.
137       */
138      if (iothread->ctx) {
139          aio_context_unref(iothread->ctx);
140          iothread->ctx = NULL;
141      }
142      if (iothread->worker_context) {
143          g_main_context_unref(iothread->worker_context);
144          iothread->worker_context = NULL;
145          g_main_loop_unref(iothread->main_loop);
146          iothread->main_loop = NULL;
147      }
148      qemu_sem_destroy(&iothread->init_done_sem);
149  }
150  
151  static void iothread_init_gcontext(IOThread *iothread)
152  {
153      GSource *source;
154  
155      iothread->worker_context = g_main_context_new();
156      source = aio_get_g_source(iothread_get_aio_context(iothread));
157      g_source_attach(source, iothread->worker_context);
158      g_source_unref(source);
159      iothread->main_loop = g_main_loop_new(iothread->worker_context, TRUE);
160  }
161  
162  static void iothread_complete(UserCreatable *obj, Error **errp)
163  {
164      Error *local_error = NULL;
165      IOThread *iothread = IOTHREAD(obj);
166      char *thread_name;
167  
168      iothread->stopping = false;
169      iothread->running = true;
170      iothread->ctx = aio_context_new(errp);
171      if (!iothread->ctx) {
172          return;
173      }
174  
175      /*
176       * Init one GMainContext for the iothread unconditionally, even if
177       * it's not used
178       */
179      iothread_init_gcontext(iothread);
180  
181      aio_context_set_poll_params(iothread->ctx,
182                                  iothread->poll_max_ns,
183                                  iothread->poll_grow,
184                                  iothread->poll_shrink,
185                                  &local_error);
186      if (local_error) {
187          error_propagate(errp, local_error);
188          aio_context_unref(iothread->ctx);
189          iothread->ctx = NULL;
190          return;
191      }
192  
193      /* This assumes we are called from a thread with useful CPU affinity for us
194       * to inherit.
195       */
196      thread_name = g_strdup_printf("IO %s",
197                          object_get_canonical_path_component(OBJECT(obj)));
198      qemu_thread_create(&iothread->thread, thread_name, iothread_run,
199                         iothread, QEMU_THREAD_JOINABLE);
200      g_free(thread_name);
201  
202      /* Wait for initialization to complete */
203      while (iothread->thread_id == -1) {
204          qemu_sem_wait(&iothread->init_done_sem);
205      }
206  }
207  
208  typedef struct {
209      const char *name;
210      ptrdiff_t offset; /* field's byte offset in IOThread struct */
211  } PollParamInfo;
212  
213  static PollParamInfo poll_max_ns_info = {
214      "poll-max-ns", offsetof(IOThread, poll_max_ns),
215  };
216  static PollParamInfo poll_grow_info = {
217      "poll-grow", offsetof(IOThread, poll_grow),
218  };
219  static PollParamInfo poll_shrink_info = {
220      "poll-shrink", offsetof(IOThread, poll_shrink),
221  };
222  
223  static void iothread_get_poll_param(Object *obj, Visitor *v,
224          const char *name, void *opaque, Error **errp)
225  {
226      IOThread *iothread = IOTHREAD(obj);
227      PollParamInfo *info = opaque;
228      int64_t *field = (void *)iothread + info->offset;
229  
230      visit_type_int64(v, name, field, errp);
231  }
232  
233  static void iothread_set_poll_param(Object *obj, Visitor *v,
234          const char *name, void *opaque, Error **errp)
235  {
236      IOThread *iothread = IOTHREAD(obj);
237      PollParamInfo *info = opaque;
238      int64_t *field = (void *)iothread + info->offset;
239      int64_t value;
240  
241      if (!visit_type_int64(v, name, &value, errp)) {
242          return;
243      }
244  
245      if (value < 0) {
246          error_setg(errp, "%s value must be in range [0, %" PRId64 "]",
247                     info->name, INT64_MAX);
248          return;
249      }
250  
251      *field = value;
252  
253      if (iothread->ctx) {
254          aio_context_set_poll_params(iothread->ctx,
255                                      iothread->poll_max_ns,
256                                      iothread->poll_grow,
257                                      iothread->poll_shrink,
258                                      errp);
259      }
260  }
261  
262  static void iothread_class_init(ObjectClass *klass, void *class_data)
263  {
264      UserCreatableClass *ucc = USER_CREATABLE_CLASS(klass);
265      ucc->complete = iothread_complete;
266  
267      object_class_property_add(klass, "poll-max-ns", "int",
268                                iothread_get_poll_param,
269                                iothread_set_poll_param,
270                                NULL, &poll_max_ns_info);
271      object_class_property_add(klass, "poll-grow", "int",
272                                iothread_get_poll_param,
273                                iothread_set_poll_param,
274                                NULL, &poll_grow_info);
275      object_class_property_add(klass, "poll-shrink", "int",
276                                iothread_get_poll_param,
277                                iothread_set_poll_param,
278                                NULL, &poll_shrink_info);
279  }
280  
281  static const TypeInfo iothread_info = {
282      .name = TYPE_IOTHREAD,
283      .parent = TYPE_OBJECT,
284      .class_init = iothread_class_init,
285      .instance_size = sizeof(IOThread),
286      .instance_init = iothread_instance_init,
287      .instance_finalize = iothread_instance_finalize,
288      .interfaces = (InterfaceInfo[]) {
289          {TYPE_USER_CREATABLE},
290          {}
291      },
292  };
293  
294  static void iothread_register_types(void)
295  {
296      type_register_static(&iothread_info);
297  }
298  
299  type_init(iothread_register_types)
300  
301  char *iothread_get_id(IOThread *iothread)
302  {
303      return g_strdup(object_get_canonical_path_component(OBJECT(iothread)));
304  }
305  
306  AioContext *iothread_get_aio_context(IOThread *iothread)
307  {
308      return iothread->ctx;
309  }
310  
311  static int query_one_iothread(Object *object, void *opaque)
312  {
313      IOThreadInfoList ***tail = opaque;
314      IOThreadInfo *info;
315      IOThread *iothread;
316  
317      iothread = (IOThread *)object_dynamic_cast(object, TYPE_IOTHREAD);
318      if (!iothread) {
319          return 0;
320      }
321  
322      info = g_new0(IOThreadInfo, 1);
323      info->id = iothread_get_id(iothread);
324      info->thread_id = iothread->thread_id;
325      info->poll_max_ns = iothread->poll_max_ns;
326      info->poll_grow = iothread->poll_grow;
327      info->poll_shrink = iothread->poll_shrink;
328  
329      QAPI_LIST_APPEND(*tail, info);
330      return 0;
331  }
332  
333  IOThreadInfoList *qmp_query_iothreads(Error **errp)
334  {
335      IOThreadInfoList *head = NULL;
336      IOThreadInfoList **prev = &head;
337      Object *container = object_get_objects_root();
338  
339      object_child_foreach(container, query_one_iothread, &prev);
340      return head;
341  }
342  
343  GMainContext *iothread_get_g_main_context(IOThread *iothread)
344  {
345      qatomic_set(&iothread->run_gcontext, 1);
346      aio_notify(iothread->ctx);
347      return iothread->worker_context;
348  }
349  
350  IOThread *iothread_create(const char *id, Error **errp)
351  {
352      Object *obj;
353  
354      obj = object_new_with_props(TYPE_IOTHREAD,
355                                  object_get_internal_root(),
356                                  id, errp, NULL);
357  
358      return IOTHREAD(obj);
359  }
360  
361  void iothread_destroy(IOThread *iothread)
362  {
363      object_unparent(OBJECT(iothread));
364  }
365  
366  /* Lookup IOThread by its id.  Only finds user-created objects, not internal
367   * iothread_create() objects. */
368  IOThread *iothread_by_id(const char *id)
369  {
370      return IOTHREAD(object_resolve_path_type(id, TYPE_IOTHREAD, NULL));
371  }
372