From 3888f31950c8f7554d74925a7eca1557c7685fc3 Mon Sep 17 00:00:00 2001 From: Dmitry Kozlyuk Date: Sun, 2 May 2021 05:33:32 +0300 Subject: [PATCH] eal/windows: fix interrupt thread handle leakage Each time a work was scheduled in the interrupt thread, usually an alarm, a handle was opened but not closed. Opening a handle is a system call, which harms alarm precision. Instead of opening and closing a handle each time, open it when interrupt thread starts and close it when the thread finishes. Fixes: 5c016fc0205a ("eal/windows: add interrupt thread skeleton") Cc: stable@dpdk.org Signed-off-by: Dmitry Kozlyuk Tested-by: Pallavi Kadam --- lib/eal/windows/eal_interrupts.c | 34 +++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/lib/eal/windows/eal_interrupts.c b/lib/eal/windows/eal_interrupts.c index 9cde02b003..f24ed6e54e 100644 --- a/lib/eal/windows/eal_interrupts.c +++ b/lib/eal/windows/eal_interrupts.c @@ -10,6 +10,7 @@ static pthread_t intr_thread; static HANDLE intr_iocp; +static HANDLE intr_thread_handle; static void eal_intr_process(const OVERLAPPED_ENTRY *event) @@ -17,9 +18,27 @@ eal_intr_process(const OVERLAPPED_ENTRY *event) RTE_SET_USED(event); } +static int +eal_intr_thread_handle_init(void) +{ + DWORD thread_id = GetCurrentThreadId(); + + intr_thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, thread_id); + if (intr_thread_handle == NULL) { + RTE_LOG_WIN32_ERR("OpenThread(%lu)", thread_id); + return -1; + } + return 0; +} + static void * eal_intr_thread_main(LPVOID arg __rte_unused) { + if (eal_intr_thread_handle_init() < 0) { + RTE_LOG(ERR, EAL, "Cannot open interrupt thread handle\n"); + goto cleanup; + } + while (1) { OVERLAPPED_ENTRY events[16]; ULONG event_count, i; @@ -46,6 +65,10 @@ eal_intr_thread_main(LPVOID arg __rte_unused) eal_intr_process(&events[i]); } + CloseHandle(intr_thread_handle); + intr_thread_handle = NULL; + +cleanup: intr_thread = 0; CloseHandle(intr_iocp); @@ -93,15 +116,8 @@ rte_intr_rx_ctl(__rte_unused struct rte_intr_handle *intr_handle, int eal_intr_thread_schedule(void (*func)(void *arg), void *arg) { - HANDLE handle; - - handle = OpenThread(THREAD_ALL_ACCESS, FALSE, intr_thread); - if (handle == NULL) { - RTE_LOG_WIN32_ERR("OpenThread(%llu)", intr_thread); - return -ENOENT; - } - - if (!QueueUserAPC((PAPCFUNC)(ULONG_PTR)func, handle, (ULONG_PTR)arg)) { + if (!QueueUserAPC((PAPCFUNC)(ULONG_PTR)func, + intr_thread_handle, (ULONG_PTR)arg)) { RTE_LOG_WIN32_ERR("QueueUserAPC()"); return -EINVAL; } -- 2.20.1