From: Elysia Witham <elysia.wit...@ll.mit.edu> The new QPP API allows plugin-to-plugin interaction for creating and using callbacks as well as importing and exporting functions. The new test plugins qpp_srv and qpp_client demonstrate how plugins use the new API.
Signed-off-by: Elysia Witham <elysia.wit...@ll.mit.edu> Signed-off-by: Andrew Fasano <fas...@mit.edu> --- docs/devel/tcg-plugins.rst | 91 +++++++++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) diff --git a/docs/devel/tcg-plugins.rst b/docs/devel/tcg-plugins.rst index 9740a70406..70ac09b96b 100644 --- a/docs/devel/tcg-plugins.rst +++ b/docs/devel/tcg-plugins.rst @@ -281,6 +281,14 @@ run:: 160 1 0 135 1 0 +- tests/plugins/qpp_srv.c & tests/plugins/qpp_client.c + +These plugins demonstrate QPP interactions. The qpp_srv plugin defines +a few exported functions and its own callback which are then imported and +used by the qpp_client plugin. The qpp_client plugin registers its own +function to run on qpp_srv's defined callback. The tests for these plugins +are modified as both plugins must be loaded in order to work. + - contrib/plugins/hotblocks.c The hotblocks plugin allows you to examine the where hot paths of @@ -573,6 +581,88 @@ The plugin has a number of arguments, all of them are optional: configuration arguments implies ``l2=on``. (default: N = 2097152 (2MB), B = 64, A = 16) +Plugin-to-Plugin Interactions +----------------------------- + +Plugins may interact with other plugins through the QEMU Plugin-to-Plugin +("QPP") API by including ``<plugin-qpp.h>`` in addition to ``<qemu_plugin.h>``. +This API supports direct function calls between plugins. An inter-plugin +callback system is supported within the core code as long as +``qemu_plugin_version >= 2``. + +Plugin names +~~~~~~~~~~~~ +Plugin names must be exported as ``qemu_plugin_name`` to use the QPP API in the same way +``qemu_plugin_version`` is exported. This name can then be used by other plugins +to import functions and use callbacks belonging to that plugin. + +Plugin dependencies +~~~~~~~~~~~~~~~~~~~ +For a plugin to use another plugin's functions or callbacks it must declare that +dependency through exporting ``qemu_plugin_uses`` which is a string array containing +names of plugins used by that plugin. Those plugins must be loaded first. Note that this +array must be null terminated, e.g. ``{plugin_a, NULL}``. + +QPP function calls +~~~~~~~~~~~~~~~~~~ +When a plugin (e.g., ``plugin_a``) wishes to make some of its functions (e.g., +``func_1``) available to other plugins, it must: + +1. Mark the function definition with the ``QEMU_PLUGIN_EXPORT`` macro. For +example : ``QEMU_PLUGIN_EXPORT int func_1(int x) {...}`` +2. Provide prototypes for exported functions in a header file using the macro +``QPP_FUN_PROTOTYPE`` with arguments of the plugin's name, the function's +return type, the function's name, and any arguments the function takes. For +example: ``QPP_FUN_PROTOTYPE(my_plugin, int, do_add, int);``. +3. Import this header from the plugin. + +When other plugins wish to use the functions exported by ``plugin_a``, they +must: + +1. Import the header file with the function prototype(s). +2. Call the function when desired by combining the target plugin name, an + underscore, and the target function name with ``_qpp`` on the end, + e.g., ``plugin_a_func_1_qpp()``. + +QPP callbacks +~~~~~~~~~~~~~ + +The QPP API also allows a plugin to define callback events and for other plugins +to request to be notified whenever these events happens. The plugin that defines +the callback is responsible for triggering the callback when it so wishes. Other +plugins that wish to be notified on these events must define a function of an +appropriate type and register it to run on this event. +In particular, these plugins must: + + +When a plugin (e.g., ``plugin_a``) wishes to define a callback (an event that +other plugins can request to be notified about), it must: + +1. Define the callback using the ``qemu_plugin_create_callback`` function which + takes two arguments: the unique ``qemu_plugin_id_t id`` and the callback name. +2. Call ``qemu_plugin_run_callback`` at appropriate places in the code to call registered + callback functions. It takes four arguments: the unique ``qemu_plugin_id_t id``, + the callback name, and the callback arguments which are standardized to be + ``gpointer evdata, gpointer udata``. The callback arguments point to two structs + which are defined by the plugin and can vary based on the use case of the callback. + +When other plugins wish to register a function to run on such an event, they +must: + +1. Define a function that matches the ``cb_func_t`` type: + ``typedef void (*cb_func_t) (gpointer evdata, gpointer udata)``. +2. Register this function to be run on the plugin defined callback using + ``qemu_plugin_reg_callback``. This function takes three arguments: the name of the + plugin which defines the callback, the callback name, and a ``cb_func_t`` function + pointer. + +When other plugins wish to unregister a function which is registered to run on a plugin +defined event callback, they must: + +1. Call ``qemu_plugin_unreg_callback``. This function takes the same arguments as + ``qemu_plugin_reg_callback``. It will return true if it successfully finds and + unregisters the function. + API --- @@ -581,4 +671,3 @@ The following API is generated from the inline documentation in include the full kernel-doc annotations. .. kernel-doc:: include/qemu/qemu-plugin.h - -- 2.34.1