[v2,14/14] eal: prevent different primary/secondary process versions
Checks
Commit Message
Currently, nothing stops DPDK to attempt to run primary and
secondary processes while having different versions. This
can lead to all sorts of weird behavior and makes it harder
to maintain compatibility without breaking ABI every once
in a while.
Fix it by explicitly disallowing running different DPDK
versions as primary and secondary processes.
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
lib/librte_eal/common/eal_common_mcfg.c | 15 +++++++++++++++
lib/librte_eal/common/eal_memcfg.h | 6 ++++++
lib/librte_eal/freebsd/eal/eal.c | 14 ++++++++++++--
lib/librte_eal/linux/eal/eal.c | 14 ++++++++++++--
4 files changed, 45 insertions(+), 4 deletions(-)
@@ -4,6 +4,7 @@
#include <rte_config.h>
#include <rte_eal_memconfig.h>
+#include <rte_version.h>
#include "eal_internal_cfg.h"
#include "eal_memcfg.h"
@@ -31,6 +32,18 @@ eal_mcfg_wait_complete(void)
rte_pause();
}
+int
+eal_mcfg_check_version(void)
+{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+
+ /* check if version from memconfig matches compiled in macro */
+ if (mcfg->version != RTE_VERSION)
+ return -1;
+
+ return 0;
+}
+
void
eal_mcfg_update_internal(void)
{
@@ -47,6 +60,8 @@ eal_mcfg_update_from_internal(void)
mcfg->legacy_mem = internal_config.legacy_mem;
mcfg->single_file_segments = internal_config.single_file_segments;
+ /* record current DPDK version */
+ mcfg->version = RTE_VERSION;
}
void
@@ -21,6 +21,8 @@
*/
struct rte_mem_config {
volatile uint32_t magic; /**< Magic number - Sanity check. */
+ uint32_t version;
+ /**< Prevent secondary processes using different DPDK versions. */
/* memory topology */
uint32_t nchannel; /**< Number of channels (0 if unknown). */
@@ -80,6 +82,10 @@ eal_mcfg_update_from_internal(void);
void
eal_mcfg_wait_complete(void);
+/* check if DPDK version of current process matches one stored in the config */
+int
+eal_mcfg_check_version(void);
+
/* set mem config as complete */
void
eal_mcfg_complete(void);
@@ -342,7 +342,7 @@ eal_proc_type_detect(void)
}
/* Sets up rte_config structure with the pointer to shared memory config.*/
-static void
+static int
rte_config_init(void)
{
rte_config.process_type = internal_config.process_type;
@@ -355,6 +355,10 @@ rte_config_init(void)
case RTE_PROC_SECONDARY:
rte_eal_config_attach();
eal_mcfg_wait_complete();
+ if (eal_mcfg_check_version() < 0) {
+ RTE_LOG(ERR, EAL, "Primary and secondary process DPDK version mismatch\n");
+ return -1;
+ }
rte_eal_config_reattach();
eal_mcfg_update_from_internal();
break;
@@ -362,6 +366,7 @@ rte_config_init(void)
case RTE_PROC_INVALID:
rte_panic("Invalid process type\n");
}
+ return 0;
}
/* display usage */
@@ -686,7 +691,12 @@ rte_eal_init(int argc, char **argv)
return -1;
}
- rte_config_init();
+ if (rte_config_init() < 0) {
+ rte_eal_init_alert("Cannot init config");
+ rte_errno = EINVAL;
+ rte_atomic32_clear(&run_once);
+ return -1;
+ }
if (rte_eal_intr_init() < 0) {
rte_eal_init_alert("Cannot init interrupt-handling thread");
@@ -444,7 +444,7 @@ eal_proc_type_detect(void)
}
/* Sets up rte_config structure with the pointer to shared memory config.*/
-static void
+static int
rte_config_init(void)
{
rte_config.process_type = internal_config.process_type;
@@ -457,6 +457,10 @@ rte_config_init(void)
case RTE_PROC_SECONDARY:
rte_eal_config_attach();
eal_mcfg_wait_complete();
+ if (eal_mcfg_check_version() < 0) {
+ RTE_LOG(ERR, EAL, "Primary and secondary process DPDK version mismatch\n");
+ return -1;
+ }
rte_eal_config_reattach();
eal_mcfg_update_internal();
break;
@@ -464,6 +468,7 @@ rte_config_init(void)
case RTE_PROC_INVALID:
rte_panic("Invalid process type\n");
}
+ return 0;
}
/* Unlocks hugepage directories that were locked by eal_hugepage_info_init */
@@ -971,7 +976,12 @@ rte_eal_init(int argc, char **argv)
return -1;
}
- rte_config_init();
+ if (rte_config_init() < 0) {
+ rte_eal_init_alert("Cannot init config");
+ rte_errno = EINVAL;
+ rte_atomic32_clear(&run_once);
+ return -1;
+ }
if (rte_eal_intr_init() < 0) {
rte_eal_init_alert("Cannot init interrupt-handling thread");