[v5,1/1] eal: add internal ABI marking support

Message ID 20200423031947.4477-2-haiyue.wang@intel.com (mailing list archive)
State Superseded, archived
Delegated to: David Marchand
Headers
Series dpdk: introduce __rte_internal tag |

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/iol-intel-Performance success Performance Testing PASS
ci/iol-nxp-Performance success Performance Testing PASS
ci/iol-mellanox-Performance success Performance Testing PASS
ci/travis-robot success Travis build: passed
ci/Intel-compilation success Compilation OK
ci/iol-testing fail Testing issues

Commit Message

Wang, Haiyue April 23, 2020, 3:19 a.m. UTC
  Introduce __rte_internal tag to mark internal ABI function which is used
by the drivers or other libraries.

Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
---
 buildtools/check-internal-syms.sh   | 57 +++++++++++++++++++++++++++++
 devtools/check-symbol-change.sh     |  7 ++++
 devtools/checkpatches.sh            | 38 +++++++++++++++++++
 devtools/libabigail.abignore        |  5 +++
 drivers/meson.build                 |  2 +-
 lib/librte_eal/include/rte_compat.h | 13 +++++++
 lib/meson.build                     |  2 +-
 mk/internal/rte.compile-pre.mk      |  3 ++
 mk/target/generic/rte.vars.mk       |  1 +
 9 files changed, 126 insertions(+), 2 deletions(-)
 create mode 100755 buildtools/check-internal-syms.sh
  

Comments

David Marchand April 24, 2020, 2:52 p.m. UTC | #1
On Thu, Apr 23, 2020 at 5:25 AM Haiyue Wang <haiyue.wang@intel.com> wrote:
>
> Introduce __rte_internal tag to mark internal ABI function which is used
> by the drivers or other libraries.
>
> Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
> ---
>  buildtools/check-internal-syms.sh   | 57 +++++++++++++++++++++++++++++
>  devtools/check-symbol-change.sh     |  7 ++++
>  devtools/checkpatches.sh            | 38 +++++++++++++++++++
>  devtools/libabigail.abignore        |  5 +++
>  drivers/meson.build                 |  2 +-
>  lib/librte_eal/include/rte_compat.h | 13 +++++++
>  lib/meson.build                     |  2 +-
>  mk/internal/rte.compile-pre.mk      |  3 ++
>  mk/target/generic/rte.vars.mk       |  1 +
>  9 files changed, 126 insertions(+), 2 deletions(-)
>  create mode 100755 buildtools/check-internal-syms.sh

