doc: update ABI version references
Updated references to abi versions in the contributors guide. Fixed an inaccurate reference to a symbol in the policy. Signed-off-by: Ray Kinsella <mdr@ashroe.eu> Reviewed-by: David Marchand <david.marchand@redhat.com>
This commit is contained in:
parent
5d73663728
commit
23b4fd825f
@ -78,15 +78,15 @@ The DPDK ABI policy
|
||||
-------------------
|
||||
|
||||
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
|
||||
@ -95,8 +95,8 @@ sonames do not change.
|
||||
|
||||
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
|
||||
@ -222,11 +222,11 @@ Examples of ABI Changes
|
||||
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
|
||||
@ -235,21 +235,21 @@ declarations of major ABI versions.
|
||||
- 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:
|
||||
@ -261,25 +261,25 @@ The following are some examples of ABI deprecation notices which would be
|
||||
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.
|
||||
|
||||
|
||||
|
@ -14,22 +14,22 @@ What is a library's soname?
|
||||
---------------------------
|
||||
|
||||
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:
|
||||
|
||||
@ -59,41 +59,41 @@ persists over multiple releases.
|
||||
.. 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.
|
||||
@ -101,12 +101,12 @@ 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:
|
||||
...
|
||||
|
||||
@ -216,7 +216,7 @@ library looks like this
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
DPDK_20 {
|
||||
DPDK_21 {
|
||||
global:
|
||||
|
||||
rte_acl_add_rules;
|
||||
@ -242,7 +242,7 @@ This file needs to be modified as follows
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
DPDK_20 {
|
||||
DPDK_21 {
|
||||
global:
|
||||
|
||||
rte_acl_add_rules;
|
||||
@ -264,15 +264,15 @@ This file needs to be modified as follows
|
||||
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
|
||||
@ -285,7 +285,7 @@ with the public symbol name
|
||||
-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;
|
||||
@ -294,7 +294,7 @@ with the public symbol name
|
||||
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
|
||||
@ -302,26 +302,26 @@ Immediately after the function, we add the VERSION_SYMBOL macro.
|
||||
#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;
|
||||
|
||||
@ -330,7 +330,7 @@ function name, with the ``v21`` suffix, and implement it appropriately.
|
||||
|
||||
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
|
||||
@ -338,10 +338,10 @@ we add the BIND_DEFAULT_SYMBOL macro.
|
||||
#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.
|
||||
@ -352,15 +352,15 @@ 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::
|
||||
|
||||
@ -385,21 +385,21 @@ this code in a position of no longer having a symbol simply named
|
||||
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:
|
||||
@ -456,7 +456,7 @@ version node.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
DPDK_20 {
|
||||
DPDK_21 {
|
||||
global:
|
||||
...
|
||||
|
||||
@ -486,22 +486,22 @@ When we promote the symbol to the stable ABI, we simply strip the
|
||||
}
|
||||
|
||||
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
|
||||
@ -509,7 +509,7 @@ 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
|
||||
|
||||
@ -535,29 +535,29 @@ and ``DPDK_21`` version nodes.
|
||||
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:
|
||||
@ -585,7 +585,7 @@ file:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
DPDK_20 {
|
||||
DPDK_21 {
|
||||
global:
|
||||
|
||||
rte_acl_add_rules;
|
||||
@ -607,21 +607,21 @@ file:
|
||||
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:
|
||||
@ -642,7 +642,7 @@ In the case of our map above, it would transform to look as follows
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
DPDK_21 {
|
||||
DPDK_22 {
|
||||
global:
|
||||
|
||||
rte_acl_add_rules;
|
||||
@ -670,8 +670,8 @@ symbols.
|
||||
|
||||
.. 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user