In secondary processes, accessing device after primary has exited will cause crash.
This patch adds a mechanism in testpmd to monitor the primary process from the secondary process. When primary process exits it forces secondary to exit avoiding issues from cleanup logic. Fixes: a550baf24af9 ('app/testpmd: support multi-process') Cc: sta...@dpdk.org Signed-off-by: Khadem Ullah <14pwcse1...@uetpeshawar.edu.pk> Signed-off-by: Stephen Hemminger <step...@networkplumber.org> --- app/test-pmd/testpmd.c | 47 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index bb88555328..b7affa6da9 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -101,13 +101,15 @@ uint16_t verbose_level = 0; /**< Silent by default. */ int testpmd_logtype; /**< Log type for testpmd logs */ +/* Maximum delay for exiting after primary process. */ +#define MONITOR_INTERVAL (500 * 1000) + /* use main core for command line ? */ uint8_t interactive = 0; uint8_t auto_start = 0; uint8_t tx_first; char cmdline_filename[PATH_MAX] = {0}; bool echo_cmdline_file; - /* * NUMA support configuration. * When set, the NUMA support attempts to dispatch the allocation of the @@ -4332,6 +4334,38 @@ signal_handler(int signum __rte_unused) prompt_exit(); } +#ifndef RTE_EXEC_ENV_WINDOWS +/* Alarm signal handler, used to check that primary process */ +static void +monitor_primary(void *arg __rte_unused) +{ + if (rte_eal_primary_proc_alive(NULL)) { + rte_eal_alarm_set(MONITOR_INTERVAL, monitor_primary, NULL); + } else { + /* + * If primary process exits, then all the device information + * is no longer valid. Calling any cleanup code is going to + * run into use after free. + */ + fprintf(stderr, "\nPrimary process is no longer active, exiting...\n"); + exit(EXIT_FAILURE); + } +} + +/* Setup handler to check when primary exits. */ +static int +enable_primary_monitor(void) +{ + return rte_eal_alarm_set(MONITOR_INTERVAL, monitor_primary, NULL); +} + +static void +disable_primary_monitor(void) +{ + rte_eal_alarm_cancel(monitor_primary, NULL); +} +#endif + int main(int argc, char** argv) { @@ -4363,6 +4397,12 @@ main(int argc, char** argv) rte_exit(EXIT_FAILURE, "Cannot init EAL: %s\n", rte_strerror(rte_errno)); +#ifndef RTE_EXEC_ENV_WINDOWS + if (rte_eal_process_type() == RTE_PROC_SECONDARY && + enable_primary_monitor() < 0) + rte_exit(EXIT_FAILURE, "Cannot setup primary monitor"); +#endif + /* allocate port structures, and init them */ init_port(); @@ -4556,6 +4596,11 @@ main(int argc, char** argv) } } +#ifndef RTE_EXEC_ENV_WINDOWS + if (rte_eal_process_type() == RTE_PROC_SECONDARY) + disable_primary_monitor(); +#endif + pmd_test_exit(); #ifdef RTE_LIB_PDUMP -- 2.43.0