We can have a single script (let's say devtools/check-symbols.sh) that
contains both experimental and internal symbols.


> diff --git a/devtools/check-symbol-change.sh b/devtools/check-symbol-change.sh
> index ed2178e36..978979077 100755
> --- a/devtools/check-symbol-change.sh
> +++ b/devtools/check-symbol-change.sh
> @@ -91,6 +91,13 @@ check_for_rule_violations()
>                 if [ "$ar" = "add" ]
>                 then
>
> +                       if [ "$secname" = "INTERNAL" ]
> +                       then
> +                               # these are absolved from any further checking
> +                               echo "Skipping symbol $symname in INTERNAL"
> +                               continue
> +                       fi
> +
>                         if [ "$secname" = "unknown" ]
>                         then
>                                 # Just inform the user of this occurrence, but

This only handles symbol additions to the INTERNAL section.
Other cases like moving or removing a INTERNAL symbol are not handled.


> diff --git a/devtools/checkpatches.sh b/devtools/checkpatches.sh
> index c30ce64cc..2df8d7f2c 100755
> --- a/devtools/checkpatches.sh
> +++ b/devtools/checkpatches.sh
> @@ -111,6 +111,36 @@ check_experimental_tags() { # <patch>
>         return $res
>  }
>
> +check_internal_tags() { # <patch>
> +       res=0
> +
> +       cat "$1" |awk '
> +       BEGIN {
> +               current_file = "";
> +               ret = 0;
> +       }
> +       /^+++ b\// {
> +               current_file = $2;
> +       }
> +       /^+.*__rte_internal/ {
> +               if (current_file ~ ".c$" ) {
> +                       print "Please only put __rte_internal tags in " \
> +                               "headers ("current_file")";
> +                       ret = 1;
> +               }
> +               if ($1 != "+__rte_internal" || $2 != "") {
> +                       print "__rte_internal must appear alone on the line" \
> +                               " immediately preceding the return type of a function."
> +                       ret = 1;
> +               }
> +       }
> +       END {
> +               exit ret;
> +       }' || res=1
> +
> +       return $res
> +}
> +
>  number=0
>  range='origin/master..'
>  quiet=false
> @@ -194,6 +224,14 @@ check () { # <patch> <commit> <title>
>                 ret=1
>         fi
>
> +       ! $verbose || printf '\nChecking __rte_internal tags:\n'
> +       report=$(check_internal_tags "$tmpinput")
> +       if [ $? -ne 0 ] ; then
> +               $headline_printed || print_headline "$3"
> +               printf '%s\n' "$report"
> +               ret=1
> +       fi
> +
>         if [ "$tmpinput" != "$1" ]; then
>                 rm -f "$tmpinput"
>                 trap - INT
> diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
> index cd86d89ca..3e8e2ea74 100644
> --- a/devtools/libabigail.abignore
> +++ b/devtools/libabigail.abignore
> @@ -3,6 +3,11 @@
>  [suppress_variable]
>          symbol_version = EXPERIMENTAL
>
> +[suppress_function]
> +        symbol_version = INTERNAL
> +[suppress_variable]
> +        symbol_version = INTERNAL
> +
>  ; Explicit ignore for driver-only ABI
>  [suppress_type]
>          name = rte_cryptodev_ops
> diff --git a/drivers/meson.build b/drivers/meson.build
> index 4d8f842ab..cac07161f 100644
> --- a/drivers/meson.build
> +++ b/drivers/meson.build
> @@ -20,7 +20,7 @@ dpdk_driver_classes = ['common',
>  disabled_drivers = run_command(list_dir_globs, get_option('disable_drivers'),
>                 ).stdout().split()
>
> -default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API']
> +default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API'] + ['-DALLOW_INTERNAL_API']

Nit:
default_cflags = machine_args
default_cflags += ['-DALLOW_EXPERIMENTAL_API']
default_cflags += ['-DALLOW_INTERNAL_API']

>  if cc.has_argument('-Wno-format-truncation')
>         default_cflags += '-Wno-format-truncation'
>  endif

More importantly on this file:

- drivers/meson.build is not updated to check for internal symbols, see:
  https://git.dpdk.org/dpdk/tree/drivers/meson.build#n166


- For fully experimental libraries, we have a special so version:
  https://git.dpdk.org/dpdk/tree/drivers/meson.build#n131

  This will apply to common drivers that will be 100% internal.
  Not sure if this is an issue.


> diff --git a/lib/librte_eal/include/rte_compat.h b/lib/librte_eal/include/rte_compat.h
> index 3eb33784b..4cd8f68d6 100644
> --- a/lib/librte_eal/include/rte_compat.h
> +++ b/lib/librte_eal/include/rte_compat.h
> @@ -19,4 +19,17 @@ __attribute__((section(".text.experimental")))
>
>  #endif
>
> +#ifndef ALLOW_INTERNAL_API
> +
> +#define __rte_internal \
> +__attribute__((error("Symbol is not public ABI"), \
> +section(".text.internal")))
> +
> +#else
> +
> +#define __rte_internal \
> +__attribute__((section(".text.internal")))
> +
> +#endif
> +
>  #endif /* _RTE_COMPAT_H_ */
> diff --git a/lib/meson.build b/lib/meson.build
> index c28b8df83..4d2f90d6a 100644
> --- a/lib/meson.build
> +++ b/lib/meson.build
> @@ -38,7 +38,7 @@ if is_windows
>         libraries = ['kvargs','eal'] # only supported libraries for windows
>  endif
>
> -default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API']
> +default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API'] + ['-DALLOW_INTERNAL_API']

Same comments as for drivers/meson.build.


> diff --git a/mk/internal/rte.compile-pre.mk b/mk/internal/rte.compile-pre.mk
> index 82fe098f7..0369786a5 100644
> --- a/mk/internal/rte.compile-pre.mk
> +++ b/mk/internal/rte.compile-pre.mk
> @@ -58,6 +58,8 @@ C_TO_O_DISP = $(if $(V),"$(C_TO_O_STR)","  CC $(@)")
>  endif
>  EXPERIMENTAL_CHECK = $(RTE_SDK)/buildtools/check-experimental-syms.sh
>  CHECK_EXPERIMENTAL = $(EXPERIMENTAL_CHECK) $(SRCDIR)/$(EXPORT_MAP) $@
> +INTERNAL_CHECK = $(RTE_SDK)/buildtools/check-internal-syms.sh
> +CHECK_INTERNAL = $(INTERNAL_CHECK) $(SRCDIR)/$(EXPORT_MAP) $@

With a single script, we can go with:
CHECK_SYMBOLS_SCRIPT = $(RTE_SDK)/buildtools/check-symbols.sh
CHECK_SYMBOLS = $(CHECK_SYMBOLS_SCRIPT) $(SRCDIR)/$(EXPORT_MAP) $@

>
>  PMDINFO_GEN = $(RTE_SDK_BIN)/app/dpdk-pmdinfogen $@ $@.pmd.c
>  PMDINFO_CC = $(CC) $(CPPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@.pmd.o $@.pmd.c
> @@ -76,6 +78,7 @@ C_TO_O_DO = @set -e; \
>         $(C_TO_O) && \
>         $(PMDINFO_TO_O) && \
>         $(CHECK_EXPERIMENTAL) && \
> +       $(CHECK_INTERNAL) && \

+       $(CHECK_SYMBOLS) && \

>         echo $(C_TO_O_CMD) > $(call obj2cmd,$(@)) && \
>         sed 's,'$@':,dep_'$@' =,' $(call obj2dep,$(@)).tmp > $(call obj2dep,$(@)) && \
>         rm -f $(call obj2dep,$(@)).tmp
> diff --git a/mk/target/generic/rte.vars.mk b/mk/target/generic/rte.vars.mk
> index ec2672897..11b0418e5 100644
> --- a/mk/target/generic/rte.vars.mk
> +++ b/mk/target/generic/rte.vars.mk
> @@ -106,6 +106,7 @@ ifeq ($(BUILDING_RTE_SDK),1)
>  # building sdk
>  CFLAGS += -include $(RTE_OUTPUT)/include/rte_config.h
>  CFLAGS += -DALLOW_EXPERIMENTAL_API
> +CFLAGS += -DALLOW_INTERNAL_API
>  else
>  # if we are building an external application, include SDK's lib and
>  # includes too
> --
> 2.26.2
>

We are missing updates on devtools/check-abi-version.sh and
devtools/update_version_map_abi.py.
  
Wang, Haiyue April 25, 2020, 6:10 a.m. UTC | #2
Hi David,

Try to fix the issues you mentioned, except below, plan to
another patch set, I need more time to test these adding.

====

We are missing updates on devtools/check-abi-version.sh and
devtools/update_version_map_abi.py.

More importantly on this file:

- drivers/meson.build is not updated to check for internal symbols, see:
  https://git.dpdk.org/dpdk/tree/drivers/meson.build#n166


- For fully experimental libraries, we have a special so version:
  https://git.dpdk.org/dpdk/tree/drivers/meson.build#n131

  This will apply to common drivers that will be 100% internal.
  Not sure if this is an issue.

BR,
Haiyue

> -----Original Message-----
> From: David Marchand <david.marchand@redhat.com>
> Sent: Friday, April 24, 2020 22:53
> To: Wang, Haiyue <haiyue.wang@intel.com>
> Cc: dev <dev@dpdk.org>; Thomas Monjalon <thomas@monjalon.net>; Richardson, Bruce
> <bruce.richardson@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>; Neil Horman
> <nhorman@tuxdriver.com>; Ray Kinsella <mdr@ashroe.eu>
> Subject: Re: [PATCH v5 1/1] eal: add internal ABI marking support
> 
> On Thu, Apr 23, 2020 at 5:25 AM Haiyue Wang <haiyue.wang@intel.com> wrote:
> >
> > Introduce __rte_internal tag to mark internal ABI function which is used
> > by the drivers or other libraries.
> >
> > Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
> > ---
> >  buildtools/check-internal-syms.sh   | 57 +++++++++++++++++++++++++++++
> >  devtools/check-symbol-change.sh     |  7 ++++
> >  devtools/checkpatches.sh            | 38 +++++++++++++++++++
> >  devtools/libabigail.abignore        |  5 +++
> >  drivers/meson.build                 |  2 +-
> >  lib/librte_eal/include/rte_compat.h | 13 +++++++
> >  lib/meson.build                     |  2 +-
> >  mk/internal/rte.compile-pre.mk      |  3 ++
> >  mk/target/generic/rte.vars.mk       |  1 +
> >  9 files changed, 126 insertions(+), 2 deletions(-)
> >  create mode 100755 buildtools/check-internal-syms.sh
> 
> We can have a single script (let's say devtools/check-symbols.sh) that
> contains both experimental and internal symbols.
> 
> 
> > diff --git a/devtools/check-symbol-change.sh b/devtools/check-symbol-change.sh
> > index ed2178e36..978979077 100755
> > --- a/devtools/check-symbol-change.sh
> > +++ b/devtools/check-symbol-change.sh
> > @@ -91,6 +91,13 @@ check_for_rule_violations()
> >                 if [ "$ar" = "add" ]
> >                 then
> >
> > +                       if [ "$secname" = "INTERNAL" ]
> > +                       then
> > +                               # these are absolved from any further checking
> > +                               echo "Skipping symbol $symname in INTERNAL"
> > +                               continue
> > +                       fi
> > +
> >                         if [ "$secname" = "unknown" ]
> >                         then
> >                                 # Just inform the user of this occurrence, but
> 
> This only handles symbol additions to the INTERNAL section.
> Other cases like moving or removing a INTERNAL symbol are not handled.
> 
> 
> > diff --git a/devtools/checkpatches.sh b/devtools/checkpatches.sh
> > index c30ce64cc..2df8d7f2c 100755
> > --- a/devtools/checkpatches.sh
> > +++ b/devtools/checkpatches.sh
> > @@ -111,6 +111,36 @@ check_experimental_tags() { # <patch>
> >         return $res
> >  }
> >
> > +check_internal_tags() { # <patch>
> > +       res=0
> > +
> > +       cat "$1" |awk '
> > +       BEGIN {
> > +               current_file = "";
> > +               ret = 0;
> > +       }
> > +       /^+++ b\// {
> > +               current_file = $2;
> > +       }
> > +       /^+.*__rte_internal/ {
> > +               if (current_file ~ ".c$" ) {
> > +                       print "Please only put __rte_internal tags in " \
> > +                               "headers ("current_file")";
> > +                       ret = 1;
> > +               }
> > +               if ($1 != "+__rte_internal" || $2 != "") {
> > +                       print "__rte_internal must appear alone on the line" \
> > +                               " immediately preceding the return type of a function."
> > +                       ret = 1;
> > +               }
> > +       }
> > +       END {
> > +               exit ret;
> > +       }' || res=1
> > +
> > +       return $res
> > +}
> > +
> >  number=0
> >  range='origin/master..'
> >  quiet=false
> > @@ -194,6 +224,14 @@ check () { # <patch> <commit> <title>
> >                 ret=1
> >         fi
> >
> > +       ! $verbose || printf '\nChecking __rte_internal tags:\n'
> > +       report=$(check_internal_tags "$tmpinput")
> > +       if [ $? -ne 0 ] ; then
> > +               $headline_printed || print_headline "$3"
> > +               printf '%s\n' "$report"
> > +               ret=1
> > +       fi
> > +
> >         if [ "$tmpinput" != "$1" ]; then
> >                 rm -f "$tmpinput"
> >                 trap - INT
> > diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
> > index cd86d89ca..3e8e2ea74 100644
> > --- a/devtools/libabigail.abignore
> > +++ b/devtools/libabigail.abignore
> > @@ -3,6 +3,11 @@
> >  [suppress_variable]
> >          symbol_version = EXPERIMENTAL
> >
> > +[suppress_function]
> > +        symbol_version = INTERNAL
> > +[suppress_variable]
> > +        symbol_version = INTERNAL
> > +
> >  ; Explicit ignore for driver-only ABI
> >  [suppress_type]
> >          name = rte_cryptodev_ops
> > diff --git a/drivers/meson.build b/drivers/meson.build
> > index 4d8f842ab..cac07161f 100644
> > --- a/drivers/meson.build
> > +++ b/drivers/meson.build
> > @@ -20,7 +20,7 @@ dpdk_driver_classes = ['common',
> >  disabled_drivers = run_command(list_dir_globs, get_option('disable_drivers'),
> >                 ).stdout().split()
> >
> > -default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API']
> > +default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API'] + ['-DALLOW_INTERNAL_API']
> 
> Nit:
> default_cflags = machine_args
> default_cflags += ['-DALLOW_EXPERIMENTAL_API']
> default_cflags += ['-DALLOW_INTERNAL_API']
> 
> >  if cc.has_argument('-Wno-format-truncation')
> >         default_cflags += '-Wno-format-truncation'
> >  endif
> 
> More importantly on this file:
> 
> - drivers/meson.build is not updated to check for internal symbols, see:
>   https://git.dpdk.org/dpdk/tree/drivers/meson.build#n166
> 
> 
> - For fully experimental libraries, we have a special so version:
>   https://git.dpdk.org/dpdk/tree/drivers/meson.build#n131
> 
>   This will apply to common drivers that will be 100% internal.
>   Not sure if this is an issue.
> 
> 
> > diff --git a/lib/librte_eal/include/rte_compat.h b/lib/librte_eal/include/rte_compat.h
> > index 3eb33784b..4cd8f68d6 100644
> > --- a/lib/librte_eal/include/rte_compat.h
> > +++ b/lib/librte_eal/include/rte_compat.h
> > @@ -19,4 +19,17 @@ __attribute__((section(".text.experimental")))
> >
> >  #endif
> >
> > +#ifndef ALLOW_INTERNAL_API
> > +
> > +#define __rte_internal \
> > +__attribute__((error("Symbol is not public ABI"), \
> > +section(".text.internal")))
> > +
> > +#else
> > +
> > +#define __rte_internal \
> > +__attribute__((section(".text.internal")))
> > +
> > +#endif
> > +
> >  #endif /* _RTE_COMPAT_H_ */
> > diff --git a/lib/meson.build b/lib/meson.build
> > index c28b8df83..4d2f90d6a 100644
> > --- a/lib/meson.build
> > +++ b/lib/meson.build
> > @@ -38,7 +38,7 @@ if is_windows
> >         libraries = ['kvargs','eal'] # only supported libraries for windows
> >  endif
> >
> > -default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API']
> > +default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API'] + ['-DALLOW_INTERNAL_API']
> 
> Same comments as for drivers/meson.build.
> 
> 
> > diff --git a/mk/internal/rte.compile-pre.mk b/mk/internal/rte.compile-pre.mk
> > index 82fe098f7..0369786a5 100644
> > --- a/mk/internal/rte.compile-pre.mk
> > +++ b/mk/internal/rte.compile-pre.mk
> > @@ -58,6 +58,8 @@ C_TO_O_DISP = $(if $(V),"$(C_TO_O_STR)","  CC $(@)")
> >  endif
> >  EXPERIMENTAL_CHECK = $(RTE_SDK)/buildtools/check-experimental-syms.sh
> >  CHECK_EXPERIMENTAL = $(EXPERIMENTAL_CHECK) $(SRCDIR)/$(EXPORT_MAP) $@
> > +INTERNAL_CHECK = $(RTE_SDK)/buildtools/check-internal-syms.sh
> > +CHECK_INTERNAL = $(INTERNAL_CHECK) $(SRCDIR)/$(EXPORT_MAP) $@
> 
> With a single script, we can go with:
> CHECK_SYMBOLS_SCRIPT = $(RTE_SDK)/buildtools/check-symbols.sh
> CHECK_SYMBOLS = $(CHECK_SYMBOLS_SCRIPT) $(SRCDIR)/$(EXPORT_MAP) $@
> 
> >
> >  PMDINFO_GEN = $(RTE_SDK_BIN)/app/dpdk-pmdinfogen $@ $@.pmd.c
> >  PMDINFO_CC = $(CC) $(CPPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@.pmd.o $@.pmd.c
> > @@ -76,6 +78,7 @@ C_TO_O_DO = @set -e; \
> >         $(C_TO_O) && \
> >         $(PMDINFO_TO_O) && \
> >         $(CHECK_EXPERIMENTAL) && \
> > +       $(CHECK_INTERNAL) && \
> 
> +       $(CHECK_SYMBOLS) && \
> 
> >         echo $(C_TO_O_CMD) > $(call obj2cmd,$(@)) && \
> >         sed 's,'$@':,dep_'$@' =,' $(call obj2dep,$(@)).tmp > $(call obj2dep,$(@)) && \
> >         rm -f $(call obj2dep,$(@)).tmp
> > diff --git a/mk/target/generic/rte.vars.mk b/mk/target/generic/rte.vars.mk
> > index ec2672897..11b0418e5 100644
> > --- a/mk/target/generic/rte.vars.mk
> > +++ b/mk/target/generic/rte.vars.mk
> > @@ -106,6 +106,7 @@ ifeq ($(BUILDING_RTE_SDK),1)
> >  # building sdk
> >  CFLAGS += -include $(RTE_OUTPUT)/include/rte_config.h
> >  CFLAGS += -DALLOW_EXPERIMENTAL_API
> > +CFLAGS += -DALLOW_INTERNAL_API
> >  else
> >  # if we are building an external application, include SDK's lib and
> >  # includes too
> > --
> > 2.26.2
> >
> 
> We are missing updates on devtools/check-abi-version.sh and
> devtools/update_version_map_abi.py.
> 
> 
> --
> David Marchand
  
David Marchand April 25, 2020, 2:21 p.m. UTC | #3
On Sat, Apr 25, 2020 at 8:10 AM Wang, Haiyue <haiyue.wang@intel.com> wrote:
>
> Hi David,
>
> Try to fix the issues you mentioned, except below, plan to
> another patch set, I need more time to test these adding.

Thanks for working on this topic.


>
> ====
>
> We are missing updates on devtools/check-abi-version.sh and
> devtools/update_version_map_abi.py.

Those two scripts can be updated later:
- I suspect the first one to be broken already,
- the 2nd one is for 20.11 when we will update all map files.


>
> More importantly on this file:
>
> - drivers/meson.build is not updated to check for internal symbols, see:
>   https://git.dpdk.org/dpdk/tree/drivers/meson.build#n166

On this point, your series is almost good to go, I would just get rid
of the "experimental" mentions.
I will reply on the patch.


> - For fully experimental libraries, we have a special so version:
>   https://git.dpdk.org/dpdk/tree/drivers/meson.build#n131
>
>   This will apply to common drivers that will be 100% internal.
>   Not sure if this is an issue.

This part should be fine, I want others to be aware of this.
  
Thomas Monjalon April 25, 2020, 2:24 p.m. UTC | #4
25/04/2020 16:21, David Marchand:
> On Sat, Apr 25, 2020 at 8:10 AM Wang, Haiyue <haiyue.wang@intel.com> wrote:
> > - For fully experimental libraries, we have a special so version:
> >   https://git.dpdk.org/dpdk/tree/drivers/meson.build#n131
> >
> >   This will apply to common drivers that will be 100% internal.
> >   Not sure if this is an issue.
> 
> This part should be fine, I want others to be aware of this.

I am not one of the ABI maintainers, but in my opinion it is OK
to have "pure internal" libs with version 0.x.
  

Patch

diff --git a/buildtools/check-internal-syms.sh b/buildtools/check-internal-syms.sh
new file mode 100755
index 000000000..5043acf87
--- /dev/null
+++ b/buildtools/check-internal-syms.sh
@@ -0,0 +1,57 @@ 
+#!/bin/sh
+
+# SPDX-License-Identifier: BSD-3-Clause
+
+MAPFILE=$1
+OBJFILE=$2
+
+LIST_SYMBOL=$(dirname $(readlink -f $0))/map-list-symbol.sh
+
+# added check for "make -C test/" usage
+if [ ! -e $MAPFILE ] || [ ! -f $OBJFILE ]
+then
+	exit 0
+fi
+
+if [ -d $MAPFILE ]
+then
+	exit 0
+fi
+
+DUMPFILE=$(mktemp -t dpdk.${0##*/}.XXX.objdump)
+trap 'rm -f "$DUMPFILE"' EXIT
+objdump -t $OBJFILE >$DUMPFILE
+
+ret=0
+for SYM in `$LIST_SYMBOL -S INTERNAL $MAPFILE |cut -d ' ' -f 3`
+do
+	if grep -q "\.text.*[[:space:]]$SYM$" $DUMPFILE &&
+		! grep -q "\.text\.internal.*[[:space:]]$SYM$" $DUMPFILE
+	then
+		cat >&2 <<- END_OF_MESSAGE
+		$SYM is not flagged as internal
+		but is listed in version map
+		Please add __rte_internal to the definition of $SYM
+		END_OF_MESSAGE
+		ret=1
+	fi
+done
+
+# Filter out symbols suffixed with a . for icc
+for SYM in `awk '{
+	if ($2 != "l" && $4 == ".text.internal" && !($NF ~ /\.$/)) {
+		print $NF
+	}
+}' $DUMPFILE`
+do
+	$LIST_SYMBOL -S INTERNAL -s $SYM -q $MAPFILE || {
+		cat >&2 <<- END_OF_MESSAGE
+		$SYM is flagged as internal
+		but is not listed in version map
+		Please add $SYM to the version map
+		END_OF_MESSAGE
+		ret=1
+	}
+done
+
+exit $ret
diff --git a/devtools/check-symbol-change.sh b/devtools/check-symbol-change.sh
index ed2178e36..978979077 100755
--- a/devtools/check-symbol-change.sh
+++ b/devtools/check-symbol-change.sh
@@ -91,6 +91,13 @@  check_for_rule_violations()
 		if [ "$ar" = "add" ]
 		then
 
+			if [ "$secname" = "INTERNAL" ]
+			then
+				# these are absolved from any further checking
+				echo "Skipping symbol $symname in INTERNAL"
+				continue
+			fi
+
 			if [ "$secname" = "unknown" ]
 			then
 				# Just inform the user of this occurrence, but
diff --git a/devtools/checkpatches.sh b/devtools/checkpatches.sh
index c30ce64cc..2df8d7f2c 100755
--- a/devtools/checkpatches.sh
+++ b/devtools/checkpatches.sh
@@ -111,6 +111,36 @@  check_experimental_tags() { # <patch>
 	return $res
 }
 
+check_internal_tags() { # <patch>
+	res=0
+
+	cat "$1" |awk '
+	BEGIN {
+		current_file = "";
+		ret = 0;
+	}
+	/^+++ b\// {
+		current_file = $2;
+	}
+	/^+.*__rte_internal/ {
+		if (current_file ~ ".c$" ) {
+			print "Please only put __rte_internal tags in " \
+				"headers ("current_file")";
+			ret = 1;
+		}
+		if ($1 != "+__rte_internal" || $2 != "") {
+			print "__rte_internal must appear alone on the line" \
+				" immediately preceding the return type of a function."
+			ret = 1;
+		}
+	}
+	END {
+		exit ret;
+	}' || res=1
+
+	return $res
+}
+
 number=0
 range='origin/master..'
 quiet=false
@@ -194,6 +224,14 @@  check () { # <patch> <commit> <title>
 		ret=1
 	fi
 
+	! $verbose || printf '\nChecking __rte_internal tags:\n'
+	report=$(check_internal_tags "$tmpinput")
+	if [ $? -ne 0 ] ; then
+		$headline_printed || print_headline "$3"
+		printf '%s\n' "$report"
+		ret=1
+	fi
+
 	if [ "$tmpinput" != "$1" ]; then
 		rm -f "$tmpinput"
 		trap - INT
diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
index cd86d89ca..3e8e2ea74 100644
--- a/devtools/libabigail.abignore
+++ b/devtools/libabigail.abignore
@@ -3,6 +3,11 @@ 
 [suppress_variable]
         symbol_version = EXPERIMENTAL
 
+[suppress_function]
+        symbol_version = INTERNAL
+[suppress_variable]
+        symbol_version = INTERNAL
+
 ; Explicit ignore for driver-only ABI
 [suppress_type]
         name = rte_cryptodev_ops
diff --git a/drivers/meson.build b/drivers/meson.build
index 4d8f842ab..cac07161f 100644
--- a/drivers/meson.build
+++ b/drivers/meson.build
@@ -20,7 +20,7 @@  dpdk_driver_classes = ['common',
 disabled_drivers = run_command(list_dir_globs, get_option('disable_drivers'),
 		).stdout().split()
 
-default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API']
+default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API'] + ['-DALLOW_INTERNAL_API']
 if cc.has_argument('-Wno-format-truncation')
 	default_cflags += '-Wno-format-truncation'
 endif
diff --git a/lib/librte_eal/include/rte_compat.h b/lib/librte_eal/include/rte_compat.h
index 3eb33784b..4cd8f68d6 100644
--- a/lib/librte_eal/include/rte_compat.h
+++ b/lib/librte_eal/include/rte_compat.h
@@ -19,4 +19,17 @@  __attribute__((section(".text.experimental")))
 
 #endif
 
+#ifndef ALLOW_INTERNAL_API
+
+#define __rte_internal \
+__attribute__((error("Symbol is not public ABI"), \
+section(".text.internal")))
+
+#else
+
+#define __rte_internal \
+__attribute__((section(".text.internal")))
+
+#endif
+
 #endif /* _RTE_COMPAT_H_ */
diff --git a/lib/meson.build b/lib/meson.build
index c28b8df83..4d2f90d6a 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -38,7 +38,7 @@  if is_windows
 	libraries = ['kvargs','eal'] # only supported libraries for windows
 endif
 
-default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API']
+default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API'] + ['-DALLOW_INTERNAL_API']
 if cc.has_argument('-Wno-format-truncation')
 	default_cflags += '-Wno-format-truncation'
 endif
diff --git a/mk/internal/rte.compile-pre.mk b/mk/internal/rte.compile-pre.mk
index 82fe098f7..0369786a5 100644
--- a/mk/internal/rte.compile-pre.mk
+++ b/mk/internal/rte.compile-pre.mk
@@ -58,6 +58,8 @@  C_TO_O_DISP = $(if $(V),"$(C_TO_O_STR)","  CC $(@)")
 endif
 EXPERIMENTAL_CHECK = $(RTE_SDK)/buildtools/check-experimental-syms.sh
 CHECK_EXPERIMENTAL = $(EXPERIMENTAL_CHECK) $(SRCDIR)/$(EXPORT_MAP) $@
+INTERNAL_CHECK = $(RTE_SDK)/buildtools/check-internal-syms.sh
+CHECK_INTERNAL = $(INTERNAL_CHECK) $(SRCDIR)/$(EXPORT_MAP) $@
 
 PMDINFO_GEN = $(RTE_SDK_BIN)/app/dpdk-pmdinfogen $@ $@.pmd.c
 PMDINFO_CC = $(CC) $(CPPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@.pmd.o $@.pmd.c
@@ -76,6 +78,7 @@  C_TO_O_DO = @set -e; \
 	$(C_TO_O) && \
 	$(PMDINFO_TO_O) && \
 	$(CHECK_EXPERIMENTAL) && \
+	$(CHECK_INTERNAL) && \
 	echo $(C_TO_O_CMD) > $(call obj2cmd,$(@)) && \
 	sed 's,'$@':,dep_'$@' =,' $(call obj2dep,$(@)).tmp > $(call obj2dep,$(@)) && \
 	rm -f $(call obj2dep,$(@)).tmp
diff --git a/mk/target/generic/rte.vars.mk b/mk/target/generic/rte.vars.mk
index ec2672897..11b0418e5 100644
--- a/mk/target/generic/rte.vars.mk
+++ b/mk/target/generic/rte.vars.mk
@@ -106,6 +106,7 @@  ifeq ($(BUILDING_RTE_SDK),1)
 # building sdk
 CFLAGS += -include $(RTE_OUTPUT)/include/rte_config.h
 CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -DALLOW_INTERNAL_API
 else
 # if we are building an external application, include SDK's lib and
 # includes too