When multiple secondary processes run in different containers that
share the same hugetlbfs mount, the fbarray names can collide.
This happens because containers use separate PID namespaces, so
different processes in different containers can have the same PID.

Fix by replacing the PID with a timestamp-based value. The TSC
(timestamp counter) provides sufficient uniqueness since containers
starting at the same CPU cycle is practically impossible - even 1ms
of startup time difference means millions of cycles apart at GHz
frequencies.

Also, reduce the name buffer from PATH_MAX to RTE_FBARRAY_NAME_LEN
since it is only used for the fbarray name.

Signed-off-by: Congjie Zhou <[email protected]>
Signed-off-by: Stephen Hemminger <[email protected]>
---
v4 - update comment and commit message
   - reduce name buffer from 4K to 64 to save stack space
     and catch any future format overflow
 lib/eal/linux/eal_memalloc.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/lib/eal/linux/eal_memalloc.c b/lib/eal/linux/eal_memalloc.c
index 1e60e21620..cbe22c98d0 100644
--- a/lib/eal/linux/eal_memalloc.c
+++ b/lib/eal/linux/eal_memalloc.c
@@ -7,6 +7,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdint.h>
+#include <inttypes.h>
 #include <string.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
@@ -28,6 +29,7 @@
 #include <rte_log.h>
 #include <rte_eal.h>
 #include <rte_memory.h>
+#include <rte_cycles.h>
 
 #include "eal_filesystem.h"
 #include "eal_internal_cfg.h"
@@ -1380,7 +1382,7 @@ secondary_msl_create_walk(const struct rte_memseg_list 
*msl,
 {
        struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
        struct rte_memseg_list *primary_msl, *local_msl;
-       char name[PATH_MAX];
+       char name[RTE_FBARRAY_NAME_LEN];
        int msl_idx, ret;
 
        if (msl->external)
@@ -1390,9 +1392,16 @@ secondary_msl_create_walk(const struct rte_memseg_list 
*msl,
        primary_msl = &mcfg->memsegs[msl_idx];
        local_msl = &local_memsegs[msl_idx];
 
-       /* create distinct fbarrays for each secondary */
-       snprintf(name, RTE_FBARRAY_NAME_LEN, "%s_%i",
-               primary_msl->memseg_arr.name, getpid());
+       /*
+        * Create distinct fbarrays for each secondary using TSC for uniqueness,
+        * since PID is not unique across containers (different PID namespaces).
+        * The worst case name length is:
+        * Base name: "memseg-1048576k-99-99" ~21 chars
+        * Suffix "_<pid>_<16hex>" +24
+        * Total = 44 < RTE_FBARRAY_NAME_LEN 64
+        */
+       snprintf(name, sizeof(name), "%s_%"PRIx64,
+               primary_msl->memseg_arr.name, rte_get_tsc_cycles());
 
        ret = rte_fbarray_init(&local_msl->memseg_arr, name,
                primary_msl->memseg_arr.len,
-- 
2.51.0

Reply via email to