[v3] mempool: return 0 if area is too small on populate

Message ID 20200425222338.2787083-1-thomas@monjalon.net (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers
Series [v3] mempool: return 0 if area is too small on populate |

Checks

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

Commit Message

Thomas Monjalon April 25, 2020, 10:23 p.m. UTC
  From: Olivier Matz <olivier.matz@6wind.com>

Change rte_mempool_populate_iova() and rte_mempool_populate_iova() to
return 0 instead of -EINVAL when there is not enough room to store one
object, as it can be helpful for applications to distinguish this
specific case.

As this is an ABI change, use symbol versioning to preserve old
behavior for binary applications.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---

changes in v3:
    - rebase
    - remove deprecation notice
    - notify API change in release notes
    - fix ABI version from 20.0.1 to 20.0.2 (should be 21 maybe)

This v3 cannot be merged because of a false positive ABI check:

2 Removed functions:
  'function int rte_mempool_populate_iova(rte_mempool*, char*, rte_iova_t, size_t, rte_mempool_memchunk_free_cb_t*, void*)'    {rte_mempool_populate_iova@@DPDK_20.0}
  'function int rte_mempool_populate_virt(rte_mempool*, char*, size_t, size_t, rte_mempool_memchunk_free_cb_t*, void*)'    {rte_mempool_populate_virt@@DPDK_20.0}

---
 doc/guides/rel_notes/deprecation.rst       |  5 --
 doc/guides/rel_notes/release_20_05.rst     |  4 ++
 examples/ntb/ntb_fwd.c                     |  2 +-
 lib/librte_mempool/meson.build             |  2 +
 lib/librte_mempool/rte_mempool.c           | 77 ++++++++++++++++++----
 lib/librte_mempool/rte_mempool.h           | 14 ++--
 lib/librte_mempool/rte_mempool_version.map |  7 ++
 7 files changed, 90 insertions(+), 21 deletions(-)
  

Comments

Ray Kinsella April 27, 2020, 11:44 a.m. UTC | #1
On 25/04/2020 23:23, Thomas Monjalon wrote:
> From: Olivier Matz <olivier.matz@6wind.com>
> 
> Change rte_mempool_populate_iova() and rte_mempool_populate_iova() to
> return 0 instead of -EINVAL when there is not enough room to store one
> object, as it can be helpful for applications to distinguish this
> specific case.
> 
> As this is an ABI change, use symbol versioning to preserve old
> behavior for binary applications.
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> ---
> 
> changes in v3:
>     - rebase
>     - remove deprecation notice
>     - notify API change in release notes
>     - fix ABI version from 20.0.1 to 20.0.2 (should be 21 maybe)

yes, should be v21.

> 
> This v3 cannot be merged because of a false positive ABI check:
> 
> 2 Removed functions:
>   'function int rte_mempool_populate_iova(rte_mempool*, char*, rte_iova_t, size_t, rte_mempool_memchunk_free_cb_t*, void*)'    {rte_mempool_populate_iova@@DPDK_20.0}
>   'function int rte_mempool_populate_virt(rte_mempool*, char*, size_t, size_t, rte_mempool_memchunk_free_cb_t*, void*)'    {rte_mempool_populate_virt@@DPDK_20.0}

Well it's not really a false positive, as the v20 symbols are now missing.
See notes on VERSION_SYMBOL.

> 
> ---
>  doc/guides/rel_notes/deprecation.rst       |  5 --
>  doc/guides/rel_notes/release_20_05.rst     |  4 ++
>  examples/ntb/ntb_fwd.c                     |  2 +-
>  lib/librte_mempool/meson.build             |  2 +
>  lib/librte_mempool/rte_mempool.c           | 77 ++++++++++++++++++----
>  lib/librte_mempool/rte_mempool.h           | 14 ++--
>  lib/librte_mempool/rte_mempool_version.map |  7 ++
>  7 files changed, 90 insertions(+), 21 deletions(-)
> 
> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> index 1339f54f5f..20aa745b77 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -65,11 +65,6 @@ Deprecation Notices
>    structure would be made internal (or removed if all dependencies are cleared)
>    in future releases.
>  
> -* mempool: starting from v20.05, the API of rte_mempool_populate_iova()
> -  and rte_mempool_populate_virt() will change to return 0 instead
> -  of -EINVAL when there is not enough room to store one object. The ABI
> -  will be preserved until 20.11.
> -
>  * ethdev: the legacy filter API, including
>    ``rte_eth_dev_filter_supported()``, ``rte_eth_dev_filter_ctrl()`` as well
>    as filter types MACVLAN, ETHERTYPE, FLEXIBLE, SYN, NTUPLE, TUNNEL, FDIR,
> diff --git a/doc/guides/rel_notes/release_20_05.rst b/doc/guides/rel_notes/release_20_05.rst
> index b124c3f287..ab20a7d021 100644
> --- a/doc/guides/rel_notes/release_20_05.rst
> +++ b/doc/guides/rel_notes/release_20_05.rst
> @@ -241,6 +241,10 @@ API Changes
>     Also, make sure to start the actual text at the margin.
>     =========================================================
>  
> +* mempool: The API of ``rte_mempool_populate_iova()`` and
> +  ``rte_mempool_populate_virt()`` changed to return 0 instead of -EINVAL
> +  when there is not enough room to store one object.
> +
>  
>  ABI Changes
>  -----------
> diff --git a/examples/ntb/ntb_fwd.c b/examples/ntb/ntb_fwd.c
> index d49189e175..eba8ebf9fa 100644
> --- a/examples/ntb/ntb_fwd.c
> +++ b/examples/ntb/ntb_fwd.c
> @@ -1319,7 +1319,7 @@ ntb_mbuf_pool_create(uint16_t mbuf_seg_size, uint32_t nb_mbuf,
>  					mz->len - ntb_info.ntb_hdr_size,
>  					ntb_mempool_mz_free,
>  					(void *)(uintptr_t)mz);
> -		if (ret < 0) {
> +		if (ret <= 0) {
>  			rte_memzone_free(mz);
>  			rte_mempool_free(mp);
>  			return NULL;
> diff --git a/lib/librte_mempool/meson.build b/lib/librte_mempool/meson.build
> index a6e861cbfc..7dbe6b9bea 100644
> --- a/lib/librte_mempool/meson.build
> +++ b/lib/librte_mempool/meson.build
> @@ -9,6 +9,8 @@ foreach flag: extra_flags
>  	endif
>  endforeach
>  
> +use_function_versioning = true
> +
>  sources = files('rte_mempool.c', 'rte_mempool_ops.c',
>  		'rte_mempool_ops_default.c', 'mempool_trace_points.c')
>  headers = files('rte_mempool.h', 'rte_mempool_trace.h',
> diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
> index 0be8f9f59d..edbdafaafb 100644
> --- a/lib/librte_mempool/rte_mempool.c
> +++ b/lib/librte_mempool/rte_mempool.c
> @@ -31,6 +31,7 @@
>  #include <rte_string_fns.h>
>  #include <rte_spinlock.h>
>  #include <rte_tailq.h>
> +#include <rte_function_versioning.h>
>  
>  #include "rte_mempool.h"
>  #include "rte_mempool_trace.h"
> @@ -303,12 +304,17 @@ mempool_ops_alloc_once(struct rte_mempool *mp)
>  	return 0;
>  }
>  
> +__vsym int
> +rte_mempool_populate_iova_v20_0_2(struct rte_mempool *mp, char *vaddr,
> +	rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
> +	void *opaque);
> +
>  /* Add objects in the pool, using a physically contiguous memory
>   * zone. Return the number of objects added, or a negative value
>   * on error.
>   */
> -static int
> -__rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
> +__vsym int
> +rte_mempool_populate_iova_v20_0_2(struct rte_mempool *mp, char *vaddr,
>  	rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
>  	void *opaque)
>  {
> @@ -366,14 +372,27 @@ __rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
>  	return ret;
>  }
>  
> -int
> -rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
> +BIND_DEFAULT_SYMBOL(rte_mempool_populate_iova, _v20_0_2, 20.0.2);
as discussed v21.

> +MAP_STATIC_SYMBOL(
> +	int rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
> +				rte_iova_t iova, size_t len,
> +				rte_mempool_memchunk_free_cb_t *free_cb,
> +				void *opaque),
> +	rte_mempool_populate_iova_v20_0_2);
> +
> +__vsym int
> +rte_mempool_populate_iova_v20(struct rte_mempool *mp, char *vaddr,
> +	rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
> +	void *opaque);
> +
> +__vsym int
> +rte_mempool_populate_iova_v20(struct rte_mempool *mp, char *vaddr,
>  	rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
>  	void *opaque)
>  {
>  	int ret;
>  
> -	ret = __rte_mempool_populate_iova(mp, vaddr, iova, len, free_cb,
> +	ret = rte_mempool_populate_iova_v20_0_2(mp, vaddr, iova, len, free_cb,
>  					opaque);
>  	if (ret == 0)
>  		ret = -EINVAL;
> @@ -381,6 +400,7 @@ rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
>  	rte_mempool_trace_populate_iova(mp, vaddr, iova, len, free_cb, opaque);
>  	return ret;
>  }
> +VERSION_SYMBOL(rte_mempool_populate_iova, _v20_0, 20.0);

this should be

VERSION_SYMBOL(rte_mempool_populate_iova, _v20, 20.0);

>  
>  static rte_iova_t
>  get_iova(void *addr)
> @@ -395,11 +415,16 @@ get_iova(void *addr)
>  	return ms->iova + RTE_PTR_DIFF(addr, ms->addr);
>  }
>  
> +__vsym int
> +rte_mempool_populate_virt_v20_0_2(struct rte_mempool *mp, char *addr,
> +	size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
> +	void *opaque);
> +
>  /* Populate the mempool with a virtual area. Return the number of
>   * objects added, or a negative value on error.
>   */
> -int
> -rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
> +__vsym int
> +rte_mempool_populate_virt_v20_0_2(struct rte_mempool *mp, char *addr,
>  	size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
>  	void *opaque)
>  {
> @@ -432,7 +457,7 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
>  				break;
>  		}
>  
> -		ret = __rte_mempool_populate_iova(mp, addr + off, iova,
> +		ret = rte_mempool_populate_iova_v20_0_2(mp, addr + off, iova,
>  			phys_len, free_cb, opaque);
>  		if (ret == 0)
>  			continue;
> @@ -443,9 +468,6 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
>  		cnt += ret;
>  	}
>  
> -	if (cnt == 0)
> -		return -EINVAL;
> -
>  	rte_mempool_trace_populate_virt(mp, addr, len, pg_sz, free_cb, opaque);
>  	return cnt;
>  
> @@ -453,6 +475,35 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
>  	rte_mempool_free_memchunks(mp);
>  	return ret;
>  }
> +BIND_DEFAULT_SYMBOL(rte_mempool_populate_virt, _v20_0_2, 20.0.2);
as discussed v21.

> +MAP_STATIC_SYMBOL(
> +	int rte_mempool_populate_virt(struct rte_mempool *mp,
> +				char *addr, size_t len, size_t pg_sz,
> +				rte_mempool_memchunk_free_cb_t *free_cb,
> +				void *opaque),
> +	rte_mempool_populate_virt_v20_0_2);
> +
> +__vsym int
> +rte_mempool_populate_virt_v20(struct rte_mempool *mp, char *addr,
> +	size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
> +	void *opaque);
> +
> +__vsym int
> +rte_mempool_populate_virt_v20(struct rte_mempool *mp, char *addr,
> +	size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
> +	void *opaque)
> +{
> +	int ret;
> +
> +	ret = rte_mempool_populate_virt_v20_0_2(mp, addr, len, pg_sz,
> +						free_cb, opaque);
> +
> +	if (ret == 0)
> +		ret = -EINVAL;
> +
> +	return ret;
> +}
> +VERSION_SYMBOL(rte_mempool_populate_virt, _v20_0, 20.0);

this should be
VERSION_SYMBOL(rte_mempool_populate_virt, _v20, 20.0);


>  
>  /* Get the minimal page size used in a mempool before populating it. */
>  int
> @@ -609,6 +660,8 @@ rte_mempool_populate_default(struct rte_mempool *mp)
>  				mz->len, pg_sz,
>  				rte_mempool_memchunk_mz_free,
>  				(void *)(uintptr_t)mz);
> +		if (ret == 0) /* should not happen */
> +			ret = -ENOBUFS;
>  		if (ret < 0) {
>  			rte_memzone_free(mz);
>  			goto fail;
> @@ -701,6 +754,8 @@ rte_mempool_populate_anon(struct rte_mempool *mp)
>  
>  	ret = rte_mempool_populate_virt(mp, addr, size, getpagesize(),
>  		rte_mempool_memchunk_anon_free, addr);
> +	if (ret == 0) /* should not happen */
> +		ret = -ENOBUFS;
>  	if (ret < 0) {
>  		rte_errno = -ret;
>  		goto fail;
> diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h
> index 6e0573ea42..652d19f9f1 100644
> --- a/lib/librte_mempool/rte_mempool.h
> +++ b/lib/librte_mempool/rte_mempool.h
> @@ -1112,9 +1112,12 @@ rte_mempool_free(struct rte_mempool *mp);
>   * @param opaque
>   *   An opaque argument passed to free_cb.
>   * @return
> - *   The number of objects added on success.
> + *   The number of objects added on success (strictly positive).
>   *   On error, the chunk is not added in the memory list of the
> - *   mempool and a negative errno is returned.
> + *   mempool the following code is returned:
> + *     (0): not enough room in chunk for one object.
> + *     (-ENOSPC): mempool is already populated.
> + *     (-ENOMEM): allocation failure.
>   */
>  int rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
>  	rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
> @@ -1139,9 +1142,12 @@ int rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
>   * @param opaque
>   *   An opaque argument passed to free_cb.
>   * @return
> - *   The number of objects added on success.
> + *   The number of objects added on success (strictly positive).
>   *   On error, the chunk is not added in the memory list of the
> - *   mempool and a negative errno is returned.
> + *   mempool the following code is returned:
> + *     (0): not enough room in chunk for one object.
> + *     (-ENOSPC): mempool is already populated.
> + *     (-ENOMEM): allocation failure.
>   */
>  int
>  rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
> diff --git a/lib/librte_mempool/rte_mempool_version.map b/lib/librte_mempool/rte_mempool_version.map
> index 695dd6e04f..9e58093665 100644
> --- a/lib/librte_mempool/rte_mempool_version.map
> +++ b/lib/librte_mempool/rte_mempool_version.map
> @@ -31,6 +31,13 @@ DPDK_20.0 {
>  	local: *;
>  };
>  
> +DPDK_20.0.2 {

as discussed DPDK_21

> +	global:
> +
> +	rte_mempool_populate_iova;
> +	rte_mempool_populate_virt;
> +} DPDK_20.0;
> +
>  EXPERIMENTAL {
>  	global:
>  
>
  
Lukasz Wojciechowski April 27, 2020, 6:02 p.m. UTC | #2
W dniu 27.04.2020 o 13:44, Ray Kinsella pisze:
>
> On 25/04/2020 23:23, Thomas Monjalon wrote:
>> From: Olivier Matz <olivier.matz@6wind.com>
>>
>> Change rte_mempool_populate_iova() and rte_mempool_populate_iova() to
... and rte_mempool_populate_virt()
>> return 0 instead of -EINVAL when there is not enough room to store one
>> object, as it can be helpful for applications to distinguish this
>> specific case.
>>
>> As this is an ABI change, use symbol versioning to preserve old
>> behavior for binary applications.
>>
>> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
>> ---
>>
>> changes in v3:
>>      - rebase
>>      - remove deprecation notice
>>      - notify API change in release notes
>>      - fix ABI version from 20.0.1 to 20.0.2 (should be 21 maybe)
> yes, should be v21.
>
>> This v3 cannot be merged because of a false positive ABI check:
>>
>> 2 Removed functions:
>>    'function int rte_mempool_populate_iova(rte_mempool*, char*, rte_iova_t, size_t, rte_mempool_memchunk_free_cb_t*, void*)'    {rte_mempool_populate_iova@@DPDK_20.0}
>>    'function int rte_mempool_populate_virt(rte_mempool*, char*, size_t, size_t, rte_mempool_memchunk_free_cb_t*, void*)'    {rte_mempool_populate_virt@@DPDK_20.0}
> Well it's not really a false positive, as the v20 symbols are now missing.
> See notes on VERSION_SYMBOL.
>
>> ---
>>   doc/guides/rel_notes/deprecation.rst       |  5 --
>>   doc/guides/rel_notes/release_20_05.rst     |  4 ++
>>   examples/ntb/ntb_fwd.c                     |  2 +-
>>   lib/librte_mempool/meson.build             |  2 +
>>   lib/librte_mempool/rte_mempool.c           | 77 ++++++++++++++++++----
>>   lib/librte_mempool/rte_mempool.h           | 14 ++--
>>   lib/librte_mempool/rte_mempool_version.map |  7 ++
>>   7 files changed, 90 insertions(+), 21 deletions(-)
>>
>> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
>> index 1339f54f5f..20aa745b77 100644
>> --- a/doc/guides/rel_notes/deprecation.rst
>> +++ b/doc/guides/rel_notes/deprecation.rst
>> @@ -65,11 +65,6 @@ Deprecation Notices
>>     structure would be made internal (or removed if all dependencies are cleared)
>>     in future releases.
>>   
>> -* mempool: starting from v20.05, the API of rte_mempool_populate_iova()
>> -  and rte_mempool_populate_virt() will change to return 0 instead
>> -  of -EINVAL when there is not enough room to store one object. The ABI
>> -  will be preserved until 20.11.
>> -
>>   * ethdev: the legacy filter API, including
>>     ``rte_eth_dev_filter_supported()``, ``rte_eth_dev_filter_ctrl()`` as well
>>     as filter types MACVLAN, ETHERTYPE, FLEXIBLE, SYN, NTUPLE, TUNNEL, FDIR,
>> diff --git a/doc/guides/rel_notes/release_20_05.rst b/doc/guides/rel_notes/release_20_05.rst
>> index b124c3f287..ab20a7d021 100644
>> --- a/doc/guides/rel_notes/release_20_05.rst
>> +++ b/doc/guides/rel_notes/release_20_05.rst
>> @@ -241,6 +241,10 @@ API Changes
>>      Also, make sure to start the actual text at the margin.
>>      =========================================================
>>   
>> +* mempool: The API of ``rte_mempool_populate_iova()`` and
>> +  ``rte_mempool_populate_virt()`` changed to return 0 instead of -EINVAL
>> +  when there is not enough room to store one object.
>> +
>>   
>>   ABI Changes
>>   -----------
>> diff --git a/examples/ntb/ntb_fwd.c b/examples/ntb/ntb_fwd.c
>> index d49189e175..eba8ebf9fa 100644
>> --- a/examples/ntb/ntb_fwd.c
>> +++ b/examples/ntb/ntb_fwd.c
>> @@ -1319,7 +1319,7 @@ ntb_mbuf_pool_create(uint16_t mbuf_seg_size, uint32_t nb_mbuf,
>>   					mz->len - ntb_info.ntb_hdr_size,
>>   					ntb_mempool_mz_free,
>>   					(void *)(uintptr_t)mz);
>> -		if (ret < 0) {
>> +		if (ret <= 0) {
>>   			rte_memzone_free(mz);
>>   			rte_mempool_free(mp);
>>   			return NULL;
>> diff --git a/lib/librte_mempool/meson.build b/lib/librte_mempool/meson.build
>> index a6e861cbfc..7dbe6b9bea 100644
>> --- a/lib/librte_mempool/meson.build
>> +++ b/lib/librte_mempool/meson.build
>> @@ -9,6 +9,8 @@ foreach flag: extra_flags
>>   	endif
>>   endforeach
>>   
>> +use_function_versioning = true
>> +
>>   sources = files('rte_mempool.c', 'rte_mempool_ops.c',
>>   		'rte_mempool_ops_default.c', 'mempool_trace_points.c')
>>   headers = files('rte_mempool.h', 'rte_mempool_trace.h',
>> diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
>> index 0be8f9f59d..edbdafaafb 100644
>> --- a/lib/librte_mempool/rte_mempool.c
>> +++ b/lib/librte_mempool/rte_mempool.c
>> @@ -31,6 +31,7 @@
>>   #include <rte_string_fns.h>
>>   #include <rte_spinlock.h>
>>   #include <rte_tailq.h>
>> +#include <rte_function_versioning.h>
>>   
>>   #include "rte_mempool.h"
>>   #include "rte_mempool_trace.h"
>> @@ -303,12 +304,17 @@ mempool_ops_alloc_once(struct rte_mempool *mp)
>>   	return 0;
>>   }
>>   
>> +__vsym int
>> +rte_mempool_populate_iova_v20_0_2(struct rte_mempool *mp, char *vaddr,
>> +	rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
>> +	void *opaque);
>> +
>>   /* Add objects in the pool, using a physically contiguous memory
>>    * zone. Return the number of objects added, or a negative value
>>    * on error.
>>    */
>> -static int
>> -__rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
>> +__vsym int
>> +rte_mempool_populate_iova_v20_0_2(struct rte_mempool *mp, char *vaddr,
>>   	rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
>>   	void *opaque)
>>   {
>> @@ -366,14 +372,27 @@ __rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
>>   	return ret;
>>   }
>>   
>> -int
>> -rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
>> +BIND_DEFAULT_SYMBOL(rte_mempool_populate_iova, _v20_0_2, 20.0.2);
> as discussed v21.
>
>> +MAP_STATIC_SYMBOL(
>> +	int rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
>> +				rte_iova_t iova, size_t len,
>> +				rte_mempool_memchunk_free_cb_t *free_cb,
>> +				void *opaque),
>> +	rte_mempool_populate_iova_v20_0_2);
>> +
>> +__vsym int
>> +rte_mempool_populate_iova_v20(struct rte_mempool *mp, char *vaddr,
>> +	rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
>> +	void *opaque);
>> +
>> +__vsym int
>> +rte_mempool_populate_iova_v20(struct rte_mempool *mp, char *vaddr,
>>   	rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
>>   	void *opaque)
>>   {
>>   	int ret;
>>   
>> -	ret = __rte_mempool_populate_iova(mp, vaddr, iova, len, free_cb,
>> +	ret = rte_mempool_populate_iova_v20_0_2(mp, vaddr, iova, len, free_cb,
>>   					opaque);
>>   	if (ret == 0)
>>   		ret = -EINVAL;
>> @@ -381,6 +400,7 @@ rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
>>   	rte_mempool_trace_populate_iova(mp, vaddr, iova, len, free_cb, opaque);
>>   	return ret;
>>   }
>> +VERSION_SYMBOL(rte_mempool_populate_iova, _v20_0, 20.0);
> this should be
>
> VERSION_SYMBOL(rte_mempool_populate_iova, _v20, 20.0);
>
>>   
>>   static rte_iova_t
>>   get_iova(void *addr)
>> @@ -395,11 +415,16 @@ get_iova(void *addr)
>>   	return ms->iova + RTE_PTR_DIFF(addr, ms->addr);
>>   }
>>   
>> +__vsym int
>> +rte_mempool_populate_virt_v20_0_2(struct rte_mempool *mp, char *addr,
>> +	size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
>> +	void *opaque);
>> +
>>   /* Populate the mempool with a virtual area. Return the number of
>>    * objects added, or a negative value on error.
>>    */
>> -int
>> -rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
>> +__vsym int
>> +rte_mempool_populate_virt_v20_0_2(struct rte_mempool *mp, char *addr,
>>   	size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
>>   	void *opaque)
>>   {
>> @@ -432,7 +457,7 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
>>   				break;
>>   		}
>>   
>> -		ret = __rte_mempool_populate_iova(mp, addr + off, iova,
>> +		ret = rte_mempool_populate_iova_v20_0_2(mp, addr + off, iova,
>>   			phys_len, free_cb, opaque);
>>   		if (ret == 0)
>>   			continue;
>> @@ -443,9 +468,6 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
>>   		cnt += ret;
>>   	}
>>   
>> -	if (cnt == 0)
>> -		return -EINVAL;
>> -
>>   	rte_mempool_trace_populate_virt(mp, addr, len, pg_sz, free_cb, opaque);
>>   	return cnt;
>>   
>> @@ -453,6 +475,35 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
>>   	rte_mempool_free_memchunks(mp);
>>   	return ret;
>>   }
>> +BIND_DEFAULT_SYMBOL(rte_mempool_populate_virt, _v20_0_2, 20.0.2);
> as discussed v21.
>
>> +MAP_STATIC_SYMBOL(
>> +	int rte_mempool_populate_virt(struct rte_mempool *mp,
>> +				char *addr, size_t len, size_t pg_sz,
>> +				rte_mempool_memchunk_free_cb_t *free_cb,
>> +				void *opaque),
>> +	rte_mempool_populate_virt_v20_0_2);
>> +
>> +__vsym int
>> +rte_mempool_populate_virt_v20(struct rte_mempool *mp, char *addr,
>> +	size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
>> +	void *opaque);
>> +
>> +__vsym int
>> +rte_mempool_populate_virt_v20(struct rte_mempool *mp, char *addr,
>> +	size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
>> +	void *opaque)
>> +{
>> +	int ret;
>> +
>> +	ret = rte_mempool_populate_virt_v20_0_2(mp, addr, len, pg_sz,
>> +						free_cb, opaque);
>> +
>> +	if (ret == 0)
>> +		ret = -EINVAL;
>> +
>> +	return ret;
>> +}
>> +VERSION_SYMBOL(rte_mempool_populate_virt, _v20_0, 20.0);
> this should be
> VERSION_SYMBOL(rte_mempool_populate_virt, _v20, 20.0);
>
>
>>   
>>   /* Get the minimal page size used in a mempool before populating it. */
>>   int
>> @@ -609,6 +660,8 @@ rte_mempool_populate_default(struct rte_mempool *mp)
>>   				mz->len, pg_sz,
>>   				rte_mempool_memchunk_mz_free,
>>   				(void *)(uintptr_t)mz);
>> +		if (ret == 0) /* should not happen */
>> +			ret = -ENOBUFS;
>>   		if (ret < 0) {
>>   			rte_memzone_free(mz);
>>   			goto fail;
>> @@ -701,6 +754,8 @@ rte_mempool_populate_anon(struct rte_mempool *mp)
>>   
>>   	ret = rte_mempool_populate_virt(mp, addr, size, getpagesize(),
>>   		rte_mempool_memchunk_anon_free, addr);
>> +	if (ret == 0) /* should not happen */
>> +		ret = -ENOBUFS;
>>   	if (ret < 0) {
>>   		rte_errno = -ret;
>>   		goto fail;
>> diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h
>> index 6e0573ea42..652d19f9f1 100644
>> --- a/lib/librte_mempool/rte_mempool.h
>> +++ b/lib/librte_mempool/rte_mempool.h
>> @@ -1112,9 +1112,12 @@ rte_mempool_free(struct rte_mempool *mp);
>>    * @param opaque
>>    *   An opaque argument passed to free_cb.
>>    * @return
>> - *   The number of objects added on success.
>> + *   The number of objects added on success (strictly positive).
>>    *   On error, the chunk is not added in the memory list of the
>> - *   mempool and a negative errno is returned.
>> + *   mempool the following code is returned:
>> + *     (0): not enough room in chunk for one object.
>> + *     (-ENOSPC): mempool is already populated.
>> + *     (-ENOMEM): allocation failure.
>>    */
>>   int rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
>>   	rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
>> @@ -1139,9 +1142,12 @@ int rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
>>    * @param opaque
>>    *   An opaque argument passed to free_cb.
>>    * @return
>> - *   The number of objects added on success.
>> + *   The number of objects added on success (strictly positive).
>>    *   On error, the chunk is not added in the memory list of the
>> - *   mempool and a negative errno is returned.
>> + *   mempool the following code is returned:
>> + *     (0): not enough room in chunk for one object.
>> + *     (-ENOSPC): mempool is already populated.
>> + *     (-ENOMEM): allocation failure.
>>    */
>>   int
>>   rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
>> diff --git a/lib/librte_mempool/rte_mempool_version.map b/lib/librte_mempool/rte_mempool_version.map
>> index 695dd6e04f..9e58093665 100644
>> --- a/lib/librte_mempool/rte_mempool_version.map
>> +++ b/lib/librte_mempool/rte_mempool_version.map
>> @@ -31,6 +31,13 @@ DPDK_20.0 {
>>   	local: *;
>>   };
>>   
>> +DPDK_20.0.2 {
> as discussed DPDK_21
>
>> +	global:
>> +
>> +	rte_mempool_populate_iova;
>> +	rte_mempool_populate_virt;
>> +} DPDK_20.0;
>> +
>>   EXPERIMENTAL {
>>   	global:
>>   
>>
  

Patch

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 1339f54f5f..20aa745b77 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -65,11 +65,6 @@  Deprecation Notices
   structure would be made internal (or removed if all dependencies are cleared)
   in future releases.
 
-* mempool: starting from v20.05, the API of rte_mempool_populate_iova()
-  and rte_mempool_populate_virt() will change to return 0 instead
-  of -EINVAL when there is not enough room to store one object. The ABI
-  will be preserved until 20.11.
-
 * ethdev: the legacy filter API, including
   ``rte_eth_dev_filter_supported()``, ``rte_eth_dev_filter_ctrl()`` as well
   as filter types MACVLAN, ETHERTYPE, FLEXIBLE, SYN, NTUPLE, TUNNEL, FDIR,
diff --git a/doc/guides/rel_notes/release_20_05.rst b/doc/guides/rel_notes/release_20_05.rst
index b124c3f287..ab20a7d021 100644
--- a/doc/guides/rel_notes/release_20_05.rst
+++ b/doc/guides/rel_notes/release_20_05.rst
@@ -241,6 +241,10 @@  API Changes
    Also, make sure to start the actual text at the margin.
    =========================================================
 
+* mempool: The API of ``rte_mempool_populate_iova()`` and
+  ``rte_mempool_populate_virt()`` changed to return 0 instead of -EINVAL
+  when there is not enough room to store one object.
+
 
 ABI Changes
 -----------
diff --git a/examples/ntb/ntb_fwd.c b/examples/ntb/ntb_fwd.c
index d49189e175..eba8ebf9fa 100644
--- a/examples/ntb/ntb_fwd.c
+++ b/examples/ntb/ntb_fwd.c
@@ -1319,7 +1319,7 @@  ntb_mbuf_pool_create(uint16_t mbuf_seg_size, uint32_t nb_mbuf,
 					mz->len - ntb_info.ntb_hdr_size,
 					ntb_mempool_mz_free,
 					(void *)(uintptr_t)mz);
-		if (ret < 0) {
+		if (ret <= 0) {
 			rte_memzone_free(mz);
 			rte_mempool_free(mp);
 			return NULL;
diff --git a/lib/librte_mempool/meson.build b/lib/librte_mempool/meson.build
index a6e861cbfc..7dbe6b9bea 100644
--- a/lib/librte_mempool/meson.build
+++ b/lib/librte_mempool/meson.build
@@ -9,6 +9,8 @@  foreach flag: extra_flags
 	endif
 endforeach
 
+use_function_versioning = true
+
 sources = files('rte_mempool.c', 'rte_mempool_ops.c',
 		'rte_mempool_ops_default.c', 'mempool_trace_points.c')
 headers = files('rte_mempool.h', 'rte_mempool_trace.h',
diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
index 0be8f9f59d..edbdafaafb 100644
--- a/lib/librte_mempool/rte_mempool.c
+++ b/lib/librte_mempool/rte_mempool.c
@@ -31,6 +31,7 @@ 
 #include <rte_string_fns.h>
 #include <rte_spinlock.h>
 #include <rte_tailq.h>
+#include <rte_function_versioning.h>
 
 #include "rte_mempool.h"
 #include "rte_mempool_trace.h"
@@ -303,12 +304,17 @@  mempool_ops_alloc_once(struct rte_mempool *mp)
 	return 0;
 }
 
+__vsym int
+rte_mempool_populate_iova_v20_0_2(struct rte_mempool *mp, char *vaddr,
+	rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
+	void *opaque);
+
 /* Add objects in the pool, using a physically contiguous memory
  * zone. Return the number of objects added, or a negative value
  * on error.
  */
-static int
-__rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
+__vsym int
+rte_mempool_populate_iova_v20_0_2(struct rte_mempool *mp, char *vaddr,
 	rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
 	void *opaque)
 {
@@ -366,14 +372,27 @@  __rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
 	return ret;
 }
 
-int
-rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
+BIND_DEFAULT_SYMBOL(rte_mempool_populate_iova, _v20_0_2, 20.0.2);
+MAP_STATIC_SYMBOL(
+	int rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
+				rte_iova_t iova, size_t len,
+				rte_mempool_memchunk_free_cb_t *free_cb,
+				void *opaque),
+	rte_mempool_populate_iova_v20_0_2);
+
+__vsym int
+rte_mempool_populate_iova_v20(struct rte_mempool *mp, char *vaddr,
+	rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
+	void *opaque);
+
+__vsym int
+rte_mempool_populate_iova_v20(struct rte_mempool *mp, char *vaddr,
 	rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
 	void *opaque)
 {
 	int ret;
 
-	ret = __rte_mempool_populate_iova(mp, vaddr, iova, len, free_cb,
+	ret = rte_mempool_populate_iova_v20_0_2(mp, vaddr, iova, len, free_cb,
 					opaque);
 	if (ret == 0)
 		ret = -EINVAL;
@@ -381,6 +400,7 @@  rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
 	rte_mempool_trace_populate_iova(mp, vaddr, iova, len, free_cb, opaque);
 	return ret;
 }
+VERSION_SYMBOL(rte_mempool_populate_iova, _v20_0, 20.0);
 
 static rte_iova_t
 get_iova(void *addr)
@@ -395,11 +415,16 @@  get_iova(void *addr)
 	return ms->iova + RTE_PTR_DIFF(addr, ms->addr);
 }
 
+__vsym int
+rte_mempool_populate_virt_v20_0_2(struct rte_mempool *mp, char *addr,
+	size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
+	void *opaque);
+
 /* Populate the mempool with a virtual area. Return the number of
  * objects added, or a negative value on error.
  */
-int
-rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
+__vsym int
+rte_mempool_populate_virt_v20_0_2(struct rte_mempool *mp, char *addr,
 	size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
 	void *opaque)
 {
@@ -432,7 +457,7 @@  rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
 				break;
 		}
 
-		ret = __rte_mempool_populate_iova(mp, addr + off, iova,
+		ret = rte_mempool_populate_iova_v20_0_2(mp, addr + off, iova,
 			phys_len, free_cb, opaque);
 		if (ret == 0)
 			continue;
@@ -443,9 +468,6 @@  rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
 		cnt += ret;
 	}
 
-	if (cnt == 0)
-		return -EINVAL;
-
 	rte_mempool_trace_populate_virt(mp, addr, len, pg_sz, free_cb, opaque);
 	return cnt;
 
@@ -453,6 +475,35 @@  rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
 	rte_mempool_free_memchunks(mp);
 	return ret;
 }
+BIND_DEFAULT_SYMBOL(rte_mempool_populate_virt, _v20_0_2, 20.0.2);
+MAP_STATIC_SYMBOL(
+	int rte_mempool_populate_virt(struct rte_mempool *mp,
+				char *addr, size_t len, size_t pg_sz,
+				rte_mempool_memchunk_free_cb_t *free_cb,
+				void *opaque),
+	rte_mempool_populate_virt_v20_0_2);
+
+__vsym int
+rte_mempool_populate_virt_v20(struct rte_mempool *mp, char *addr,
+	size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
+	void *opaque);
+
+__vsym int
+rte_mempool_populate_virt_v20(struct rte_mempool *mp, char *addr,
+	size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
+	void *opaque)
+{
+	int ret;
+
+	ret = rte_mempool_populate_virt_v20_0_2(mp, addr, len, pg_sz,
+						free_cb, opaque);
+
+	if (ret == 0)
+		ret = -EINVAL;
+
+	return ret;
+}
+VERSION_SYMBOL(rte_mempool_populate_virt, _v20_0, 20.0);
 
 /* Get the minimal page size used in a mempool before populating it. */
 int
@@ -609,6 +660,8 @@  rte_mempool_populate_default(struct rte_mempool *mp)
 				mz->len, pg_sz,
 				rte_mempool_memchunk_mz_free,
 				(void *)(uintptr_t)mz);
+		if (ret == 0) /* should not happen */
+			ret = -ENOBUFS;
 		if (ret < 0) {
 			rte_memzone_free(mz);
 			goto fail;
@@ -701,6 +754,8 @@  rte_mempool_populate_anon(struct rte_mempool *mp)
 
 	ret = rte_mempool_populate_virt(mp, addr, size, getpagesize(),
 		rte_mempool_memchunk_anon_free, addr);
+	if (ret == 0) /* should not happen */
+		ret = -ENOBUFS;
 	if (ret < 0) {
 		rte_errno = -ret;
 		goto fail;
diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h
index 6e0573ea42..652d19f9f1 100644
--- a/lib/librte_mempool/rte_mempool.h
+++ b/lib/librte_mempool/rte_mempool.h
@@ -1112,9 +1112,12 @@  rte_mempool_free(struct rte_mempool *mp);
  * @param opaque
  *   An opaque argument passed to free_cb.
  * @return
- *   The number of objects added on success.
+ *   The number of objects added on success (strictly positive).
  *   On error, the chunk is not added in the memory list of the
- *   mempool and a negative errno is returned.
+ *   mempool the following code is returned:
+ *     (0): not enough room in chunk for one object.
+ *     (-ENOSPC): mempool is already populated.
+ *     (-ENOMEM): allocation failure.
  */
 int rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
 	rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
@@ -1139,9 +1142,12 @@  int rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
  * @param opaque
  *   An opaque argument passed to free_cb.
  * @return
- *   The number of objects added on success.
+ *   The number of objects added on success (strictly positive).
  *   On error, the chunk is not added in the memory list of the
- *   mempool and a negative errno is returned.
+ *   mempool the following code is returned:
+ *     (0): not enough room in chunk for one object.
+ *     (-ENOSPC): mempool is already populated.
+ *     (-ENOMEM): allocation failure.
  */
 int
 rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
diff --git a/lib/librte_mempool/rte_mempool_version.map b/lib/librte_mempool/rte_mempool_version.map
index 695dd6e04f..9e58093665 100644
--- a/lib/librte_mempool/rte_mempool_version.map
+++ b/lib/librte_mempool/rte_mempool_version.map
@@ -31,6 +31,13 @@  DPDK_20.0 {
 	local: *;
 };
 
+DPDK_20.0.2 {
+	global:
+
+	rte_mempool_populate_iova;
+	rte_mempool_populate_virt;
+} DPDK_20.0;
+
 EXPERIMENTAL {
 	global: