From 2786ccb086d7f8c42f39d0ef048631c9c8ce66c7 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Thu, 3 Aug 2023 16:02:10 +0200 Subject: [PATCH] dpdk/mlx5: fix shutdown crash in IPS mode Make sure to first close all ports before freeing device mempools. Thread 1 "Suricata-Main" received signal SIGSEGV, Segmentation fault. 0x00007ffff456a3fb in ?? () from /usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/librte_pmd_mlx5.so (gdb) bt #0 0x00007ffff456a3fb in ?? () from /usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/librte_pmd_mlx5.so #1 0x00007ffff469a948 in ?? () from /usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/librte_pmd_mlx5.so #2 0x00007ffff45606aa in ?? () from /usr/lib/x86_64-linux-gnu/dpdk/pmds-20.0/librte_pmd_mlx5.so #3 0x00007ffff6d4ed8d in rte_eth_dev_close () from /usr/lib/x86_64-linux-gnu/librte_ethdev.so.20.0 #4 0x000000000055fc4c in DPDKCloseDevice (ldev=ldev@entry=0xe3a400) at util-dpdk.c:53 #5 0x000000000055f4eb in LiveDeviceListClean () at util-device.c:331 #6 0x00000000005511c8 in GlobalsDestroy (suri=) at suricata.c:381 #7 0x0000000000550a76 in SuricataMain (argc=, argv=) at suricata.c:3059 #8 0x00007ffff6a24083 in __libc_start_main (main=0x54cca0
, argc=8, argv=0x7fffffffe4c8, init=, fini=, rtld_fini=, stack_end=0x7fffffffe4b8) at ../csu/libc-start.c:308 #9 0x000000000054cbde in _start () Bug: #5619. --- src/util-device.c | 6 +++++- src/util-dpdk.c | 13 ++++++++++--- src/util-dpdk.h | 1 + 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/util-device.c b/src/util-device.c index cc38bbd76fe3..b624cf07342b 100644 --- a/src/util-device.c +++ b/src/util-device.c @@ -316,6 +316,10 @@ int LiveDeviceListClean(void) SCEnter(); LiveDevice *pd, *tpd; + /* dpdk: need to close all devices before freeing them. */ + TAILQ_FOREACH (pd, &live_devices, next) { + DPDKCloseDevice(pd); + } TAILQ_FOREACH_SAFE(pd, &live_devices, next, tpd) { if (live_devices_stats) { SCLogNotice("%s: packets: %" PRIu64 ", drops: %" PRIu64 @@ -328,7 +332,7 @@ int LiveDeviceListClean(void) } RestoreIfaceOffloading(pd); - DPDKCloseDevice(pd); + DPDKFreeDevice(pd); if (pd->dev) SCFree(pd->dev); diff --git a/src/util-dpdk.c b/src/util-dpdk.c index 462b4b8cb7d1..c9c1d73d0314 100644 --- a/src/util-dpdk.c +++ b/src/util-dpdk.c @@ -40,10 +40,9 @@ void DPDKCloseDevice(LiveDevice *ldev) { (void)ldev; // avoid warnings of unused variable #ifdef HAVE_DPDK - uint16_t port_id; - int retval; if (run_mode == RUNMODE_DPDK) { - retval = rte_eth_dev_get_port_by_name(ldev->dev, &port_id); + uint16_t port_id; + int retval = rte_eth_dev_get_port_by_name(ldev->dev, &port_id); if (retval < 0) { SCLogError("%s: failed get port id, error: %s", ldev->dev, rte_strerror(-retval)); return; @@ -51,7 +50,15 @@ void DPDKCloseDevice(LiveDevice *ldev) SCLogPerf("%s: closing device", ldev->dev); rte_eth_dev_close(port_id); + } +#endif +} +void DPDKFreeDevice(LiveDevice *ldev) +{ + (void)ldev; // avoid warnings of unused variable +#ifdef HAVE_DPDK + if (run_mode == RUNMODE_DPDK) { SCLogDebug("%s: releasing packet mempool", ldev->dev); rte_mempool_free(ldev->dpdk_vars.pkt_mp); } diff --git a/src/util-dpdk.h b/src/util-dpdk.h index f6a54a8323e4..1fb3532f5d4d 100644 --- a/src/util-dpdk.h +++ b/src/util-dpdk.h @@ -120,6 +120,7 @@ void DPDKCleanupEAL(void); void DPDKCloseDevice(LiveDevice *ldev); +void DPDKFreeDevice(LiveDevice *ldev); #ifdef HAVE_DPDK const char *DPDKGetPortNameByPortID(uint16_t pid);