-------------------
A new major ABI version is declared no more frequently than yearly, with
-declarations usually aligning with a LTS release, e.g. ABI 20 for DPDK 19.11.
+declarations usually aligning with a LTS release, e.g. ABI 21 for DPDK 20.11.
Compatibility with the major ABI version is then mandatory in subsequent
-releases until the next major ABI version is declared, e.g. ABI 21 for DPDK
-20.11.
+releases until the next major ABI version is declared, e.g. ABI 22 for DPDK
+21.11.
At the declaration of a major ABI version, major version numbers encoded in
libraries' sonames are bumped to indicate the new version, with the minor
-version reset to ``0``. An example would be ``librte_eal.so.20.3`` would become
-``librte_eal.so.21.0``.
+version reset to ``0``. An example would be ``librte_eal.so.21.3`` would become
+``librte_eal.so.22.0``.
The ABI may then change multiple times, without warning, between the last major
ABI version increment and the HEAD label of the git tree, with the condition
Minor versions are incremented to indicate the release of a new ABI compatible
DPDK release, typically the DPDK quarterly releases. An example of this, might
-be that ``librte_eal.so.20.1`` would indicate the first ABI compatible DPDK
-release, following the declaration of the new major ABI version ``20``.
+be that ``librte_eal.so.21.1`` would indicate the first ABI compatible DPDK
+release, following the declaration of the new major ABI version ``21``.
An ABI version is supported in all new releases until the next major ABI version
is declared. When changing the major ABI version, the release notes will detail
The following are examples of allowable ABI changes occurring between
declarations of major ABI versions.
-* DPDK 19.11 release defines the function ``rte_foo()`` ; ``rte_foo()``
- is part of the major ABI version ``20``.
+* DPDK 20.11 release defines the function ``rte_foo()`` ; ``rte_foo()``
+ is part of the major ABI version ``21``.
-* DPDK 20.02 release defines a new function ``rte_foo(uint8_t bar)``.
- This is not a problem as long as the symbol ``rte_foo@DPDK20`` is
+* DPDK 21.02 release defines a new function ``rte_foo(uint8_t bar)``.
+ This is not a problem as long as the symbol ``rte_foo@DPDK_21`` is
preserved through :ref:`abi_versioning`.
- The new function may be marked with the ``__rte_experimental`` tag for a
- Once ``rte_foo(uint8_t bar)`` becomes non-experimental, ``rte_foo()`` is
declared as ``__rte_deprecated`` and an deprecation notice is provided.
-* DPDK 19.11 is not re-released to include ``rte_foo(uint8_t bar)``, the new
- version of ``rte_foo`` only exists from DPDK 20.02 onwards as described in the
+* DPDK 20.11 is not re-released to include ``rte_foo(uint8_t bar)``, the new
+ version of ``rte_foo`` only exists from DPDK 21.02 onwards as described in the
:ref:`note on forward-only compatibility<forward-only>`.
-* DPDK 20.02 release defines the experimental function ``__rte_experimental
- rte_baz()``. This function may or may not exist in the DPDK 20.05 release.
+* DPDK 21.02 release defines the experimental function ``__rte_experimental
+ rte_baz()``. This function may or may not exist in the DPDK 21.05 release.
* An application ``dPacket`` wishes to use ``rte_foo(uint8_t bar)``, before the
- declaration of the DPDK ``21`` major ABI version. The application can only
- ensure its runtime dependencies are met by specifying ``DPDK (>= 20.2)`` as
+ declaration of the DPDK ``22`` major ABI version. The application can only
+ ensure its runtime dependencies are met by specifying ``DPDK (>= 21.2)`` as
an explicit package dependency, as the soname can only indicate the
supported major ABI version.
-* At the release of DPDK 20.11, the function ``rte_foo(uint8_t bar)`` becomes
- formally part of then new major ABI version DPDK ``21`` and ``rte_foo()`` may be
+* At the release of DPDK 21.11, the function ``rte_foo(uint8_t bar)`` becomes
+ formally part of then new major ABI version DPDK ``22`` and ``rte_foo()`` may be
removed.
.. _deprecation_notices:
added to the Release Notes:
* The Macro ``#RTE_FOO`` is deprecated and will be removed with ABI version
- 21, to be replaced with the inline function ``rte_foo()``.
+ 22, to be replaced with the inline function ``rte_foo()``.
* The function ``rte_mbuf_grok()`` has been updated to include a new parameter
- in version 20.2. Backwards compatibility will be maintained for this function
- until the release of the new DPDK major ABI version 21, in DPDK version
- 20.11.
+ in version 21.2. Backwards compatibility will be maintained for this function
+ until the release of the new DPDK major ABI version 22, in DPDK version
+ 21.11.
-* The members of ``struct rte_foo`` have been reorganized in DPDK 20.02 for
+* The members of ``struct rte_foo`` have been reorganized in DPDK 21.02 for
performance reasons. Existing binary applications will have backwards
- compatibility in release 20.02, while newly built binaries will need to
+ compatibility in release 21.02, while newly built binaries will need to
reference the new structure variant ``struct rte_foo2``. Compatibility will be
- removed in release 20.11, and all applications will require updating and
+ removed in release 21.11, and all applications will require updating and
rebuilding to the new structure at that time, which will be renamed to the
original ``struct rte_foo``.
* Significant ABI changes are planned for the ``librte_dostuff`` library. The
- upcoming release 20.02 will not contain these changes, but release 20.11 will,
+ upcoming release 21.02 will not contain these changes, but release 21.11 will,
and no backwards compatibility is planned due to the extensive nature of
- these changes. Binaries using this library built prior to ABI version 21 will
+ these changes. Binaries using this library built prior to ABI version 22 will
require updating and recompilation.
---------------------------
System libraries usually adopt the familiar major and minor version naming
-convention, where major versions (e.g. ``librte_eal 20.x, 21.x``) are presumed
+convention, where major versions (e.g. ``librte_eal 21.x, 22.x``) are presumed
to be ABI incompatible with each other and minor versions (e.g. ``librte_eal
-20.1, 20.2``) are presumed to be ABI compatible. A library's `soname
+21.1, 21.2``) are presumed to be ABI compatible. A library's `soname
<https://en.wikipedia.org/wiki/Soname>`_. is typically used to provide backward
compatibility information about a given library, describing the lowest common
denominator ABI supported by the library. The soname or logical name for the
library, is typically comprised of the library's name and major version e.g.
-``librte_eal.so.20``.
+``librte_eal.so.21``.
During an application's build process, a library's soname is noted as a runtime
dependency of the application. This information is then used by the `dynamic
linker <https://en.wikipedia.org/wiki/Dynamic_linker>`_ when resolving the
applications dependencies at runtime, to load a library supporting the correct
ABI version. The library loaded at runtime therefore, may be a minor revision
-supporting the same major ABI version (e.g. ``librte_eal.20.2``), as the library
-used to link the application (e.g ``librte_eal.20.0``).
+supporting the same major ABI version (e.g. ``librte_eal.21.2``), as the library
+used to link the application (e.g ``librte_eal.21.0``).
.. _major_abi_versions:
.. code-block:: none
$ head ./lib/librte_acl/version.map
- DPDK_20 {
+ DPDK_21 {
global:
...
$ head ./lib/librte_eal/version.map
- DPDK_20 {
+ DPDK_21 {
global:
...
When an ABI change is made between major ABI versions to a given library, a new
section is added to that library's version map describing the impending new ABI
version, as described in the section :ref:`example_abi_macro_usage`. The
-library's soname and filename however do not change, e.g. ``libacl.so.20``, as
+library's soname and filename however do not change, e.g. ``libacl.so.21``, as
ABI compatibility with the last major ABI version continues to be preserved for
that library.
.. code-block:: none
$ head ./lib/librte_acl/version.map
- DPDK_20 {
+ DPDK_21 {
global:
...
- DPDK_21 {
+ DPDK_22 {
global:
- } DPDK_20;
+ } DPDK_21;
...
$ head ./lib/librte_eal/version.map
- DPDK_20 {
+ DPDK_21 {
global:
...
-However when a new ABI version is declared, for example DPDK ``21``, old
+However when a new ABI version is declared, for example DPDK ``22``, old
depreciated functions may be safely removed at this point and the entire old
major ABI version removed, see the section :ref:`deprecating_entire_abi` on
how this may be done.
.. code-block:: none
$ head ./lib/librte_acl/version.map
- DPDK_21 {
+ DPDK_22 {
global:
...
$ head ./lib/librte_eal/version.map
- DPDK_21 {
+ DPDK_22 {
global:
...
.. code-block:: none
- DPDK_20 {
+ DPDK_21 {
global:
rte_acl_add_rules;
.. code-block:: none
- DPDK_20 {
+ DPDK_21 {
global:
rte_acl_add_rules;
local: *;
};
- DPDK_21 {
+ DPDK_22 {
global:
rte_acl_create;
- } DPDK_20;
+ } DPDK_21;
The addition of the new block tells the linker that a new version node
-``DPDK_21`` is available, which contains the symbol rte_acl_create, and inherits
-the symbols from the DPDK_20 node. This list is directly translated into a
+``DPDK_22`` is available, which contains the symbol rte_acl_create, and inherits
+the symbols from the DPDK_21 node. This list is directly translated into a
list of exported symbols when DPDK is compiled as a shared library.
Next, we need to specify in the code which function maps to the rte_acl_create
-struct rte_acl_ctx *
-rte_acl_create(const struct rte_acl_param *param)
+struct rte_acl_ctx * __vsym
- +rte_acl_create_v20(const struct rte_acl_param *param)
+ +rte_acl_create_v21(const struct rte_acl_param *param)
{
size_t sz;
struct rte_acl_ctx *ctx;
Note that the base name of the symbol was kept intact, as this is conducive to
the macros used for versioning symbols and we have annotated the function as
``__vsym``, an implementation of a versioned symbol . That is our next step,
-mapping this new symbol name to the initial symbol name at version node 20.
+mapping this new symbol name to the initial symbol name at version node 21.
Immediately after the function, we add the VERSION_SYMBOL macro.
.. code-block:: c
#include <rte_function_versioning.h>
...
- VERSION_SYMBOL(rte_acl_create, _v20, 20);
+ VERSION_SYMBOL(rte_acl_create, _v21, 21);
Remembering to also add the rte_function_versioning.h header to the requisite c
file where these changes are being made. The macro instructs the linker to
-create a new symbol ``rte_acl_create@DPDK_20``, which matches the symbol created
+create a new symbol ``rte_acl_create@DPDK_21``, which matches the symbol created
in older builds, but now points to the above newly named function. We have now
mapped the original rte_acl_create symbol to the original function (but with a
new name).
Please see the section :ref:`Enabling versioning macros
<enabling_versioning_macros>` to enable this macro in the meson/ninja build.
-Next, we need to create the new ``v21`` version of the symbol. We create a new
-function name, with the ``v21`` suffix, and implement it appropriately.
+Next, we need to create the new ``v22`` version of the symbol. We create a new
+function name, with the ``v22`` suffix, and implement it appropriately.
.. code-block:: c
struct rte_acl_ctx * __vsym
- rte_acl_create_v21(const struct rte_acl_param *param, int debug);
+ rte_acl_create_v22(const struct rte_acl_param *param, int debug);
{
- struct rte_acl_ctx *ctx = rte_acl_create_v20(param);
+ struct rte_acl_ctx *ctx = rte_acl_create_v21(param);
ctx->debug = debug;
This code serves as our new API call. Its the same as our old call, but adds the
new parameter in place. Next we need to map this function to the new default
-symbol ``rte_acl_create@DPDK_21``. To do this, immediately after the function,
+symbol ``rte_acl_create@DPDK_22``. To do this, immediately after the function,
we add the BIND_DEFAULT_SYMBOL macro.
.. code-block:: c
#include <rte_function_versioning.h>
...
- BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 21);
+ BIND_DEFAULT_SYMBOL(rte_acl_create, _v22, 22);
The macro instructs the linker to create the new default symbol
-``rte_acl_create@DPDK_21``, which points to the above newly named function.
+``rte_acl_create@DPDK_22``, which points to the above newly named function.
We finally modify the prototype of the call in the public header file,
such that it contains both versions of the symbol and the public API.
rte_acl_create(const struct rte_acl_param *param);
struct rte_acl_ctx * __vsym
- rte_acl_create_v20(const struct rte_acl_param *param);
+ rte_acl_create_v21(const struct rte_acl_param *param);
struct rte_acl_ctx * __vsym
- rte_acl_create_v21(const struct rte_acl_param *param, int debug);
+ rte_acl_create_v22(const struct rte_acl_param *param, int debug);
And that's it, on the next shared library rebuild, there will be two versions of
-rte_acl_create, an old DPDK_20 version, used by previously built applications,
-and a new DPDK_21 version, used by future built applications.
+rte_acl_create, an old DPDK_21 version, used by previously built applications,
+and a new DPDK_22 version, used by future built applications.
.. note::
To correct this, we can simply map a function of our choosing back to the public
symbol in the static build with the ``MAP_STATIC_SYMBOL`` macro. Generally the
assumption is that the most recent version of the symbol is the one you want to
-map. So, back in the C file where, immediately after ``rte_acl_create_v21`` is
+map. So, back in the C file where, immediately after ``rte_acl_create_v22`` is
defined, we add this
.. code-block:: c
struct rte_acl_ctx * __vsym
- rte_acl_create_v21(const struct rte_acl_param *param, int debug)
+ rte_acl_create_v22(const struct rte_acl_param *param, int debug)
{
...
}
- MAP_STATIC_SYMBOL(struct rte_acl_ctx *rte_acl_create(const struct rte_acl_param *param, int debug), rte_acl_create_v21);
+ MAP_STATIC_SYMBOL(struct rte_acl_ctx *rte_acl_create(const struct rte_acl_param *param, int debug), rte_acl_create_v22);
That tells the compiler that, when building a static library, any calls to the
-symbol ``rte_acl_create`` should be linked to ``rte_acl_create_v21``
+symbol ``rte_acl_create`` should be linked to ``rte_acl_create_v22``
.. _enabling_versioning_macros:
.. code-block:: none
- DPDK_20 {
+ DPDK_21 {
global:
...
}
We then update the map file, adding the symbol ``rte_acl_create``
-to the ``DPDK_21`` version node.
+to the ``DPDK_22`` version node.
.. code-block:: none
- DPDK_20 {
+ DPDK_21 {
global:
...
local: *;
};
- DPDK_21 {
+ DPDK_22 {
global:
rte_acl_create;
- } DPDK_20;
+ } DPDK_21;
Although there are strictly no guarantees or commitments associated with
an alias to experimental. The process to add an alias to experimental,
is similar to the symbol versioning process. Assuming we have an experimental
symbol as before, we now add the symbol to both the ``EXPERIMENTAL``
-and ``DPDK_21`` version nodes.
+and ``DPDK_22`` version nodes.
.. code-block:: c
VERSION_SYMBOL_EXPERIMENTAL(rte_acl_create, _e);
struct rte_acl_ctx *
- rte_acl_create_v21(const struct rte_acl_param *param)
+ rte_acl_create_v22(const struct rte_acl_param *param)
{
return rte_acl_create(param);
}
- BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 21);
+ BIND_DEFAULT_SYMBOL(rte_acl_create, _v22, 22);
In the map file, we map the symbol to both the ``EXPERIMENTAL``
-and ``DPDK_21`` version nodes.
+and ``DPDK_22`` version nodes.
.. code-block:: none
- DPDK_20 {
+ DPDK_21 {
global:
...
local: *;
};
- DPDK_21 {
+ DPDK_22 {
global:
rte_acl_create;
- } DPDK_20;
+ } DPDK_21;
EXPERIMENTAL {
global:
.. code-block:: none
- DPDK_20 {
+ DPDK_21 {
global:
rte_acl_add_rules;
local: *;
};
- DPDK_21 {
+ DPDK_22 {
global:
rte_acl_create;
- } DPDK_20;
+ } DPDK_21;
Next remove the corresponding versioned export.
.. code-block:: c
- -VERSION_SYMBOL(rte_acl_create, _v20, 20);
+ -VERSION_SYMBOL(rte_acl_create, _v21, 21);
Note that the internal function definition could also be removed, but its used
-in our example by the newer version ``v21``, so we leave it in place and declare
+in our example by the newer version ``v22``, so we leave it in place and declare
it as static. This is a coding style choice.
.. _deprecating_entire_abi:
.. code-block:: none
- DPDK_21 {
+ DPDK_22 {
global:
rte_acl_add_rules;
.. code-block:: c
- -BIND_DEFAULT_SYMBOL(rte_acl_create, _v20, 20);
- +BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 21);
+ -BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 21);
+ +BIND_DEFAULT_SYMBOL(rte_acl_create, _v22, 22);
Lastly, any VERSION_SYMBOL macros that point to the old version nodes
should be removed, taking care to preserve any code that is shared