Skip to content
Snippets Groups Projects
  1. Sep 08, 2023
    • Stefan Hajnoczi's avatar
      io: follow coroutine AioContext in qio_channel_yield() · 06e0f098
      Stefan Hajnoczi authored
      
      The ongoing QEMU multi-queue block layer effort makes it possible for multiple
      threads to process I/O in parallel. The nbd block driver is not compatible with
      the multi-queue block layer yet because QIOChannel cannot be used easily from
      coroutines running in multiple threads. This series changes the QIOChannel API
      to make that possible.
      
      In the current API, calling qio_channel_attach_aio_context() sets the
      AioContext where qio_channel_yield() installs an fd handler prior to yielding:
      
        qio_channel_attach_aio_context(ioc, my_ctx);
        ...
        qio_channel_yield(ioc); // my_ctx is used here
        ...
        qio_channel_detach_aio_context(ioc);
      
      This API design has limitations: reading and writing must be done in the same
      AioContext and moving between AioContexts involves a cumbersome sequence of API
      calls that is not suitable for doing on a per-request basis.
      
      There is no fundamental reason why a QIOChannel needs to run within the
      same AioContext every time qio_channel_yield() is called. QIOChannel
      only uses the AioContext while inside qio_channel_yield(). The rest of
      the time, QIOChannel is independent of any AioContext.
      
      In the new API, qio_channel_yield() queries the AioContext from the current
      coroutine using qemu_coroutine_get_aio_context(). There is no need to
      explicitly attach/detach AioContexts anymore and
      qio_channel_attach_aio_context() and qio_channel_detach_aio_context() are gone.
      One coroutine can read from the QIOChannel while another coroutine writes from
      a different AioContext.
      
      This API change allows the nbd block driver to use QIOChannel from any thread.
      It's important to keep in mind that the block driver already synchronizes
      QIOChannel access and ensures that two coroutines never read simultaneously or
      write simultaneously.
      
      This patch updates all users of qio_channel_attach_aio_context() to the
      new API. Most conversions are simple, but vhost-user-server requires a
      new qemu_coroutine_yield() call to quiesce the vu_client_trip()
      coroutine when not attached to any AioContext.
      
      While the API is has become simpler, there is one wart: QIOChannel has a
      special case for the iohandler AioContext (used for handlers that must not run
      in nested event loops). I didn't find an elegant way preserve that behavior, so
      I added a new API called qio_channel_set_follow_coroutine_ctx(ioc, true|false)
      for opting in to the new AioContext model. By default QIOChannel uses the
      iohandler AioHandler. Code that formerly called
      qio_channel_attach_aio_context() now calls
      qio_channel_set_follow_coroutine_ctx(ioc, true) once after the QIOChannel is
      created.
      
      Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
      Reviewed-by: default avatarEric Blake <eblake@redhat.com>
      Acked-by: default avatarDaniel P. Berrangé <berrange@redhat.com>
      Message-ID: <20230830224802.493686-5-stefanha@redhat.com>
      [eblake: also fix migration/rdma.c]
      Signed-off-by: default avatarEric Blake <eblake@redhat.com>
      06e0f098
  2. Jun 06, 2023
  3. Apr 25, 2023
  4. Feb 06, 2023
  5. May 16, 2022
    • Leonardo Bras's avatar
      QIOChannel: Add flags on io_writev and introduce io_flush callback · b88651cb
      Leonardo Bras authored
      
      Add flags to io_writev and introduce io_flush as optional callback to
      QIOChannelClass, allowing the implementation of zero copy writes by
      subclasses.
      
      How to use them:
      - Write data using qio_channel_writev*(...,QIO_CHANNEL_WRITE_FLAG_ZERO_COPY),
      - Wait write completion with qio_channel_flush().
      
      Notes:
      As some zero copy write implementations work asynchronously, it's
      recommended to keep the write buffer untouched until the return of
      qio_channel_flush(), to avoid the risk of sending an updated buffer
      instead of the buffer state during write.
      
      As io_flush callback is optional, if a subclass does not implement it, then:
      - io_flush will return 0 without changing anything.
      
      Also, some functions like qio_channel_writev_full_all() were adapted to
      receive a flag parameter. That allows shared code between zero copy and
      non-zero copy writev, and also an easier implementation on new flags.
      
      Signed-off-by: default avatarLeonardo Bras <leobras@redhat.com>
      Reviewed-by: default avatarDaniel P. Berrangé <berrange@redhat.com>
      Reviewed-by: default avatarPeter Xu <peterx@redhat.com>
      Reviewed-by: default avatarJuan Quintela <quintela@redhat.com>
      Message-Id: <20220513062836.965425-3-leobras@redhat.com>
      Signed-off-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
      b88651cb
  6. Apr 21, 2022
  7. Apr 20, 2022
  8. Aug 26, 2021
  9. Jun 02, 2021
  10. Mar 16, 2021
  11. Mar 06, 2021
  12. Feb 25, 2021
  13. Jan 28, 2021
  14. Jan 22, 2021
  15. Nov 11, 2020
  16. Sep 23, 2020
    • Stefan Hajnoczi's avatar
      qemu/atomic.h: rename atomic_ to qatomic_ · d73415a3
      Stefan Hajnoczi authored
      
      clang's C11 atomic_fetch_*() functions only take a C11 atomic type
      pointer argument. QEMU uses direct types (int, etc) and this causes a
      compiler error when a QEMU code calls these functions in a source file
      that also included <stdatomic.h> via a system header file:
      
        $ CC=clang CXX=clang++ ./configure ... && make
        ../util/async.c:79:17: error: address argument to atomic operation must be a pointer to _Atomic type ('unsigned int *' invalid)
      
      Avoid using atomic_*() names in QEMU's atomic.h since that namespace is
      used by <stdatomic.h>. Prefix QEMU's APIs with 'q' so that atomic.h
      and <stdatomic.h> can co-exist. I checked /usr/include on my machine and
      searched GitHub for existing "qatomic_" users but there seem to be none.
      
      This patch was generated using:
      
        $ git grep -h -o '\<atomic\(64\)\?_[a-z0-9_]\+' include/qemu/atomic.h | \
          sort -u >/tmp/changed_identifiers
        $ for identifier in $(</tmp/changed_identifiers); do
              sed -i "s%\<$identifier\>%q$identifier%g" \
                  $(git grep -I -l "\<$identifier\>")
          done
      
      I manually fixed line-wrap issues and misaligned rST tables.
      
      Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
      Reviewed-by: default avatarPhilippe Mathieu-Daudé <philmd@redhat.com>
      Acked-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
      Message-Id: <20200923105646.47864-1-stefanha@redhat.com>
      d73415a3
  17. Sep 18, 2020
  18. Sep 17, 2020
  19. Sep 09, 2020
  20. Sep 01, 2020
  21. Aug 21, 2020
  22. Jul 21, 2020
  23. May 27, 2020
  24. May 15, 2020
    • Markus Armbruster's avatar
      qom: Drop parameter @errp of object_property_add() & friends · d2623129
      Markus Armbruster authored
      
      The only way object_property_add() can fail is when a property with
      the same name already exists.  Since our property names are all
      hardcoded, failure is a programming error, and the appropriate way to
      handle it is passing &error_abort.
      
      Same for its variants, except for object_property_add_child(), which
      additionally fails when the child already has a parent.  Parentage is
      also under program control, so this is a programming error, too.
      
      We have a bit over 500 callers.  Almost half of them pass
      &error_abort, slightly fewer ignore errors, one test case handles
      errors, and the remaining few callers pass them to their own callers.
      
      The previous few commits demonstrated once again that ignoring
      programming errors is a bad idea.
      
      Of the few ones that pass on errors, several violate the Error API.
      The Error ** argument must be NULL, &error_abort, &error_fatal, or a
      pointer to a variable containing NULL.  Passing an argument of the
      latter kind twice without clearing it in between is wrong: if the
      first call sets an error, it no longer points to NULL for the second
      call.  ich9_pm_add_properties(), sparc32_ledma_realize(),
      sparc32_dma_realize(), xilinx_axidma_realize(), xilinx_enet_realize()
      are wrong that way.
      
      When the one appropriate choice of argument is &error_abort, letting
      users pick the argument is a bad idea.
      
      Drop parameter @errp and assert the preconditions instead.
      
      There's one exception to "duplicate property name is a programming
      error": the way object_property_add() implements the magic (and
      undocumented) "automatic arrayification".  Don't drop @errp there.
      Instead, rename object_property_add() to object_property_try_add(),
      and add the obvious wrapper object_property_add().
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Reviewed-by: default avatarEric Blake <eblake@redhat.com>
      Reviewed-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
      Message-Id: <20200505152926.18877-15-armbru@redhat.com>
      [Two semantic rebase conflicts resolved]
      d2623129
  25. Mar 16, 2020
    • Christophe de Dinechin's avatar
      scsi/qemu-pr-helper: Fix out-of-bounds access to trnptid_list[] · 4ce1e15f
      Christophe de Dinechin authored
      
      Compile error reported by gcc 10.0.1:
      
      scsi/qemu-pr-helper.c: In function ‘multipath_pr_out’:
      scsi/qemu-pr-helper.c:523:32: error: array subscript <unknown> is outside array bounds of ‘struct transportid *[0]’ [-Werror=array-bounds]
        523 |             paramp.trnptid_list[paramp.num_transportid++] = id;
            |             ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
      In file included from scsi/qemu-pr-helper.c:36:
      /usr/include/mpath_persist.h:168:22: note: while referencing ‘trnptid_list’
        168 |  struct transportid *trnptid_list[];
            |                      ^~~~~~~~~~~~
      scsi/qemu-pr-helper.c:424:35: note: defined here ‘paramp’
        424 |     struct prout_param_descriptor paramp;
            |                                   ^~~~~~
      
      This highlights an actual implementation issue in function multipath_pr_out.
      The variable paramp is declared with type `struct prout_param_descriptor`,
      which is a struct terminated by an empty array in mpath_persist.h:
      
              struct transportid *trnptid_list[];
      
      That empty array was filled with code that looked like that:
      
              trnptid_list[paramp.descr.num_transportid++] = id;
      
      This is an actual out-of-bounds access.
      
      The fix is to malloc `paramp`.
      
      Signed-off-by: default avatarChristophe de Dinechin <dinechin@redhat.com>
      Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
      4ce1e15f
  26. Dec 17, 2019
  27. Oct 03, 2019
    • Maxim Levitsky's avatar
      qemu-pr-helper: fix crash in mpath_reconstruct_sense · b2aca78c
      Maxim Levitsky authored
      The 'r' variable was accidently shadowed, and because of this
      we were always passing 0 to mpath_generic_sense, instead of original
      return value, which triggers an abort()
      
      This is an attempt to fix the
      https://bugzilla.redhat.com/show_bug.cgi?id=1720047
      
      
      although there might be other places in the code
      that trigger qemu-pr-helper crash, and this fix might
      not be the root cause.
      
      The crash was reproduced by creating an iscsi target on a test machine,
      and passing it twice to the guest like that:
      
      -blockdev node-name=idisk0,driver=iscsi,transport=...,target=...
      -device scsi-block,drive=idisk0,bus=scsi0.0,bootindex=-1,scsi-id=1,lun=0,share-rw=on
      -device scsi-block,drive=idisk0,bus=scsi0.0,bootindex=-1,scsi-id=1,lun=1,share-rw=on
      
      Then in the guest, both /dev/sda and /dev/sdb were aggregated by multipath to /dev/mpatha,
      which was passed to a nested guest like that
      
      -object pr-manager-helper,id=qemu_pr_helper,path=/root/work/vm/testvm/.run/pr_helper.socket
      -blockdev node-name=test,driver=host_device,filename=/dev/mapper/mpatha,pr-manager=qemu_pr_helper
      -device scsi-block,drive=test,bus=scsi0.0,bootindex=-1,scsi-id=0,lun=0
      
      The nested guest run:
      
      sg_persist --no-inquiry  -v --out --register --param-sark 0x1234 /dev/sda
      
      Strictly speaking this is wrong configuration since qemu is where
      the multipath was split, and thus the iscsi target was not aware of
      multipath, and thus when libmpathpersist code rightfully tried to register
      the PR key on all paths, it failed to do so.
      
      However qemu-pr-helper should not crash in this case.
      
      Signed-off-by: default avatarMaxim Levitsky <mlevitsk@redhat.com>
      Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
      b2aca78c
  28. Sep 10, 2019
  29. Sep 03, 2019
  30. Jul 15, 2019
  31. Jun 12, 2019
    • Markus Armbruster's avatar
      Include qemu-common.h exactly where needed · a8d25326
      Markus Armbruster authored
      
      No header includes qemu-common.h after this commit, as prescribed by
      qemu-common.h's file comment.
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Message-Id: <20190523143508.25387-5-armbru@redhat.com>
      [Rebased with conflicts resolved automatically, except for
      include/hw/arm/xlnx-zynqmp.h hw/arm/nrf51_soc.c hw/arm/msf2-soc.c
      block/qcow2-refcount.c block/qcow2-cluster.c block/qcow2-cache.c
      target/arm/cpu.h target/lm32/cpu.h target/m68k/cpu.h target/mips/cpu.h
      target/moxie/cpu.h target/nios2/cpu.h target/openrisc/cpu.h
      target/riscv/cpu.h target/tilegx/cpu.h target/tricore/cpu.h
      target/unicore32/cpu.h target/xtensa/cpu.h; bsd-user/main.c and
      net/tap-bsd.c fixed up]
      a8d25326
    • Markus Armbruster's avatar
      Include qemu/module.h where needed, drop it from qemu-common.h · 0b8fa32f
      Markus Armbruster authored
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Message-Id: <20190523143508.25387-4-armbru@redhat.com>
      [Rebased with conflicts resolved automatically, except for
      hw/usb/dev-hub.c hw/misc/exynos4210_rng.c hw/misc/bcm2835_rng.c
      hw/misc/aspeed_scu.c hw/display/virtio-vga.c hw/arm/stm32f205_soc.c;
      ui/cocoa.m fixed up]
      0b8fa32f
Loading