From cfdaa678b3bbff51fe152c18621c751867c70bd2 Mon Sep 17 00:00:00 2001 From: Dmitry Kozlyuk Date: Sun, 2 May 2021 05:33:33 +0300 Subject: [PATCH] eal/windows: cleanup interrupt resources Interrupt manager in Windows EAL allocates on IOCP and starts a control thread that runs indefinitely. At DPDK cleanup this thread was not stopped and IOCP handle was not closed. Gracefully stop interrupt-handling in rte_eal_cleanup(). The thread already closes IOCP handle before exiting. Fixes: 5c016fc0205a ("eal/windows: add interrupt thread skeleton") Cc: stable@dpdk.org Signed-off-by: Dmitry Kozlyuk Acked-by: Ranjit Menon Acked-by: Jie Zhou Tested-by: Jie Zhou --- lib/eal/windows/eal.c | 2 ++ lib/eal/windows/eal_interrupts.c | 26 ++++++++++++++++++++++++-- lib/eal/windows/eal_windows.h | 5 +++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/lib/eal/windows/eal.c b/lib/eal/windows/eal.c index 28c787c0b0..8483f6b02c 100644 --- a/lib/eal/windows/eal.c +++ b/lib/eal/windows/eal.c @@ -258,6 +258,8 @@ rte_eal_cleanup(void) { struct internal_config *internal_conf = eal_get_internal_configuration(); + + eal_intr_thread_cancel(); /* after this point, any DPDK pointers will become dangling */ rte_eal_memory_detach(); eal_cleanup_config(internal_conf); diff --git a/lib/eal/windows/eal_interrupts.c b/lib/eal/windows/eal_interrupts.c index f24ed6e54e..bb0585cb34 100644 --- a/lib/eal/windows/eal_interrupts.c +++ b/lib/eal/windows/eal_interrupts.c @@ -7,6 +7,8 @@ #include "eal_private.h" #include "eal_windows.h" +#define IOCP_KEY_SHUTDOWN UINT32_MAX + static pthread_t intr_thread; static HANDLE intr_iocp; @@ -34,12 +36,14 @@ eal_intr_thread_handle_init(void) static void * eal_intr_thread_main(LPVOID arg __rte_unused) { + bool finished = false; + if (eal_intr_thread_handle_init() < 0) { RTE_LOG(ERR, EAL, "Cannot open interrupt thread handle\n"); goto cleanup; } - while (1) { + while (!finished) { OVERLAPPED_ENTRY events[16]; ULONG event_count, i; BOOL result; @@ -61,8 +65,13 @@ eal_intr_thread_main(LPVOID arg __rte_unused) continue; } - for (i = 0; i < event_count; i++) + for (i = 0; i < event_count; i++) { + if (events[i].lpCompletionKey == IOCP_KEY_SHUTDOWN) { + finished = true; + break; + } eal_intr_process(&events[i]); + } } CloseHandle(intr_thread_handle); @@ -125,6 +134,19 @@ eal_intr_thread_schedule(void (*func)(void *arg), void *arg) return 0; } +void +eal_intr_thread_cancel(void) +{ + if (!PostQueuedCompletionStatus( + intr_iocp, 0, IOCP_KEY_SHUTDOWN, NULL)) { + RTE_LOG_WIN32_ERR("PostQueuedCompletionStatus()"); + RTE_LOG(ERR, EAL, "Cannot cancel interrupt thread\n"); + return; + } + + WaitForSingleObject(intr_thread_handle, INFINITE); +} + int rte_intr_callback_register( __rte_unused const struct rte_intr_handle *intr_handle, diff --git a/lib/eal/windows/eal_windows.h b/lib/eal/windows/eal_windows.h index 478accc1b9..7cc811485d 100644 --- a/lib/eal/windows/eal_windows.h +++ b/lib/eal/windows/eal_windows.h @@ -67,6 +67,11 @@ unsigned int eal_socket_numa_node(unsigned int socket_id); */ int eal_intr_thread_schedule(void (*func)(void *arg), void *arg); +/** + * Request interrupt thread to stop and wait its termination. + */ +void eal_intr_thread_cancel(void); + /** * Open virt2phys driver interface device. * -- 2.20.1