DPDK patches and discussions
 help / color / mirror / Atom feed
From: "Gonzalez Monroy, Sergio" <sergio.gonzalez.monroy@intel.com>
To: "Zhang, Helin" <helin.zhang@intel.com>,
	 Neil Horman <nhorman@tuxdriver.com>,
	"dev@dpdk.org" <dev@dpdk.org>
Subject: Re: [dpdk-dev] [PATCHv2 2/2] ABI: Add some documentation
Date: Thu, 25 Jun 2015 09:00:24 +0100	[thread overview]
Message-ID: <558BB518.20104@intel.com> (raw)
In-Reply-To: <558BB0FD.9040803@intel.com>

On 25/06/2015 08:42, Gonzalez Monroy, Sergio wrote:
> On 25/06/2015 08:19, Zhang, Helin wrote:
>>
>>> -----Original Message-----
>>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Neil Horman
>>> Sent: Thursday, June 25, 2015 2:35 AM
>>> To: dev@dpdk.org
>>> Subject: [dpdk-dev] [PATCHv2 2/2] ABI: Add some documentation
>>>
>>> People have been asking for ways to use the ABI macros, heres some 
>>> docs to
>>> clarify their use.  Included is:
>>>
>>> * An overview of what ABI is
>>> * Details of the ABI deprecation process
>>> * Details of the versioning macros
>>> * Examples of their use
>>> * Details of how to use the ABI validator
>>>
>>> Thanks to John Mcnamara, who duplicated much of this effort at Intel 
>>> while I was
>>> working on it.  Much of the introductory material was gathered and 
>>> cleaned up
>>> by him
>>>
>>> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
>>> CC: john.mcnamara@intel.com
>>> CC: thomas.monjalon@6wind.com
>>>
>>> Change notes:
>>>
>>> v2)
>>>       * Fixed RST indentations and spelling errors
>>>       * Rebased to upstream to fix index.rst conflict
>>> ---
>>>   doc/guides/guidelines/index.rst      |   1 +
>>>   doc/guides/guidelines/versioning.rst | 456
>>> +++++++++++++++++++++++++++++++++++
>>>   2 files changed, 457 insertions(+)
>>>   create mode 100644 doc/guides/guidelines/versioning.rst
>>>
>>> diff --git a/doc/guides/guidelines/index.rst 
>>> b/doc/guides/guidelines/index.rst
>>> index 0ee9ab3..bfb9fa3 100644
>>> --- a/doc/guides/guidelines/index.rst
>>> +++ b/doc/guides/guidelines/index.rst
>>> @@ -7,3 +7,4 @@ Guidelines
>>>
>>>       coding_style
>>>       design
>>> +    versioning
>>> diff --git a/doc/guides/guidelines/versioning.rst
>>> b/doc/guides/guidelines/versioning.rst
>>> new file mode 100644
>>> index 0000000..2aef526
>>> --- /dev/null
>>> +++ b/doc/guides/guidelines/versioning.rst
>>> @@ -0,0 +1,456 @@
>>> +Managing ABI updates
>>> +====================
>>> +
>>> +Description
>>> +-----------
>>> +
>>> +This document details some methods for handling ABI management in the
>>> DPDK.
>>> +Note this document is not exhaustive, in that C library versioning is
>>> +flexible allowing multiple methods to achieve various goals, but it
>>> +will provide the user with some introductory methods
>>> +
>>> +General Guidelines
>>> +------------------
>>> +
>>> +#. Whenever possible, ABI should be preserved #. The addition of
>>> +symbols is generally not problematic #. The modification of symbols 
>>> can
>>> +generally be managed with versioning #. The removal of symbols
>>> +generally is an ABI break and requires bumping of the
>>> +   LIBABIVER macro
>>> +
>>> +What is an ABI
>>> +--------------
>>> +
>>> +An ABI (Application Binary Interface) is the set of runtime interfaces
>>> +exposed by a library. It is similar to an API (Application Programming
>>> +Interface) but is the result of compilation.  It is also effectively
>>> +cloned when applications link to dynamic libraries.  That is to say
>>> +when an application is compiled to link against dynamic libraries, it
>>> +is assumed that the ABI remains constant between the time the 
>>> application is
>>> compiled/linked, and the time that it runs.
>>> +Therefore, in the case of dynamic linking, it is critical that an ABI
>>> +is preserved, or (when modified), done in such a way that the
>>> +application is unable to behave improperly or in an unexpected 
>>> fashion.
>>> +
>>> +The DPDK ABI policy
>>> +-------------------
>>> +
>>> +ABI versions are set at the time of major release labeling, and the 
>>> ABI
>>> +may change multiple times, without warning, between the last release
>>> +label and the HEAD label of the git tree.
>>> +
>>> +ABI versions, once released, are available until such time as their
>>> +deprecation has been noted in the Release Notes for at least one major
>>> +release cycle. For example consider the case where the ABI for DPDK 
>>> 2.0
>>> +has been shipped and then a decision is made to modify it during the
>>> +development of DPDK 2.1. The decision will be recorded in the Release
>>> +Notes for the DPDK 2.1 release and the modification will be made 
>>> available in
>>> the DPDK 2.2 release.
>>> +
>>> +ABI versions may be deprecated in whole or in part as needed by a 
>>> given
>>> +update.
>>> +
>>> +Some ABI changes may be too significant to reasonably maintain 
>>> multiple
>>> +versions. In those cases ABI's may be updated without backward
>>> +compatibility being provided. The requirements for doing so are:
>>> +
>>> +#. At least 3 acknowledgments of the need to do so must be made on the
>>> +   dpdk.org mailing list.
>>> +
>>> +#. A full deprecation cycle, as explained above, must be made to offer
>>> +   downstream consumers sufficient warning of the change.
>>> +
>>> +#. The ``LIBABIVER`` variable in the makefile(s) where the ABI 
>>> changes are
>>> +   incorporated must be incremented in parallel with the ABI changes
>>> +   themselves.
>>> +
>>> +Note that the above process for ABI deprecation should not be
>>> +undertaken lightly. ABI stability is extremely important for 
>>> downstream
>>> +consumers of the DPDK, especially when distributed in shared object
>>> +form. Every effort should be made to preserve the ABI whenever
>>> +possible. The ABI should only be changed for significant reasons, such
>>> +as performance enhancements. ABI breakage due to changes such as
>>> +reorganizing public structure fields for aesthetic or readability 
>>> purposes should
>>> be avoided.
>>> +
>>> +Examples of Deprecation Notices
>>> +-------------------------------
>>> +
>>> +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 
>>> version
>>> +2.0,
>>> +  to be replaced with the inline function ``rte_foo()``.
>>> +
>>> +* The function ``rte_mbuf_grok()`` has been updated to include a new
>>> +parameter
>>> +  in version 2.0. Backwards compatibility will be maintained for this
>>> +function
>>> +  until the release of version 2.1
>>> +
>>> +* The members of ``struct rte_foo`` have been reorganized in release
>>> +2.0 for
>>> +  performance reasons. Existing binary applications will have 
>>> backwards
>>> +  compatibility in release 2.0, while newly built binaries will 
>>> need to
>>> +  reference the new structure variant ``struct rte_foo2``.
>>> +Compatibility will
>>> +  be removed in release 2.2, 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 2.0 will not contain these changes, but release 2.1
>>> +will,
>>> +  and no backwards compatibility is planned due to the extensive 
>>> nature
>>> +of
>>> +  these changes. Binaries using this library built prior to version 
>>> 2.1
>>> +will
>>> +  require updating and recompilation.
>>> +
>>> +Versioning Macros
>>> +-----------------
>>> +
>>> +When a symbol is exported from a library to provide an API, it also
>>> +provides a calling convention (ABI) that is embodied in its name,
>>> +return type and arguments. Occasionally that function may need to
>>> +change to accommodate new functionality or behavior. When that occurs,
>>> +it is desirable to allow for backward compatibility for a time with
>>> +older binaries that are dynamically linked to the DPDK.
>>> +
>>> +To support backward compatibility the
>>> +``lib/librte_compat/rte_compat.h``
>>> +header file provides macros to use when updating exported functions.
>>> +These macros are used in conjunction with the
>>> +``rte_<library>_version.map`` file for a given library to allow
>>> +multiple versions of a symbol to exist in a shared library so that 
>>> older binaries
>>> need not be immediately recompiled.
>>> +
>>> +The macros exported are:
>>> +
>>> +* ``VERSION_SYMBOL(b, e, n)``: Creates a symbol version table entry
>>> +binding
>>> +  unversioned symbol ``b`` to the internal function ``b_e``.
>>> +
>>> +
>>> +* ``BASE_SYMBOL(b, e)``: Creates a symbol version table entry binding
>>> +  unversioned symbol ``b`` to the internal function ``b_e``.
>>> +
>>> +* ``BIND_DEFAULT_SYMBOL(b, e, n)``: Creates a symbol version entry
>>> +instructing
>>> +  the linker to bind references to symbol ``b`` to the internal symbol
>>> +  ``b_e``.
>>> +
>>> +
>>> +Examples of ABI Macro use
>>> +-------------------------
>>> +
>>> +Updating a public API
>>> +~~~~~~~~~~~~~~~~~~~~~
>>> +
>>> +Assume we have a function as follows
>>> +
>>> +.. code-block:: c
>>> +
>>> + /*
>>> +  * Create an acl context object for apps to
>>> +  * manipulate
>>> +  */
>>> + struct rte_acl_ctx *
>>> + rte_acl_create(const struct rte_acl_param *param) {
>>> +        ...
>>> + }
>>> +
>>> +
>>> +Assume that struct rte_acl_ctx is a private structure, and that a
>>> +developer wishes to enhance the acl api so that a debugging flag 
>>> can be
>>> +enabled on a per-context basis.  This requires an addition to the
>>> +structure (which, being private, is safe), but it also requires
>>> +modifying the code as follows
>>> +
>>> +.. code-block:: c
>>> +
>>> + /*
>>> +  * Create an acl context object for apps to
>>> +  * manipulate
>>> +  */
>>> + struct rte_acl_ctx *
>>> + rte_acl_create(const struct rte_acl_param *param, int debug) {
>>> +        ...
>>> + }
>>> +
>>> +
>>> +Note also that, being a public function, the header file prototype 
>>> must
>>> +also be changed, as must all the call sites, to reflect the new ABI
>>> +footprint.  We will maintain previous ABI versions that are accessible
>>> +only to previously compiled binaries
>>> +
>>> +The addition of a parameter to the function is ABI breaking as the
>>> +function is public, and existing application may use it in its current
>>> +form.  However, the compatibility macros in DPDK allow a developer to
>>> +use symbol versioning so that multiple functions can be mapped to the
>>> +same public symbol based on when an application was linked to it.  To
>>> +see how this is done, we start with the requisite libraries version 
>>> map
>>> +file.  Initially the version map file for the acl library looks like
>>> +this
>>> +
>>> +.. code-block:: none
>>> +
>>> +   DPDK_2.0 {
>>> +        global:
>>> +
>>> +        rte_acl_add_rules;
>>> +        rte_acl_build;
>>> +        rte_acl_classify;
>>> +        rte_acl_classify_alg;
>>> +        rte_acl_classify_scalar;
>>> +        rte_acl_create;
>>> +        rte_acl_dump;
>>> +        rte_acl_find_existing;
>>> +        rte_acl_free;
>>> +        rte_acl_ipv4vlan_add_rules;
>>> +        rte_acl_ipv4vlan_build;
>>> +        rte_acl_list_dump;
>>> +        rte_acl_reset;
>>> +        rte_acl_reset_rules;
>>> +        rte_acl_set_ctx_classify;
>>> +
>>> +        local: *;
>>> +   };
>>> +
>>> +This file needs to be modified as follows
>>> +
>>> +.. code-block:: none
>>> +
>>> +   DPDK_2.0 {
>>> +        global:
>>> +
>>> +        rte_acl_add_rules;
>>> +        rte_acl_build;
>>> +        rte_acl_classify;
>>> +        rte_acl_classify_alg;
>>> +        rte_acl_classify_scalar;
>>> +        rte_acl_create;
>>> +        rte_acl_dump;
>>> +        rte_acl_find_existing;
>>> +        rte_acl_free;
>>> +        rte_acl_ipv4vlan_add_rules;
>>> +        rte_acl_ipv4vlan_build;
>>> +        rte_acl_list_dump;
>>> +        rte_acl_reset;
>>> +        rte_acl_reset_rules;
>>> +        rte_acl_set_ctx_classify;
>>> +
>>> +        local: *;
>>> +   };
>>> +
>>> +   DPDK_2.1 {
>>> +        global:
>>> +        rte_acl_create;
>> One question, does it need a line of "local: *;", like it did in
>> librte_ether/rte_ether_version.map?
> No, it does not. You only need to specify 'local' in the default/base 
> node, which
> in this case/example is DPDK_2.0.
>
> Sergio
Just to be clear, as I think I may have misused the term 'default' here, 
it is recommended
to just specify 'local: *;' in just one node (it could confuse the 
linker) and it doesn't really
matter which one.

Quoting http://www.akkadia.org/drepper/symbol-versioning:
"It makes no sense at all to associate versions with symbols which are 
not exported. Therefore the `local:' sections of all but the base 
version are empty and the `local:' section of the base version simply 
contains `*'. This will match all symbols which are not explicitly 
mentioned in any `global:' list."

Sergio

  reply	other threads:[~2015-06-25  8:00 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-23 19:33 [dpdk-dev] [PATCH 1/2] rte_compat.h : Clean up some typos Neil Horman
2015-06-23 19:33 ` [dpdk-dev] [PATCH 2/2] ABI: Add some documentation Neil Horman
2015-06-24 11:21   ` Mcnamara, John
2015-06-24 11:23 ` [dpdk-dev] [PATCH 1/2] rte_compat.h : Clean up some typos Mcnamara, John
2015-06-24 18:06   ` Neil Horman
2015-06-24 18:34 ` [dpdk-dev] [PATCHv2 " Neil Horman
2015-06-24 18:34   ` [dpdk-dev] [PATCHv2 2/2] ABI: Add some documentation Neil Horman
2015-06-24 21:09     ` Thomas Monjalon
2015-06-25 11:35       ` Neil Horman
2015-06-25 13:22         ` Thomas Monjalon
2015-06-25  7:19     ` Zhang, Helin
2015-06-25  7:42       ` Gonzalez Monroy, Sergio
2015-06-25  8:00         ` Gonzalez Monroy, Sergio [this message]
2015-06-25 12:25       ` Neil Horman
2015-06-29 16:35         ` [dpdk-dev] [PATCH] lib: remove redundant definition of local symbols Thomas Monjalon
2015-06-30 15:50           ` Thomas Monjalon
2015-06-24 19:41   ` [dpdk-dev] [PATCHv2 1/2] rte_compat.h : Clean up some typos Thomas Monjalon
2015-06-24 20:15     ` Neil Horman
2015-06-24 20:49       ` Thomas Monjalon
2015-06-25  7:37 ` [dpdk-dev] [PATCH " Gajdzica, MaciejX T
2015-06-25 12:28   ` Neil Horman
2015-06-25 14:35 ` [dpdk-dev] [PATCHv3 1/3] " Neil Horman
2015-06-25 14:35   ` [dpdk-dev] [PATCHv3 2/3] rte_compat: Add MAP_STATIC_SYMBOL macro Neil Horman
2015-06-26 10:13     ` Gajdzica, MaciejX T
2015-06-26 12:52     ` Thomas Monjalon
2015-06-26 14:30       ` Neil Horman
2015-06-28 20:13         ` Thomas Monjalon
2015-06-29 13:44           ` Neil Horman
2015-06-25 14:35   ` [dpdk-dev] [PATCHv3 3/3] ABI: Add some documentation Neil Horman
2015-06-26 13:00     ` Thomas Monjalon
2015-06-26 14:54       ` Neil Horman
2015-06-28 20:24         ` Thomas Monjalon
2015-06-29 13:53           ` Neil Horman
2015-06-26 12:45   ` [dpdk-dev] [PATCHv3 1/3] rte_compat.h : Clean up some typos Thomas Monjalon
2015-06-29 13:59 ` [dpdk-dev] [PATCHv4 1/4] " Neil Horman
2015-06-29 13:59   ` [dpdk-dev] [PATCHv4 2/4] rte_compat: Add MAP_STATIC_SYMBOL macro Neil Horman
2015-06-29 13:59   ` [dpdk-dev] [PATCHv4 3/4] rte_compat: remove BASE_SYMBOL Neil Horman
2015-06-29 13:59   ` [dpdk-dev] [PATCHv4 4/4] ABI: Add some documentation Neil Horman
2015-06-29 15:07     ` Thomas Monjalon
2015-07-08  9:52   ` [dpdk-dev] [PATCHv4 1/4] rte_compat.h : Clean up some typos Thomas Monjalon
2015-07-08 11:04     ` Neil Horman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=558BB518.20104@intel.com \
    --to=sergio.gonzalez.monroy@intel.com \
    --cc=dev@dpdk.org \
    --cc=helin.zhang@intel.com \
    --cc=nhorman@tuxdriver.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).