Features/CoroutineFnCleanup: Difference between revisions

From QEMU
No edit summary
Line 1: Line 1:
== Hand-written bdrv_co_* functions ==
== Hand-written bdrv_co_* functions ==
# bdrv_pread/bdrv_pwrite have different calling convention than bdrv_co_pread/bdrv_co_pwrite
# bdrv_pread/bdrv_pwrite have different calling convention than bdrv_co_pread/bdrv_co_pwrite
#* Fix using Coccinelle?
#* Fix using Coccinelle
#* Switch bdrv_pread/bdrv_pwrite to generated_co_wrapper
# Missing bdrv_co_pwrite_sync, bdrv_co_pwrite_zeroes
# Missing bdrv_co_pwrite_sync, bdrv_co_pwrite_zeroes
#* Adjust code in block/io.c and introduce generated_co_wrapper
#* Adjust code in block/io.c and introduce generated_co_wrapper

Revision as of 11:16, 9 May 2022

Hand-written bdrv_co_* functions

  1. bdrv_pread/bdrv_pwrite have different calling convention than bdrv_co_pread/bdrv_co_pwrite
    • Fix using Coccinelle
    • Switch bdrv_pread/bdrv_pwrite to generated_co_wrapper
  2. Missing bdrv_co_pwrite_sync, bdrv_co_pwrite_zeroes
    • Adjust code in block/io.c and introduce generated_co_wrapper
  3. Probably more will be found with custom matching tools (see below)

Annotations

  1. Add coroutine_mixed_fn annotation; functions that call qemu_in_coroutine(). Includes:
    • all generated_co_wrapper functions
    • bdrv_create
    • bdrv_can_store_new_dirty_bitmap, bdrv_remove_persistent_dirty_bitmap
    • bdrv_drain_all_begin, bdrv_do_drained_begin, bdrv_do_drained_end
    • qio_channel_readv_full_all_eof, qio_channel_writev_full
    • qcow2_open, qcow2_has_zero_init
    • bdrv_qed_open
    • qmp_dispatch
    • nvme_get_free_req
    • schedule_next_request
  2. Detect call from non-coroutine_fn/coroutine_mixed_fn to coroutine_fn (libclang/clang-tidy)
    • Remove coroutine_fn from callee
    • Possibly add fixit to rewrite
  3. Detect call from coroutine_fn to coroutine_mixed_fn (libclang/clang-tidy)
    • Use _co_ version instead.
    • Possibly add fixit to rewrite

Clang-query examples

Invoking clang-query:

  1. Change definition of coroutine_fn to #define coroutine_fn __attribute__((annotate("coroutine")))
  2. Invoke clang-query -p build-path block/io.c

Example of clang-query uses:

match functionDecl(allOf(unless(hasAttr("attr::Annotate")),hasDescendant(callExpr(callee(hasAttr("attr::Annotate"))).bind("callee"))))
call from non-coroutine_fn to coroutine_fn (doesn't actually check the string in the annotate attribute)
match varDecl(hasType(namedDecl(hasName("BlockDriver"))), hasInitializer(anything()))
declaration of BlockDriver struct, with initializer
match functionDecl(isExpansionInMainFile(), forEachDescendant(callExpr(callee(unless(functionDecl()))).bind("call"))).bind("root")'
indirect call

Clang references

https://devblogs.microsoft.com/cppblog/exploring-clang-tooling-part-1-extending-clang-tidy/

https://devblogs.microsoft.com/cppblog/exploring-clang-tooling-part-2-examining-the-clang-ast-with-clang-query/

https://devblogs.microsoft.com/cppblog/exploring-clang-tooling-part-3-rewriting-code-with-clang-tidy/