[dpdk-dev] [PATCH v5 3/3] mempool: allow for user-owned mempool caches

2016-06-29 Thread Olivier MATZ
Hi Lazaros,

On 06/29/2016 01:47 AM, Lazaros Koromilas wrote:
> The mempool cache is only available to EAL threads as a per-lcore
> resource. Change this so that the user can create and provide their own
> cache on mempool get and put operations. This works with non-EAL threads
> too. This commit introduces the new API calls:
>
>  rte_mempool_cache_create(size, socket_id)
>  rte_mempool_cache_free(cache)
>  rte_mempool_cache_flush(cache, mp)
>  rte_mempool_default_cache(mp, lcore_id)
>
> Changes the API calls:
>
>  rte_mempool_generic_put(mp, obj_table, n, cache, flags)
>  rte_mempool_generic_get(mp, obj_table, n, cache, flags)
>
> The cache-oblivious API calls use the per-lcore default local cache.
>
> Signed-off-by: Lazaros Koromilas 
> Acked-by: Olivier Matz 
> ---
>   app/test/test_mempool.c |  73 ---
>   app/test/test_mempool_perf.c|  73 +--
>   doc/guides/prog_guide/env_abstraction_layer.rst |   4 +-
>   doc/guides/prog_guide/mempool_lib.rst   |   6 +-
>   lib/librte_mempool/rte_mempool.c|  66 +-
>   lib/librte_mempool/rte_mempool.h| 164 
> +---
>   lib/librte_mempool/rte_mempool_version.map  |   4 +
>   7 files changed, 308 insertions(+), 82 deletions(-)
>

Thanks Lazaros for the doc update, looks good to me.


Thomas, as discussed IRL, could you please remove the deprecation
notice and add the following note in release_16_07.rst when applying
the patches?

* **Added mempool external cache for non-EAL thread.**

   Added new functions to create, free or flush a user-owned mempool
   cache for non-EAL threads. Previously, cache was always disabled
   on these threads.


Thanks,
Olivier


[dpdk-dev] [PATCH v5 3/3] mempool: allow for user-owned mempool caches

2016-06-29 Thread Lazaros Koromilas
The mempool cache is only available to EAL threads as a per-lcore
resource. Change this so that the user can create and provide their own
cache on mempool get and put operations. This works with non-EAL threads
too. This commit introduces the new API calls:

rte_mempool_cache_create(size, socket_id)
rte_mempool_cache_free(cache)
rte_mempool_cache_flush(cache, mp)
rte_mempool_default_cache(mp, lcore_id)

Changes the API calls:

rte_mempool_generic_put(mp, obj_table, n, cache, flags)
rte_mempool_generic_get(mp, obj_table, n, cache, flags)

The cache-oblivious API calls use the per-lcore default local cache.

Signed-off-by: Lazaros Koromilas 
Acked-by: Olivier Matz 
---
 app/test/test_mempool.c |  73 ---
 app/test/test_mempool_perf.c|  73 +--
 doc/guides/prog_guide/env_abstraction_layer.rst |   4 +-
 doc/guides/prog_guide/mempool_lib.rst   |   6 +-
 lib/librte_mempool/rte_mempool.c|  66 +-
 lib/librte_mempool/rte_mempool.h| 164 +---
 lib/librte_mempool/rte_mempool_version.map  |   4 +
 7 files changed, 308 insertions(+), 82 deletions(-)

diff --git a/app/test/test_mempool.c b/app/test/test_mempool.c
index 55c2cbc..63c61f3 100644
--- a/app/test/test_mempool.c
+++ b/app/test/test_mempool.c
@@ -75,10 +75,16 @@
 #define MAX_KEEP 16
 #define MEMPOOL_SIZE 
((rte_lcore_count()*(MAX_KEEP+RTE_MEMPOOL_CACHE_MAX_SIZE))-1)

+#define LOG_ERR() printf("test failed at %s():%d\n", __func__, __LINE__)
 #define RET_ERR() do { \
-   printf("test failed at %s():%d\n", __func__, __LINE__); \
+   LOG_ERR();  \
return -1;  \
} while (0)
+#define GOTO_ERR(var, label) do {  \
+   LOG_ERR();  \
+   var = -1;   \
+   goto label; \
+   } while (0)

 static rte_atomic32_t synchro;

@@ -191,7 +197,7 @@ my_obj_init(struct rte_mempool *mp, __attribute__((unused)) 
void *arg,

 /* basic tests (done on one core) */
 static int
-test_mempool_basic(struct rte_mempool *mp)
+test_mempool_basic(struct rte_mempool *mp, int use_external_cache)
 {
uint32_t *objnum;
void **objtable;
@@ -199,47 +205,62 @@ test_mempool_basic(struct rte_mempool *mp)
char *obj_data;
int ret = 0;
unsigned i, j;
+   int offset;
+   struct rte_mempool_cache *cache;
+
+   if (use_external_cache) {
+   /* Create a user-owned mempool cache. */
+   cache = rte_mempool_cache_create(RTE_MEMPOOL_CACHE_MAX_SIZE,
+SOCKET_ID_ANY);
+   if (cache == NULL)
+   RET_ERR();
+   } else {
+   /* May be NULL if cache is disabled. */
+   cache = rte_mempool_default_cache(mp, rte_lcore_id());
+   }

/* dump the mempool status */
rte_mempool_dump(stdout, mp);

printf("get an object\n");
-   if (rte_mempool_get(mp, &obj) < 0)
-   RET_ERR();
+   if (rte_mempool_generic_get(mp, &obj, 1, cache, 0) < 0)
+   GOTO_ERR(ret, out);
rte_mempool_dump(stdout, mp);

/* tests that improve coverage */
printf("get object count\n");
-   if (rte_mempool_count(mp) != MEMPOOL_SIZE - 1)
-   RET_ERR();
+   /* We have to count the extra caches, one in this case. */
+   offset = use_external_cache ? 1 * cache->len : 0;
+   if (rte_mempool_count(mp) + offset != MEMPOOL_SIZE - 1)
+   GOTO_ERR(ret, out);

printf("get private data\n");
if (rte_mempool_get_priv(mp) != (char *)mp +
MEMPOOL_HEADER_SIZE(mp, mp->cache_size))
-   RET_ERR();
+   GOTO_ERR(ret, out);

 #ifndef RTE_EXEC_ENV_BSDAPP /* rte_mem_virt2phy() not supported on bsd */
printf("get physical address of an object\n");
if (rte_mempool_virt2phy(mp, obj) != rte_mem_virt2phy(obj))
-   RET_ERR();
+   GOTO_ERR(ret, out);
 #endif

printf("put the object back\n");
-   rte_mempool_put(mp, obj);
+   rte_mempool_generic_put(mp, &obj, 1, cache, 0);
rte_mempool_dump(stdout, mp);

printf("get 2 objects\n");
-   if (rte_mempool_get(mp, &obj) < 0)
-   RET_ERR();
-   if (rte_mempool_get(mp, &obj2) < 0) {
-   rte_mempool_put(mp, obj);
-   RET_ERR();
+   if (rte_mempool_generic_get(mp, &obj, 1, cache, 0) < 0)
+   GOTO_ERR(ret, out);
+   if (rte_mempool_generic_get(mp, &obj2, 1, cache, 0) < 0) {
+   rte_mempool_generic_put(mp, &obj, 1,