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

