1ced6b2d1SRay Kinsella.. SPDX-License-Identifier: BSD-3-Clause 2ced6b2d1SRay Kinsella Copyright 2018 The DPDK contributors 3ced6b2d1SRay Kinsella 4144beafcSRay Kinsella.. _abi_versioning: 5ced6b2d1SRay Kinsella 6144beafcSRay KinsellaABI Versioning 7144beafcSRay Kinsella============== 8144beafcSRay Kinsella 9144beafcSRay KinsellaThis document details the mechanics of ABI version management in DPDK. 10144beafcSRay Kinsella 11144beafcSRay Kinsella.. _what_is_soname: 12144beafcSRay Kinsella 13144beafcSRay KinsellaWhat is a library's soname? 14144beafcSRay Kinsella--------------------------- 15144beafcSRay Kinsella 16144beafcSRay KinsellaSystem libraries usually adopt the familiar major and minor version naming 1723b4fd82SRay Kinsellaconvention, where major versions (e.g. ``librte_eal 21.x, 22.x``) are presumed 18144beafcSRay Kinsellato be ABI incompatible with each other and minor versions (e.g. ``librte_eal 1923b4fd82SRay Kinsella21.1, 21.2``) are presumed to be ABI compatible. A library's `soname 20144beafcSRay Kinsella<https://en.wikipedia.org/wiki/Soname>`_. is typically used to provide backward 21144beafcSRay Kinsellacompatibility information about a given library, describing the lowest common 22144beafcSRay Kinselladenominator ABI supported by the library. The soname or logical name for the 23144beafcSRay Kinsellalibrary, is typically comprised of the library's name and major version e.g. 2423b4fd82SRay Kinsella``librte_eal.so.21``. 25144beafcSRay Kinsella 26144beafcSRay KinsellaDuring an application's build process, a library's soname is noted as a runtime 27144beafcSRay Kinselladependency of the application. This information is then used by the `dynamic 28144beafcSRay Kinsellalinker <https://en.wikipedia.org/wiki/Dynamic_linker>`_ when resolving the 29144beafcSRay Kinsellaapplications dependencies at runtime, to load a library supporting the correct 30144beafcSRay KinsellaABI version. The library loaded at runtime therefore, may be a minor revision 3123b4fd82SRay Kinsellasupporting the same major ABI version (e.g. ``librte_eal.21.2``), as the library 3223b4fd82SRay Kinsellaused to link the application (e.g ``librte_eal.21.0``). 33144beafcSRay Kinsella 34144beafcSRay Kinsella.. _major_abi_versions: 35144beafcSRay Kinsella 36144beafcSRay KinsellaMajor ABI versions 37ced6b2d1SRay Kinsella------------------ 38ced6b2d1SRay Kinsella 39144beafcSRay KinsellaAn ABI version change to a given library, especially in core libraries such as 40144beafcSRay Kinsella``librte_mbuf``, may cause an implicit ripple effect on the ABI of it's 41144beafcSRay Kinsellaconsuming libraries, causing ABI breakages. There may however be no explicit 42144beafcSRay Kinsellareason to bump a dependent library's ABI version, as there may have been no 43144beafcSRay Kinsellaobvious change to the dependent library's API, even though the library's ABI 44144beafcSRay Kinsellacompatibility will have been broken. 45ced6b2d1SRay Kinsella 46144beafcSRay KinsellaThis interdependence of DPDK libraries, means that ABI versioning of libraries 47144beafcSRay Kinsellais more manageable at a project level, with all project libraries sharing a 48144beafcSRay Kinsella**single ABI version**. In addition, the need to maintain a stable ABI for some 49144beafcSRay Kinsellanumber of releases as described in the section :doc:`abi_policy`, means 50144beafcSRay Kinsellathat ABI version increments need to carefully planned and managed at a project 51144beafcSRay Kinsellalevel. 52ced6b2d1SRay Kinsella 53144beafcSRay KinsellaMajor ABI versions are therefore declared typically aligned with an LTS release 54144beafcSRay Kinsellaand is then supported some number of subsequent releases, shared across all 55144beafcSRay Kinsellalibraries. This means that a single project level ABI version, reflected in all 56144beafcSRay Kinsellaindividual library's soname, library filenames and associated version maps 57144beafcSRay Kinsellapersists over multiple releases. 58ced6b2d1SRay Kinsella 59144beafcSRay Kinsella.. code-block:: none 60ced6b2d1SRay Kinsella 6199a2dd95SBruce Richardson $ head ./lib/acl/version.map 6223b4fd82SRay Kinsella DPDK_21 { 63144beafcSRay Kinsella global: 64144beafcSRay Kinsella ... 65ced6b2d1SRay Kinsella 6699a2dd95SBruce Richardson $ head ./lib/eal/version.map 6723b4fd82SRay Kinsella DPDK_21 { 68144beafcSRay Kinsella global: 69144beafcSRay Kinsella ... 70ced6b2d1SRay Kinsella 71144beafcSRay KinsellaWhen an ABI change is made between major ABI versions to a given library, a new 72144beafcSRay Kinsellasection is added to that library's version map describing the impending new ABI 73144beafcSRay Kinsellaversion, as described in the section :ref:`example_abi_macro_usage`. The 7423b4fd82SRay Kinsellalibrary's soname and filename however do not change, e.g. ``libacl.so.21``, as 75144beafcSRay KinsellaABI compatibility with the last major ABI version continues to be preserved for 76144beafcSRay Kinsellathat library. 77ced6b2d1SRay Kinsella 78144beafcSRay Kinsella.. code-block:: none 79144beafcSRay Kinsella 8099a2dd95SBruce Richardson $ head ./lib/acl/version.map 8123b4fd82SRay Kinsella DPDK_21 { 82144beafcSRay Kinsella global: 83144beafcSRay Kinsella ... 84144beafcSRay Kinsella 8523b4fd82SRay Kinsella DPDK_22 { 86144beafcSRay Kinsella global: 87144beafcSRay Kinsella 8823b4fd82SRay Kinsella } DPDK_21; 89144beafcSRay Kinsella ... 90144beafcSRay Kinsella 9199a2dd95SBruce Richardson $ head ./lib/eal/version.map 9223b4fd82SRay Kinsella DPDK_21 { 93144beafcSRay Kinsella global: 94144beafcSRay Kinsella ... 95144beafcSRay Kinsella 9623b4fd82SRay KinsellaHowever when a new ABI version is declared, for example DPDK ``22``, old 97*98afdb15SStephen Colemandeprecated functions may be safely removed at this point and the entire old 98144beafcSRay Kinsellamajor ABI version removed, see the section :ref:`deprecating_entire_abi` on 99144beafcSRay Kinsellahow this may be done. 100144beafcSRay Kinsella 101144beafcSRay Kinsella.. code-block:: none 102144beafcSRay Kinsella 10399a2dd95SBruce Richardson $ head ./lib/acl/version.map 10423b4fd82SRay Kinsella DPDK_22 { 105144beafcSRay Kinsella global: 106144beafcSRay Kinsella ... 107144beafcSRay Kinsella 10899a2dd95SBruce Richardson $ head ./lib/eal/version.map 10923b4fd82SRay Kinsella DPDK_22 { 110144beafcSRay Kinsella global: 111144beafcSRay Kinsella ... 112144beafcSRay Kinsella 113144beafcSRay KinsellaAt the same time, the major ABI version is changed atomically across all 114cba806e0SMarcin Baranlibraries by incrementing the major version in the ABI_VERSION file. This is 1157762e013SDavid Marchanddone globally for all libraries. 116144beafcSRay Kinsella 117cba806e0SMarcin BaranMinor ABI versions 118cba806e0SMarcin Baran~~~~~~~~~~~~~~~~~~ 119144beafcSRay Kinsella 120cba806e0SMarcin BaranEach non-LTS release will also increment minor ABI version, to permit multiple 121cba806e0SMarcin BaranDPDK versions being installed alongside each other. Both stable and 122cba806e0SMarcin Baranexperimental ABI's are versioned using the global version file that is updated 123cba806e0SMarcin Baranat the start of each release cycle, and are managed at the project level. 124ced6b2d1SRay Kinsella 125ced6b2d1SRay KinsellaVersioning Macros 126144beafcSRay Kinsella----------------- 127ced6b2d1SRay Kinsella 128ced6b2d1SRay KinsellaWhen a symbol is exported from a library to provide an API, it also provides a 129ced6b2d1SRay Kinsellacalling convention (ABI) that is embodied in its name, return type and 130ced6b2d1SRay Kinsellaarguments. Occasionally that function may need to change to accommodate new 131144beafcSRay Kinsellafunctionality or behavior. When that occurs, it is may be required to allow for 132ced6b2d1SRay Kinsellabackward compatibility for a time with older binaries that are dynamically 133ced6b2d1SRay Kinsellalinked to the DPDK. 134ced6b2d1SRay Kinsella 135ced6b2d1SRay KinsellaTo support backward compatibility the ``rte_function_versioning.h`` 136ced6b2d1SRay Kinsellaheader file provides macros to use when updating exported functions. These 1376b3848e2SDavid Marchandmacros are used in conjunction with the ``version.map`` file for 138ced6b2d1SRay Kinsellaa given library to allow multiple versions of a symbol to exist in a shared 139ced6b2d1SRay Kinsellalibrary so that older binaries need not be immediately recompiled. 140ced6b2d1SRay Kinsella 141ced6b2d1SRay KinsellaThe macros exported are: 142ced6b2d1SRay Kinsella 143ced6b2d1SRay Kinsella* ``VERSION_SYMBOL(b, e, n)``: Creates a symbol version table entry binding 144ced6b2d1SRay Kinsella versioned symbol ``b@DPDK_n`` to the internal function ``be``. 145ced6b2d1SRay Kinsella 146ced6b2d1SRay Kinsella* ``BIND_DEFAULT_SYMBOL(b, e, n)``: Creates a symbol version entry instructing 147ced6b2d1SRay Kinsella the linker to bind references to symbol ``b`` to the internal symbol 148ced6b2d1SRay Kinsella ``be``. 149ced6b2d1SRay Kinsella 150ced6b2d1SRay Kinsella* ``MAP_STATIC_SYMBOL(f, p)``: Declare the prototype ``f``, and map it to the 151ced6b2d1SRay Kinsella fully qualified function ``p``, so that if a symbol becomes versioned, it 152ced6b2d1SRay Kinsella can still be mapped back to the public symbol name. 153ced6b2d1SRay Kinsella 154ced6b2d1SRay Kinsella* ``__vsym``: Annotation to be used in a declaration of the internal symbol 155ced6b2d1SRay Kinsella ``be`` to signal that it is being used as an implementation of a particular 156ced6b2d1SRay Kinsella version of symbol ``b``. 157ced6b2d1SRay Kinsella 15805a38d7cSFerruh Yigit* ``VERSION_SYMBOL_EXPERIMENTAL(b, e)``: Creates a symbol version table entry 15905a38d7cSFerruh Yigit binding versioned symbol ``b@EXPERIMENTAL`` to the internal function ``be``. 16005a38d7cSFerruh Yigit The macro is used when a symbol matures to become part of the stable ABI, to 16106df45afSRay Kinsella provide an alias to experimental until the next major ABI version. 16205a38d7cSFerruh Yigit 163144beafcSRay Kinsella.. _example_abi_macro_usage: 164144beafcSRay Kinsella 165ced6b2d1SRay KinsellaExamples of ABI Macro use 166144beafcSRay Kinsella~~~~~~~~~~~~~~~~~~~~~~~~~ 167ced6b2d1SRay Kinsella 168ced6b2d1SRay KinsellaUpdating a public API 169ced6b2d1SRay Kinsella_____________________ 170ced6b2d1SRay Kinsella 171ced6b2d1SRay KinsellaAssume we have a function as follows 172ced6b2d1SRay Kinsella 173ced6b2d1SRay Kinsella.. code-block:: c 174ced6b2d1SRay Kinsella 175ced6b2d1SRay Kinsella /* 176ced6b2d1SRay Kinsella * Create an acl context object for apps to 177ced6b2d1SRay Kinsella * manipulate 178ced6b2d1SRay Kinsella */ 179ced6b2d1SRay Kinsella struct rte_acl_ctx * 180ced6b2d1SRay Kinsella rte_acl_create(const struct rte_acl_param *param) 181ced6b2d1SRay Kinsella { 182ced6b2d1SRay Kinsella ... 183ced6b2d1SRay Kinsella } 184ced6b2d1SRay Kinsella 185ced6b2d1SRay Kinsella 186ced6b2d1SRay KinsellaAssume that struct rte_acl_ctx is a private structure, and that a developer 187ced6b2d1SRay Kinsellawishes to enhance the acl api so that a debugging flag can be enabled on a 188ced6b2d1SRay Kinsellaper-context basis. This requires an addition to the structure (which, being 189ced6b2d1SRay Kinsellaprivate, is safe), but it also requires modifying the code as follows 190ced6b2d1SRay Kinsella 191ced6b2d1SRay Kinsella.. code-block:: c 192ced6b2d1SRay Kinsella 193ced6b2d1SRay Kinsella /* 194ced6b2d1SRay Kinsella * Create an acl context object for apps to 195ced6b2d1SRay Kinsella * manipulate 196ced6b2d1SRay Kinsella */ 197ced6b2d1SRay Kinsella struct rte_acl_ctx * 198ced6b2d1SRay Kinsella rte_acl_create(const struct rte_acl_param *param, int debug) 199ced6b2d1SRay Kinsella { 200ced6b2d1SRay Kinsella ... 201ced6b2d1SRay Kinsella } 202ced6b2d1SRay Kinsella 203ced6b2d1SRay Kinsella 204ced6b2d1SRay KinsellaNote also that, being a public function, the header file prototype must also be 205ced6b2d1SRay Kinsellachanged, as must all the call sites, to reflect the new ABI footprint. We will 206ced6b2d1SRay Kinsellamaintain previous ABI versions that are accessible only to previously compiled 20745a4103eSRay Kinsellabinaries. 208ced6b2d1SRay Kinsella 209ced6b2d1SRay KinsellaThe addition of a parameter to the function is ABI breaking as the function is 210ced6b2d1SRay Kinsellapublic, and existing application may use it in its current form. However, the 211ced6b2d1SRay Kinsellacompatibility macros in DPDK allow a developer to use symbol versioning so that 212ced6b2d1SRay Kinsellamultiple functions can be mapped to the same public symbol based on when an 213ced6b2d1SRay Kinsellaapplication was linked to it. To see how this is done, we start with the 214144beafcSRay Kinsellarequisite libraries version map file. Initially the version map file for the acl 215144beafcSRay Kinsellalibrary looks like this 216ced6b2d1SRay Kinsella 217ced6b2d1SRay Kinsella.. code-block:: none 218ced6b2d1SRay Kinsella 21923b4fd82SRay Kinsella DPDK_21 { 220ced6b2d1SRay Kinsella global: 221ced6b2d1SRay Kinsella 222ced6b2d1SRay Kinsella rte_acl_add_rules; 223ced6b2d1SRay Kinsella rte_acl_build; 224ced6b2d1SRay Kinsella rte_acl_classify; 225ced6b2d1SRay Kinsella rte_acl_classify_alg; 226ced6b2d1SRay Kinsella rte_acl_classify_scalar; 227ced6b2d1SRay Kinsella rte_acl_create; 228ced6b2d1SRay Kinsella rte_acl_dump; 229ced6b2d1SRay Kinsella rte_acl_find_existing; 230ced6b2d1SRay Kinsella rte_acl_free; 231ced6b2d1SRay Kinsella rte_acl_ipv4vlan_add_rules; 232ced6b2d1SRay Kinsella rte_acl_ipv4vlan_build; 233ced6b2d1SRay Kinsella rte_acl_list_dump; 234ced6b2d1SRay Kinsella rte_acl_reset; 235ced6b2d1SRay Kinsella rte_acl_reset_rules; 236ced6b2d1SRay Kinsella rte_acl_set_ctx_classify; 237ced6b2d1SRay Kinsella 238ced6b2d1SRay Kinsella local: *; 239ced6b2d1SRay Kinsella }; 240ced6b2d1SRay Kinsella 241ced6b2d1SRay KinsellaThis file needs to be modified as follows 242ced6b2d1SRay Kinsella 243ced6b2d1SRay Kinsella.. code-block:: none 244ced6b2d1SRay Kinsella 24523b4fd82SRay Kinsella DPDK_21 { 246ced6b2d1SRay Kinsella global: 247ced6b2d1SRay Kinsella 248ced6b2d1SRay Kinsella rte_acl_add_rules; 249ced6b2d1SRay Kinsella rte_acl_build; 250ced6b2d1SRay Kinsella rte_acl_classify; 251ced6b2d1SRay Kinsella rte_acl_classify_alg; 252ced6b2d1SRay Kinsella rte_acl_classify_scalar; 253ced6b2d1SRay Kinsella rte_acl_create; 254ced6b2d1SRay Kinsella rte_acl_dump; 255ced6b2d1SRay Kinsella rte_acl_find_existing; 256ced6b2d1SRay Kinsella rte_acl_free; 257ced6b2d1SRay Kinsella rte_acl_ipv4vlan_add_rules; 258ced6b2d1SRay Kinsella rte_acl_ipv4vlan_build; 259ced6b2d1SRay Kinsella rte_acl_list_dump; 260ced6b2d1SRay Kinsella rte_acl_reset; 261ced6b2d1SRay Kinsella rte_acl_reset_rules; 262ced6b2d1SRay Kinsella rte_acl_set_ctx_classify; 263ced6b2d1SRay Kinsella 264ced6b2d1SRay Kinsella local: *; 265ced6b2d1SRay Kinsella }; 266ced6b2d1SRay Kinsella 26723b4fd82SRay Kinsella DPDK_22 { 268ced6b2d1SRay Kinsella global: 269ced6b2d1SRay Kinsella rte_acl_create; 270ced6b2d1SRay Kinsella 27123b4fd82SRay Kinsella } DPDK_21; 272ced6b2d1SRay Kinsella 27345a4103eSRay KinsellaThe addition of the new block tells the linker that a new version node 27423b4fd82SRay Kinsella``DPDK_22`` is available, which contains the symbol rte_acl_create, and inherits 27523b4fd82SRay Kinsellathe symbols from the DPDK_21 node. This list is directly translated into a 27645a4103eSRay Kinsellalist of exported symbols when DPDK is compiled as a shared library. 277ced6b2d1SRay Kinsella 27845a4103eSRay KinsellaNext, we need to specify in the code which function maps to the rte_acl_create 279ced6b2d1SRay Kinsellasymbol at which versions. First, at the site of the initial symbol definition, 280ced6b2d1SRay Kinsellawe need to update the function so that it is uniquely named, and not in conflict 281ced6b2d1SRay Kinsellawith the public symbol name 282ced6b2d1SRay Kinsella 283ced6b2d1SRay Kinsella.. code-block:: c 284ced6b2d1SRay Kinsella 285ced6b2d1SRay Kinsella -struct rte_acl_ctx * 286ced6b2d1SRay Kinsella -rte_acl_create(const struct rte_acl_param *param) 287ced6b2d1SRay Kinsella +struct rte_acl_ctx * __vsym 28823b4fd82SRay Kinsella +rte_acl_create_v21(const struct rte_acl_param *param) 289ced6b2d1SRay Kinsella { 290ced6b2d1SRay Kinsella size_t sz; 291ced6b2d1SRay Kinsella struct rte_acl_ctx *ctx; 292ced6b2d1SRay Kinsella ... 293ced6b2d1SRay Kinsella 294ced6b2d1SRay KinsellaNote that the base name of the symbol was kept intact, as this is conducive to 29545a4103eSRay Kinsellathe macros used for versioning symbols and we have annotated the function as 29645a4103eSRay Kinsella``__vsym``, an implementation of a versioned symbol . That is our next step, 29723b4fd82SRay Kinsellamapping this new symbol name to the initial symbol name at version node 21. 29845a4103eSRay KinsellaImmediately after the function, we add the VERSION_SYMBOL macro. 299ced6b2d1SRay Kinsella 300ced6b2d1SRay Kinsella.. code-block:: c 301ced6b2d1SRay Kinsella 30245a4103eSRay Kinsella #include <rte_function_versioning.h> 30345a4103eSRay Kinsella 30445a4103eSRay Kinsella ... 30523b4fd82SRay Kinsella VERSION_SYMBOL(rte_acl_create, _v21, 21); 306ced6b2d1SRay Kinsella 307144beafcSRay KinsellaRemembering to also add the rte_function_versioning.h header to the requisite c 30845a4103eSRay Kinsellafile where these changes are being made. The macro instructs the linker to 30923b4fd82SRay Kinsellacreate a new symbol ``rte_acl_create@DPDK_21``, which matches the symbol created 310144beafcSRay Kinsellain older builds, but now points to the above newly named function. We have now 311144beafcSRay Kinsellamapped the original rte_acl_create symbol to the original function (but with a 312144beafcSRay Kinsellanew name). 313ced6b2d1SRay Kinsella 31445a4103eSRay KinsellaPlease see the section :ref:`Enabling versioning macros 31545a4103eSRay Kinsella<enabling_versioning_macros>` to enable this macro in the meson/ninja build. 31623b4fd82SRay KinsellaNext, we need to create the new ``v22`` version of the symbol. We create a new 31723b4fd82SRay Kinsellafunction name, with the ``v22`` suffix, and implement it appropriately. 318ced6b2d1SRay Kinsella 319ced6b2d1SRay Kinsella.. code-block:: c 320ced6b2d1SRay Kinsella 321ced6b2d1SRay Kinsella struct rte_acl_ctx * __vsym 32223b4fd82SRay Kinsella rte_acl_create_v22(const struct rte_acl_param *param, int debug); 323ced6b2d1SRay Kinsella { 32423b4fd82SRay Kinsella struct rte_acl_ctx *ctx = rte_acl_create_v21(param); 325ced6b2d1SRay Kinsella 326ced6b2d1SRay Kinsella ctx->debug = debug; 327ced6b2d1SRay Kinsella 328ced6b2d1SRay Kinsella return ctx; 329ced6b2d1SRay Kinsella } 330ced6b2d1SRay Kinsella 331144beafcSRay KinsellaThis code serves as our new API call. Its the same as our old call, but adds the 33245a4103eSRay Kinsellanew parameter in place. Next we need to map this function to the new default 33323b4fd82SRay Kinsellasymbol ``rte_acl_create@DPDK_22``. To do this, immediately after the function, 33445a4103eSRay Kinsellawe add the BIND_DEFAULT_SYMBOL macro. 33545a4103eSRay Kinsella 33645a4103eSRay Kinsella.. code-block:: c 33745a4103eSRay Kinsella 33845a4103eSRay Kinsella #include <rte_function_versioning.h> 33945a4103eSRay Kinsella 34045a4103eSRay Kinsella ... 34123b4fd82SRay Kinsella BIND_DEFAULT_SYMBOL(rte_acl_create, _v22, 22); 34245a4103eSRay Kinsella 34345a4103eSRay KinsellaThe macro instructs the linker to create the new default symbol 34423b4fd82SRay Kinsella``rte_acl_create@DPDK_22``, which points to the above newly named function. 34545a4103eSRay Kinsella 34645a4103eSRay KinsellaWe finally modify the prototype of the call in the public header file, 34745a4103eSRay Kinsellasuch that it contains both versions of the symbol and the public API. 348ced6b2d1SRay Kinsella 349ced6b2d1SRay Kinsella.. code-block:: c 350ced6b2d1SRay Kinsella 351ced6b2d1SRay Kinsella struct rte_acl_ctx * 35245a4103eSRay Kinsella rte_acl_create(const struct rte_acl_param *param); 353ced6b2d1SRay Kinsella 35445a4103eSRay Kinsella struct rte_acl_ctx * __vsym 35523b4fd82SRay Kinsella rte_acl_create_v21(const struct rte_acl_param *param); 356ced6b2d1SRay Kinsella 35745a4103eSRay Kinsella struct rte_acl_ctx * __vsym 35823b4fd82SRay Kinsella rte_acl_create_v22(const struct rte_acl_param *param, int debug); 35945a4103eSRay Kinsella 36045a4103eSRay Kinsella 36145a4103eSRay KinsellaAnd that's it, on the next shared library rebuild, there will be two versions of 36223b4fd82SRay Kinsellarte_acl_create, an old DPDK_21 version, used by previously built applications, 36323b4fd82SRay Kinsellaand a new DPDK_22 version, used by future built applications. 36445a4103eSRay Kinsella 36545a4103eSRay Kinsella.. note:: 36645a4103eSRay Kinsella 36745a4103eSRay Kinsella **Before you leave**, please take care reviewing the sections on 36845a4103eSRay Kinsella :ref:`mapping static symbols <mapping_static_symbols>`, 36945a4103eSRay Kinsella :ref:`enabling versioning macros <enabling_versioning_macros>`, 37045a4103eSRay Kinsella and :ref:`ABI deprecation <abi_deprecation>`. 37145a4103eSRay Kinsella 37245a4103eSRay Kinsella 37345a4103eSRay Kinsella.. _mapping_static_symbols: 37445a4103eSRay Kinsella 37545a4103eSRay KinsellaMapping static symbols 37645a4103eSRay Kinsella______________________ 37745a4103eSRay Kinsella 37845a4103eSRay KinsellaNow we've taken what was a public symbol, and duplicated it into two uniquely 37945a4103eSRay Kinsellaand differently named symbols. We've then mapped each of those back to the 38045a4103eSRay Kinsellapublic symbol ``rte_acl_create`` with different version tags. This only applies 38145a4103eSRay Kinsellato dynamic linking, as static linking has no notion of versioning. That leaves 38245a4103eSRay Kinsellathis code in a position of no longer having a symbol simply named 38345a4103eSRay Kinsella``rte_acl_create`` and a static build will fail on that missing symbol. 384ced6b2d1SRay Kinsella 385ced6b2d1SRay KinsellaTo correct this, we can simply map a function of our choosing back to the public 386ced6b2d1SRay Kinsellasymbol in the static build with the ``MAP_STATIC_SYMBOL`` macro. Generally the 387ced6b2d1SRay Kinsellaassumption is that the most recent version of the symbol is the one you want to 38823b4fd82SRay Kinsellamap. So, back in the C file where, immediately after ``rte_acl_create_v22`` is 389ced6b2d1SRay Kinselladefined, we add this 390ced6b2d1SRay Kinsella 391144beafcSRay Kinsella 392ced6b2d1SRay Kinsella.. code-block:: c 393ced6b2d1SRay Kinsella 394ced6b2d1SRay Kinsella struct rte_acl_ctx * __vsym 39523b4fd82SRay Kinsella rte_acl_create_v22(const struct rte_acl_param *param, int debug) 396ced6b2d1SRay Kinsella { 397ced6b2d1SRay Kinsella ... 398ced6b2d1SRay Kinsella } 39923b4fd82SRay Kinsella MAP_STATIC_SYMBOL(struct rte_acl_ctx *rte_acl_create(const struct rte_acl_param *param, int debug), rte_acl_create_v22); 400ced6b2d1SRay Kinsella 401ced6b2d1SRay KinsellaThat tells the compiler that, when building a static library, any calls to the 40223b4fd82SRay Kinsellasymbol ``rte_acl_create`` should be linked to ``rte_acl_create_v22`` 403ced6b2d1SRay Kinsella 404ced6b2d1SRay Kinsella 40545a4103eSRay Kinsella.. _enabling_versioning_macros: 40645a4103eSRay Kinsella 40745a4103eSRay KinsellaEnabling versioning macros 40845a4103eSRay Kinsella__________________________ 40945a4103eSRay Kinsella 41045a4103eSRay KinsellaFinally, we need to indicate to the :doc:`meson/ninja build system 41145a4103eSRay Kinsella<../prog_guide/build-sdk-meson>` to enable versioning macros when building the 41245a4103eSRay Kinsellalibrary or driver. In the libraries or driver where we have added symbol 41345a4103eSRay Kinsellaversioning, in the ``meson.build`` file we add the following 41445a4103eSRay Kinsella 415efdda86bSRaslan Darawsheh.. code-block:: none 41645a4103eSRay Kinsella 41745a4103eSRay Kinsella use_function_versioning = true 41845a4103eSRay Kinsella 41945a4103eSRay Kinsellaat the start of the head of the file. This will indicate to the tool-chain to 42070d2f421SThomas Monjalonenable the function version macros when building. 42145a4103eSRay Kinsella 42205a38d7cSFerruh Yigit 42305a38d7cSFerruh Yigit.. _aliasing_experimental_symbols: 42405a38d7cSFerruh Yigit 42505a38d7cSFerruh YigitAliasing experimental symbols 42605a38d7cSFerruh Yigit_____________________________ 42705a38d7cSFerruh Yigit 42805a38d7cSFerruh YigitIn situations in which an ``experimental`` symbol has been stable for some time, 42905a38d7cSFerruh Yigitand it becomes a candidate for promotion to the stable ABI. At this time, when 43006df45afSRay Kinsellapromoting the symbol, the maintainer may choose to provide an alias to the 43105a38d7cSFerruh Yigit``experimental`` symbol version, so as not to break consuming applications. 43206df45afSRay KinsellaThis alias is then dropped in the next major ABI version. 43305a38d7cSFerruh Yigit 43405a38d7cSFerruh YigitThe process to provide an alias to ``experimental`` is similar to that, of 43505a38d7cSFerruh Yigit:ref:`symbol versioning <example_abi_macro_usage>` described above. 43605a38d7cSFerruh YigitAssume we have an experimental function ``rte_acl_create`` as follows: 43705a38d7cSFerruh Yigit 43805a38d7cSFerruh Yigit.. code-block:: c 43905a38d7cSFerruh Yigit 44005a38d7cSFerruh Yigit #include <rte_compat.h> 44105a38d7cSFerruh Yigit 44205a38d7cSFerruh Yigit /* 44305a38d7cSFerruh Yigit * Create an acl context object for apps to 44405a38d7cSFerruh Yigit * manipulate 44505a38d7cSFerruh Yigit */ 44605a38d7cSFerruh Yigit __rte_experimental 44705a38d7cSFerruh Yigit struct rte_acl_ctx * 44805a38d7cSFerruh Yigit rte_acl_create(const struct rte_acl_param *param) 44905a38d7cSFerruh Yigit { 45005a38d7cSFerruh Yigit ... 45105a38d7cSFerruh Yigit } 45205a38d7cSFerruh Yigit 45305a38d7cSFerruh YigitIn the map file, experimental symbols are listed as part of the ``EXPERIMENTAL`` 45405a38d7cSFerruh Yigitversion node. 45505a38d7cSFerruh Yigit 45605a38d7cSFerruh Yigit.. code-block:: none 45705a38d7cSFerruh Yigit 45823b4fd82SRay Kinsella DPDK_21 { 45905a38d7cSFerruh Yigit global: 46005a38d7cSFerruh Yigit ... 46105a38d7cSFerruh Yigit 46205a38d7cSFerruh Yigit local: *; 46305a38d7cSFerruh Yigit }; 46405a38d7cSFerruh Yigit 46505a38d7cSFerruh Yigit EXPERIMENTAL { 46605a38d7cSFerruh Yigit global: 46705a38d7cSFerruh Yigit 46805a38d7cSFerruh Yigit rte_acl_create; 46905a38d7cSFerruh Yigit }; 47005a38d7cSFerruh Yigit 47105a38d7cSFerruh YigitWhen we promote the symbol to the stable ABI, we simply strip the 47205a38d7cSFerruh Yigit``__rte_experimental`` annotation from the function and move the symbol from the 47305a38d7cSFerruh Yigit``EXPERIMENTAL`` node, to the node of the next major ABI version as follow. 47405a38d7cSFerruh Yigit 47505a38d7cSFerruh Yigit.. code-block:: c 47605a38d7cSFerruh Yigit 47705a38d7cSFerruh Yigit /* 47805a38d7cSFerruh Yigit * Create an acl context object for apps to 47905a38d7cSFerruh Yigit * manipulate 48005a38d7cSFerruh Yigit */ 48105a38d7cSFerruh Yigit struct rte_acl_ctx * 48205a38d7cSFerruh Yigit rte_acl_create(const struct rte_acl_param *param) 48305a38d7cSFerruh Yigit { 48405a38d7cSFerruh Yigit ... 48505a38d7cSFerruh Yigit } 48605a38d7cSFerruh Yigit 48705a38d7cSFerruh YigitWe then update the map file, adding the symbol ``rte_acl_create`` 48823b4fd82SRay Kinsellato the ``DPDK_22`` version node. 48905a38d7cSFerruh Yigit 49005a38d7cSFerruh Yigit.. code-block:: none 49105a38d7cSFerruh Yigit 49223b4fd82SRay Kinsella DPDK_21 { 49305a38d7cSFerruh Yigit global: 49405a38d7cSFerruh Yigit ... 49505a38d7cSFerruh Yigit 49605a38d7cSFerruh Yigit local: *; 49705a38d7cSFerruh Yigit }; 49805a38d7cSFerruh Yigit 49923b4fd82SRay Kinsella DPDK_22 { 50005a38d7cSFerruh Yigit global: 50105a38d7cSFerruh Yigit 50205a38d7cSFerruh Yigit rte_acl_create; 50323b4fd82SRay Kinsella } DPDK_21; 50405a38d7cSFerruh Yigit 50505a38d7cSFerruh Yigit 50605a38d7cSFerruh YigitAlthough there are strictly no guarantees or commitments associated with 50705a38d7cSFerruh Yigit:ref:`experimental symbols <experimental_apis>`, a maintainer may wish to offer 50805a38d7cSFerruh Yigitan alias to experimental. The process to add an alias to experimental, 50905a38d7cSFerruh Yigitis similar to the symbol versioning process. Assuming we have an experimental 51005a38d7cSFerruh Yigitsymbol as before, we now add the symbol to both the ``EXPERIMENTAL`` 51123b4fd82SRay Kinsellaand ``DPDK_22`` version nodes. 51205a38d7cSFerruh Yigit 51305a38d7cSFerruh Yigit.. code-block:: c 51405a38d7cSFerruh Yigit 51505a38d7cSFerruh Yigit #include <rte_compat.h>; 51605a38d7cSFerruh Yigit #include <rte_function_versioning.h> 51705a38d7cSFerruh Yigit 51805a38d7cSFerruh Yigit /* 51905a38d7cSFerruh Yigit * Create an acl context object for apps to 52005a38d7cSFerruh Yigit * manipulate 52105a38d7cSFerruh Yigit */ 52205a38d7cSFerruh Yigit struct rte_acl_ctx * 52305a38d7cSFerruh Yigit rte_acl_create(const struct rte_acl_param *param) 52405a38d7cSFerruh Yigit { 52505a38d7cSFerruh Yigit ... 52605a38d7cSFerruh Yigit } 52705a38d7cSFerruh Yigit 52805a38d7cSFerruh Yigit __rte_experimental 52905a38d7cSFerruh Yigit struct rte_acl_ctx * 53005a38d7cSFerruh Yigit rte_acl_create_e(const struct rte_acl_param *param) 53105a38d7cSFerruh Yigit { 53205a38d7cSFerruh Yigit return rte_acl_create(param); 53305a38d7cSFerruh Yigit } 53405a38d7cSFerruh Yigit VERSION_SYMBOL_EXPERIMENTAL(rte_acl_create, _e); 53505a38d7cSFerruh Yigit 53605a38d7cSFerruh Yigit struct rte_acl_ctx * 53723b4fd82SRay Kinsella rte_acl_create_v22(const struct rte_acl_param *param) 53805a38d7cSFerruh Yigit { 53905a38d7cSFerruh Yigit return rte_acl_create(param); 54005a38d7cSFerruh Yigit } 54123b4fd82SRay Kinsella BIND_DEFAULT_SYMBOL(rte_acl_create, _v22, 22); 54205a38d7cSFerruh Yigit 54305a38d7cSFerruh YigitIn the map file, we map the symbol to both the ``EXPERIMENTAL`` 54423b4fd82SRay Kinsellaand ``DPDK_22`` version nodes. 54505a38d7cSFerruh Yigit 54605a38d7cSFerruh Yigit.. code-block:: none 54705a38d7cSFerruh Yigit 54823b4fd82SRay Kinsella DPDK_21 { 54905a38d7cSFerruh Yigit global: 55005a38d7cSFerruh Yigit ... 55105a38d7cSFerruh Yigit 55205a38d7cSFerruh Yigit local: *; 55305a38d7cSFerruh Yigit }; 55405a38d7cSFerruh Yigit 55523b4fd82SRay Kinsella DPDK_22 { 55605a38d7cSFerruh Yigit global: 55705a38d7cSFerruh Yigit 55805a38d7cSFerruh Yigit rte_acl_create; 55923b4fd82SRay Kinsella } DPDK_21; 56005a38d7cSFerruh Yigit 56105a38d7cSFerruh Yigit EXPERIMENTAL { 56205a38d7cSFerruh Yigit global: 56305a38d7cSFerruh Yigit 56405a38d7cSFerruh Yigit rte_acl_create; 56505a38d7cSFerruh Yigit }; 56605a38d7cSFerruh Yigit 56705a38d7cSFerruh Yigit.. note:: 56805a38d7cSFerruh Yigit 56905a38d7cSFerruh Yigit Please note, similar to :ref:`symbol versioning <example_abi_macro_usage>`, 57005a38d7cSFerruh Yigit when aliasing to experimental you will also need to take care of 57105a38d7cSFerruh Yigit :ref:`mapping static symbols <mapping_static_symbols>`. 57205a38d7cSFerruh Yigit 57305a38d7cSFerruh Yigit 57445a4103eSRay Kinsella.. _abi_deprecation: 575ced6b2d1SRay Kinsella 576ced6b2d1SRay KinsellaDeprecating part of a public API 577ced6b2d1SRay Kinsella________________________________ 578ced6b2d1SRay Kinsella 57945a4103eSRay KinsellaLets assume that you've done the above updates, and in preparation for the next 580144beafcSRay Kinsellamajor ABI version you decide you would like to retire the old version of the 581144beafcSRay Kinsellafunction. After having gone through the ABI deprecation announcement process, 582144beafcSRay Kinsellaremoval is easy. Start by removing the symbol from the requisite version map 583144beafcSRay Kinsellafile: 584ced6b2d1SRay Kinsella 585ced6b2d1SRay Kinsella.. code-block:: none 586ced6b2d1SRay Kinsella 58723b4fd82SRay Kinsella DPDK_21 { 588ced6b2d1SRay Kinsella global: 589ced6b2d1SRay Kinsella 590ced6b2d1SRay Kinsella rte_acl_add_rules; 591ced6b2d1SRay Kinsella rte_acl_build; 592ced6b2d1SRay Kinsella rte_acl_classify; 593ced6b2d1SRay Kinsella rte_acl_classify_alg; 594ced6b2d1SRay Kinsella rte_acl_classify_scalar; 595ced6b2d1SRay Kinsella rte_acl_dump; 596ced6b2d1SRay Kinsella - rte_acl_create 597ced6b2d1SRay Kinsella rte_acl_find_existing; 598ced6b2d1SRay Kinsella rte_acl_free; 599ced6b2d1SRay Kinsella rte_acl_ipv4vlan_add_rules; 600ced6b2d1SRay Kinsella rte_acl_ipv4vlan_build; 601ced6b2d1SRay Kinsella rte_acl_list_dump; 602ced6b2d1SRay Kinsella rte_acl_reset; 603ced6b2d1SRay Kinsella rte_acl_reset_rules; 604ced6b2d1SRay Kinsella rte_acl_set_ctx_classify; 605ced6b2d1SRay Kinsella 606ced6b2d1SRay Kinsella local: *; 607ced6b2d1SRay Kinsella }; 608ced6b2d1SRay Kinsella 60923b4fd82SRay Kinsella DPDK_22 { 610ced6b2d1SRay Kinsella global: 611ced6b2d1SRay Kinsella rte_acl_create; 61223b4fd82SRay Kinsella } DPDK_21; 613ced6b2d1SRay Kinsella 614ced6b2d1SRay Kinsella 615ced6b2d1SRay KinsellaNext remove the corresponding versioned export. 616ced6b2d1SRay Kinsella 617ced6b2d1SRay Kinsella.. code-block:: c 618ced6b2d1SRay Kinsella 61923b4fd82SRay Kinsella -VERSION_SYMBOL(rte_acl_create, _v21, 21); 620ced6b2d1SRay Kinsella 621ced6b2d1SRay Kinsella 622ced6b2d1SRay KinsellaNote that the internal function definition could also be removed, but its used 62323b4fd82SRay Kinsellain our example by the newer version ``v22``, so we leave it in place and declare 62445a4103eSRay Kinsellait as static. This is a coding style choice. 625ced6b2d1SRay Kinsella 626144beafcSRay Kinsella.. _deprecating_entire_abi: 627ced6b2d1SRay Kinsella 628ced6b2d1SRay KinsellaDeprecating an entire ABI version 629ced6b2d1SRay Kinsella_________________________________ 630ced6b2d1SRay Kinsella 631144beafcSRay KinsellaWhile removing a symbol from an ABI may be useful, it is more practical to 632144beafcSRay Kinsellaremove an entire version node at once, as is typically done at the declaration 633144beafcSRay Kinsellaof a major ABI version. If a version node completely specifies an API, then 634144beafcSRay Kinsellaremoving part of it, typically makes it incomplete. In those cases it is better 635144beafcSRay Kinsellato remove the entire node. 636ced6b2d1SRay Kinsella 637ced6b2d1SRay KinsellaTo do this, start by modifying the version map file, such that all symbols from 638144beafcSRay Kinsellathe node to be removed are merged into the next node in the map. 639ced6b2d1SRay Kinsella 640ced6b2d1SRay KinsellaIn the case of our map above, it would transform to look as follows 641ced6b2d1SRay Kinsella 642ced6b2d1SRay Kinsella.. code-block:: none 643ced6b2d1SRay Kinsella 64423b4fd82SRay Kinsella DPDK_22 { 645ced6b2d1SRay Kinsella global: 646ced6b2d1SRay Kinsella 647ced6b2d1SRay Kinsella rte_acl_add_rules; 648ced6b2d1SRay Kinsella rte_acl_build; 649ced6b2d1SRay Kinsella rte_acl_classify; 650ced6b2d1SRay Kinsella rte_acl_classify_alg; 651ced6b2d1SRay Kinsella rte_acl_classify_scalar; 652ced6b2d1SRay Kinsella rte_acl_dump; 653ced6b2d1SRay Kinsella rte_acl_create 654ced6b2d1SRay Kinsella rte_acl_find_existing; 655ced6b2d1SRay Kinsella rte_acl_free; 656ced6b2d1SRay Kinsella rte_acl_ipv4vlan_add_rules; 657ced6b2d1SRay Kinsella rte_acl_ipv4vlan_build; 658ced6b2d1SRay Kinsella rte_acl_list_dump; 659ced6b2d1SRay Kinsella rte_acl_reset; 660ced6b2d1SRay Kinsella rte_acl_reset_rules; 661ced6b2d1SRay Kinsella rte_acl_set_ctx_classify; 662ced6b2d1SRay Kinsella 663ced6b2d1SRay Kinsella local: *; 664ced6b2d1SRay Kinsella }; 665ced6b2d1SRay Kinsella 666ced6b2d1SRay KinsellaThen any uses of BIND_DEFAULT_SYMBOL that pointed to the old node should be 667ced6b2d1SRay Kinsellaupdated to point to the new version node in any header files for all affected 668ced6b2d1SRay Kinsellasymbols. 669ced6b2d1SRay Kinsella 670ced6b2d1SRay Kinsella.. code-block:: c 671ced6b2d1SRay Kinsella 67223b4fd82SRay Kinsella -BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 21); 67323b4fd82SRay Kinsella +BIND_DEFAULT_SYMBOL(rte_acl_create, _v22, 22); 674ced6b2d1SRay Kinsella 6753eecaba9SRay KinsellaLastly, any VERSION_SYMBOL macros that point to the old version nodes 6763eecaba9SRay Kinsellashould be removed, taking care to preserve any code that is shared 6773eecaba9SRay Kinsellawith the new version node. 678ced6b2d1SRay Kinsella 679ced6b2d1SRay Kinsella 680ced6b2d1SRay KinsellaRunning the ABI Validator 681ced6b2d1SRay Kinsella------------------------- 682ced6b2d1SRay Kinsella 683ced6b2d1SRay KinsellaThe ``devtools`` directory in the DPDK source tree contains a utility program, 68467354349SNeil Horman``check-abi.sh``, for validating the DPDK ABI based on the libabigail 68567354349SNeil Horman`abidiff utility <https://sourceware.org/libabigail/manual/abidiff.html>`_. 686ced6b2d1SRay Kinsella 68767354349SNeil HormanThe syntax of the ``check-abi.sh`` utility is:: 688ced6b2d1SRay Kinsella 68967354349SNeil Horman devtools/check-abi.sh <refdir> <newdir> 690ced6b2d1SRay Kinsella 69167354349SNeil HormanWhere <refdir> specifies the directory housing the reference build of DPDK, 69267354349SNeil Hormanand <newdir> specifies the DPDK build directory to check the ABI of. 693ced6b2d1SRay Kinsella 69467354349SNeil HormanThe ABI compatibility is automatically verified when using a build script 69567354349SNeil Hormanfrom ``devtools``, if the variable ``DPDK_ABI_REF_VERSION`` is set with a tag, 69667354349SNeil Hormanas described in :ref:`ABI check recommendations<integrated_abi_check>`. 697