From: Congjie Zhou <[email protected]>

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.

Fixes: 046aa5c4477b ("mem: add memalloc init stage")
Cc: [email protected]

Signed-off-by: Congjie Zhou <[email protected]>
Signed-off-by: Stephen Hemminger <[email protected]>
---
v6 - fix typo in subject
   - add pid to name because if two secondary spawn at once
     in theory could collide.

 lib/eal/linux/eal_memalloc.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/lib/eal/linux/eal_memalloc.c b/lib/eal/linux/eal_memalloc.c
index 4dee224ac5..dfbedf4626 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"
@@ -1387,7 +1389,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)
@@ -1397,12 +1399,21 @@ 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 */
-       ret = snprintf(name, RTE_FBARRAY_NAME_LEN, "%s_%i",
-               primary_msl->memseg_arr.name, getpid());
-       if (ret >= RTE_FBARRAY_NAME_LEN) {
-               EAL_LOG(ERR, "fbarray name %s_%i is too long",
-                               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
+        */
+       uint64_t tsc = rte_get_tsc_cycles();
+       pid_t pid = getpid();
+       ret = snprintf(name, sizeof(name), "%s_%d_%"PRIx64,
+                      primary_msl->memseg_arr.name, pid, tsc);
+       if (ret >= (int)sizeof(name)) {
+               EAL_LOG(ERR, "fbarray name \"%s_%d_%"PRIx64"\" is too long",
+                       primary_msl->memseg_arr.name, pid, tsc);
                return -1;
        }
 
-- 
2.51.0

Reply via email to