[v4] eal/windows: fix thread handle
Checks
Commit Message
Casting thread ID to handle is not accurate way to get thread handle.
Need to use OpenThread function to get thread handle from thread ID.
pthread_setaffinity_np and pthread_getaffinity_np functions
for Windows are affected because of it.
Signed-off-by: Tasnim Bashar <tbashar@mellanox.com>
---
v3: WA to remove warning(-Wmaybe-uninitialized)
v4: Directly used function name instead of #define
---
lib/librte_eal/windows/include/pthread.h | 84 +++++++++++++++-----
lib/librte_eal/windows/include/rte_windows.h | 1 +
2 files changed, 67 insertions(+), 18 deletions(-)
Comments
Hi, Tasnim...
On 6/24/2020 4:10 PM, Tasnim Bashar wrote:
> Casting thread ID to handle is not accurate way to get thread handle.
> Need to use OpenThread function to get thread handle from thread ID.
>
> pthread_setaffinity_np and pthread_getaffinity_np functions
> for Windows are affected because of it.
>
> Signed-off-by: Tasnim Bashar <tbashar@mellanox.com>
> ---
> v3: WA to remove warning(-Wmaybe-uninitialized)
> v4: Directly used function name instead of #define
> ---
> lib/librte_eal/windows/include/pthread.h | 84 +++++++++++++++-----
> lib/librte_eal/windows/include/rte_windows.h | 1 +
> 2 files changed, 67 insertions(+), 18 deletions(-)
>
> diff --git a/lib/librte_eal/windows/include/pthread.h b/lib/librte_eal/windows/include/pthread.h
> index e2274cf4e9..2553c0890a 100644
> --- a/lib/librte_eal/windows/include/pthread.h
> +++ b/lib/librte_eal/windows/include/pthread.h
> @@ -6,6 +6,7 @@
> #define _PTHREAD_H_
>
> #include <stdint.h>
> +#include <sched.h>
>
> /**
> * This file is required to support the common code in eal_common_proc.c,
> @@ -16,8 +17,8 @@
> extern "C" {
> #endif
>
> -#include <windows.h>
> #include <rte_common.h>
> +#include <rte_windows.h>
>
> #define PTHREAD_BARRIER_SERIAL_THREAD TRUE
>
> @@ -40,37 +41,84 @@ typedef SYNCHRONIZATION_BARRIER pthread_barrier_t;
> /* pthread function overrides */
> #define pthread_self() \
> ((pthread_t)GetCurrentThreadId())
> -#define pthread_setaffinity_np(thread, size, cpuset) \
> - eal_set_thread_affinity_mask(thread, (unsigned long *) cpuset)
> -#define pthread_getaffinity_np(thread, size, cpuset) \
> - eal_get_thread_affinity_mask(thread, (unsigned long *) cpuset)
> -#define pthread_create(threadid, threadattr, threadfunc, args) \
> - eal_create_thread(threadid, threadattr, threadfunc, args)
>
> static inline int
> -eal_set_thread_affinity_mask(pthread_t threadid, unsigned long *cpuset)
> +pthread_setaffinity_np(pthread_t threadid, size_t cpuset_size,
> + rte_cpuset_t *cpuset)
> {
> - SetThreadAffinityMask((HANDLE) threadid, *cpuset);
> - return 0;
> + DWORD_PTR ret;
> + HANDLE thread_handle;
> +
> + if (cpuset == NULL || cpuset_size == 0)
> + return -1;
> +
> + thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, threadid);
> + if (thread_handle == NULL) {
> + RTE_LOG_WIN32_ERR("OpenThread()");
> + return -1;
> + }
> +
> + ret = SetThreadAffinityMask(thread_handle, *cpuset->_bits);
> + if (ret == 0) {
> + RTE_LOG_WIN32_ERR("SetThreadAffinityMask()");
> + goto close_handle;
> + }
> +
> +close_handle:
> + if (CloseHandle(thread_handle) == 0) {
> + RTE_LOG_WIN32_ERR("CloseHandle()");
> + return -1;
> + }
> + return (ret == 0) ? -1 : 0;
> }
>
> static inline int
> -eal_get_thread_affinity_mask(pthread_t threadid, unsigned long *cpuset)
> +pthread_getaffinity_np(pthread_t threadid, size_t cpuset_size,
> + rte_cpuset_t *cpuset)
> {
> /* Workaround for the lack of a GetThreadAffinityMask()
> *API in Windows
> */
> - /* obtain previous mask by setting dummy mask */
> - DWORD dwprevaffinitymask =
> - SetThreadAffinityMask((HANDLE) threadid, 0x1);
> + DWORD_PTR prev_affinity_mask;
> + HANDLE thread_handle;
> + DWORD_PTR ret;
Initialize ret to 0 here, otherwise... (see below)
> +
> + if (cpuset == NULL || cpuset_size == 0)
> + return -1;
> +
> + thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, threadid);
> + if (thread_handle == NULL) {
> + RTE_LOG_WIN32_ERR("OpenThread()");
> + return -1;
> + }
> +
> + /* obtain previous mask by setting dummy mask */
> + prev_affinity_mask = SetThreadAffinityMask(thread_handle, 0x1);
> + if (prev_affinity_mask == 0) {
> + RTE_LOG_WIN32_ERR("SetThreadAffinityMask()");
> + goto close_handle;
...after this jump, ret is uninitialized and will produce random results
at the check at the end of the function.
> + }
> +
> /* set it back! */
> - SetThreadAffinityMask((HANDLE) threadid, dwprevaffinitymask);
> - *cpuset = dwprevaffinitymask;
> - return 0;
> + ret = SetThreadAffinityMask(thread_handle, prev_affinity_mask);
> + if (ret == 0) {
> + RTE_LOG_WIN32_ERR("SetThreadAffinityMask()");
> + goto close_handle;
> + }
> +
> + memset(cpuset, 0, cpuset_size);
> + *cpuset->_bits = prev_affinity_mask;
> +
> +close_handle:
> + if (CloseHandle(thread_handle) == 0) {
> + RTE_LOG_WIN32_ERR("SetThreadAffinityMask()");
> + return -1;
> + }
> + return (ret == 0) ? -1 : 0;
> }
>
> static inline int
> -eal_create_thread(void *threadid, const void *threadattr, void *threadfunc,
> +pthread_create(void *threadid, const void *threadattr, void *threadfunc,
> void *args)
> {
> RTE_SET_USED(threadattr);
> diff --git a/lib/librte_eal/windows/include/rte_windows.h b/lib/librte_eal/windows/include/rte_windows.h
> index 899ed7d874..d013b50241 100644
> --- a/lib/librte_eal/windows/include/rte_windows.h
> +++ b/lib/librte_eal/windows/include/rte_windows.h
> @@ -31,6 +31,7 @@
> #define INITGUID
> #endif
> #include <initguid.h>
> +#include <rte_log.h>
>
> /**
> * Log GetLastError() with context, usually a Win32 API function and arguments.
ranjit m.
> From: Ranjit Menon <ranjit.menon@intel.com>
> Sent: Wednesday, June 24, 2020 5:39 PM
> To: Tasnim Bashar <tbashar@mellanox.com>; dev@dpdk.org
> Cc: harini.ramakrishnan@microsoft.com; pallavi.kadam@intel.com;
> ocardona@microsoft.com; navasile@linux.microsoft.com;
> dmitry.kozliuk@gmail.com; Tal Shnaiderman <talshn@mellanox.com>; Fady
> Bader <fady@mellanox.com>; Ophir Munk <ophirmu@mellanox.com>; Thomas
> Monjalon <thomas@monjalon.net>
> Subject: Re: [PATCH v4] eal/windows: fix thread handle
>
> Hi, Tasnim...
>
> On 6/24/2020 4:10 PM, Tasnim Bashar wrote:
> > Casting thread ID to handle is not accurate way to get thread handle.
> > Need to use OpenThread function to get thread handle from thread ID.
> >
> > pthread_setaffinity_np and pthread_getaffinity_np functions for
> > Windows are affected because of it.
> >
> > Signed-off-by: Tasnim Bashar <tbashar@mellanox.com>
> > ---
> > v3: WA to remove warning(-Wmaybe-uninitialized)
> > v4: Directly used function name instead of #define
> > ---
> > lib/librte_eal/windows/include/pthread.h | 84 +++++++++++++++-----
> > lib/librte_eal/windows/include/rte_windows.h | 1 +
> > 2 files changed, 67 insertions(+), 18 deletions(-)
> >
> > diff --git a/lib/librte_eal/windows/include/pthread.h
> > b/lib/librte_eal/windows/include/pthread.h
> > index e2274cf4e9..2553c0890a 100644
> > --- a/lib/librte_eal/windows/include/pthread.h
> > +++ b/lib/librte_eal/windows/include/pthread.h
> > @@ -6,6 +6,7 @@
> > #define _PTHREAD_H_
> >
> > #include <stdint.h>
> > +#include <sched.h>
> >
> > /**
> > * This file is required to support the common code in
> > eal_common_proc.c, @@ -16,8 +17,8 @@
> > extern "C" {
> > #endif
> >
> > -#include <windows.h>
> > #include <rte_common.h>
> > +#include <rte_windows.h>
> >
> > #define PTHREAD_BARRIER_SERIAL_THREAD TRUE
> >
> > @@ -40,37 +41,84 @@ typedef SYNCHRONIZATION_BARRIER
> pthread_barrier_t;
> > /* pthread function overrides */
> > #define pthread_self() \
> > ((pthread_t)GetCurrentThreadId())
> > -#define pthread_setaffinity_np(thread, size, cpuset) \
> > - eal_set_thread_affinity_mask(thread, (unsigned long *) cpuset)
> > -#define pthread_getaffinity_np(thread, size, cpuset) \
> > - eal_get_thread_affinity_mask(thread, (unsigned long *) cpuset)
> > -#define pthread_create(threadid, threadattr, threadfunc, args) \
> > - eal_create_thread(threadid, threadattr, threadfunc, args)
> >
> > static inline int
> > -eal_set_thread_affinity_mask(pthread_t threadid, unsigned long
> > *cpuset)
> > +pthread_setaffinity_np(pthread_t threadid, size_t cpuset_size,
> > + rte_cpuset_t *cpuset)
> > {
> > - SetThreadAffinityMask((HANDLE) threadid, *cpuset);
> > - return 0;
> > + DWORD_PTR ret;
> > + HANDLE thread_handle;
> > +
> > + if (cpuset == NULL || cpuset_size == 0)
> > + return -1;
> > +
> > + thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, threadid);
> > + if (thread_handle == NULL) {
> > + RTE_LOG_WIN32_ERR("OpenThread()");
> > + return -1;
> > + }
> > +
> > + ret = SetThreadAffinityMask(thread_handle, *cpuset->_bits);
> > + if (ret == 0) {
> > + RTE_LOG_WIN32_ERR("SetThreadAffinityMask()");
> > + goto close_handle;
> > + }
> > +
> > +close_handle:
> > + if (CloseHandle(thread_handle) == 0) {
> > + RTE_LOG_WIN32_ERR("CloseHandle()");
> > + return -1;
> > + }
> > + return (ret == 0) ? -1 : 0;
> > }
> >
> > static inline int
> > -eal_get_thread_affinity_mask(pthread_t threadid, unsigned long
> > *cpuset)
> > +pthread_getaffinity_np(pthread_t threadid, size_t cpuset_size,
> > + rte_cpuset_t *cpuset)
> > {
> > /* Workaround for the lack of a GetThreadAffinityMask()
> > *API in Windows
> > */
> > - /* obtain previous mask by setting dummy mask */
> > - DWORD dwprevaffinitymask =
> > - SetThreadAffinityMask((HANDLE) threadid, 0x1);
> > + DWORD_PTR prev_affinity_mask;
> > + HANDLE thread_handle;
> > + DWORD_PTR ret;
> Initialize ret to 0 here, otherwise... (see below)
> > +
> > + if (cpuset == NULL || cpuset_size == 0)
> > + return -1;
> > +
> > + thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, threadid);
> > + if (thread_handle == NULL) {
> > + RTE_LOG_WIN32_ERR("OpenThread()");
> > + return -1;
> > + }
> > +
> > + /* obtain previous mask by setting dummy mask */
> > + prev_affinity_mask = SetThreadAffinityMask(thread_handle, 0x1);
> > + if (prev_affinity_mask == 0) {
> > + RTE_LOG_WIN32_ERR("SetThreadAffinityMask()");
> > + goto close_handle;
> ...after this jump, ret is uninitialized and will produce random results at the check
> at the end of the function.
Good observation Ranjit. I will send new patch with the fix.
> > + }
> > +
> > /* set it back! */
> > - SetThreadAffinityMask((HANDLE) threadid, dwprevaffinitymask);
> > - *cpuset = dwprevaffinitymask;
> > - return 0;
> > + ret = SetThreadAffinityMask(thread_handle, prev_affinity_mask);
> > + if (ret == 0) {
> > + RTE_LOG_WIN32_ERR("SetThreadAffinityMask()");
> > + goto close_handle;
> > + }
> > +
> > + memset(cpuset, 0, cpuset_size);
> > + *cpuset->_bits = prev_affinity_mask;
> > +
> > +close_handle:
> > + if (CloseHandle(thread_handle) == 0) {
> > + RTE_LOG_WIN32_ERR("SetThreadAffinityMask()");
> > + return -1;
> > + }
> > + return (ret == 0) ? -1 : 0;
> > }
> >
> > static inline int
> > -eal_create_thread(void *threadid, const void *threadattr, void
> > *threadfunc,
> > +pthread_create(void *threadid, const void *threadattr, void
> > +*threadfunc,
> > void *args)
> > {
> > RTE_SET_USED(threadattr);
> > diff --git a/lib/librte_eal/windows/include/rte_windows.h
> > b/lib/librte_eal/windows/include/rte_windows.h
> > index 899ed7d874..d013b50241 100644
> > --- a/lib/librte_eal/windows/include/rte_windows.h
> > +++ b/lib/librte_eal/windows/include/rte_windows.h
> > @@ -31,6 +31,7 @@
> > #define INITGUID
> > #endif
> > #include <initguid.h>
> > +#include <rte_log.h>
> >
> > /**
> > * Log GetLastError() with context, usually a Win32 API function and
> arguments.
>
>
> ranjit m.
@@ -6,6 +6,7 @@
#define _PTHREAD_H_
#include <stdint.h>
+#include <sched.h>
/**
* This file is required to support the common code in eal_common_proc.c,
@@ -16,8 +17,8 @@
extern "C" {
#endif
-#include <windows.h>
#include <rte_common.h>
+#include <rte_windows.h>
#define PTHREAD_BARRIER_SERIAL_THREAD TRUE
@@ -40,37 +41,84 @@ typedef SYNCHRONIZATION_BARRIER pthread_barrier_t;
/* pthread function overrides */
#define pthread_self() \
((pthread_t)GetCurrentThreadId())
-#define pthread_setaffinity_np(thread, size, cpuset) \
- eal_set_thread_affinity_mask(thread, (unsigned long *) cpuset)
-#define pthread_getaffinity_np(thread, size, cpuset) \
- eal_get_thread_affinity_mask(thread, (unsigned long *) cpuset)
-#define pthread_create(threadid, threadattr, threadfunc, args) \
- eal_create_thread(threadid, threadattr, threadfunc, args)
static inline int
-eal_set_thread_affinity_mask(pthread_t threadid, unsigned long *cpuset)
+pthread_setaffinity_np(pthread_t threadid, size_t cpuset_size,
+ rte_cpuset_t *cpuset)
{
- SetThreadAffinityMask((HANDLE) threadid, *cpuset);
- return 0;
+ DWORD_PTR ret;
+ HANDLE thread_handle;
+
+ if (cpuset == NULL || cpuset_size == 0)
+ return -1;
+
+ thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, threadid);
+ if (thread_handle == NULL) {
+ RTE_LOG_WIN32_ERR("OpenThread()");
+ return -1;
+ }
+
+ ret = SetThreadAffinityMask(thread_handle, *cpuset->_bits);
+ if (ret == 0) {
+ RTE_LOG_WIN32_ERR("SetThreadAffinityMask()");
+ goto close_handle;
+ }
+
+close_handle:
+ if (CloseHandle(thread_handle) == 0) {
+ RTE_LOG_WIN32_ERR("CloseHandle()");
+ return -1;
+ }
+ return (ret == 0) ? -1 : 0;
}
static inline int
-eal_get_thread_affinity_mask(pthread_t threadid, unsigned long *cpuset)
+pthread_getaffinity_np(pthread_t threadid, size_t cpuset_size,
+ rte_cpuset_t *cpuset)
{
/* Workaround for the lack of a GetThreadAffinityMask()
*API in Windows
*/
- /* obtain previous mask by setting dummy mask */
- DWORD dwprevaffinitymask =
- SetThreadAffinityMask((HANDLE) threadid, 0x1);
+ DWORD_PTR prev_affinity_mask;
+ HANDLE thread_handle;
+ DWORD_PTR ret;
+
+ if (cpuset == NULL || cpuset_size == 0)
+ return -1;
+
+ thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, threadid);
+ if (thread_handle == NULL) {
+ RTE_LOG_WIN32_ERR("OpenThread()");
+ return -1;
+ }
+
+ /* obtain previous mask by setting dummy mask */
+ prev_affinity_mask = SetThreadAffinityMask(thread_handle, 0x1);
+ if (prev_affinity_mask == 0) {
+ RTE_LOG_WIN32_ERR("SetThreadAffinityMask()");
+ goto close_handle;
+ }
+
/* set it back! */
- SetThreadAffinityMask((HANDLE) threadid, dwprevaffinitymask);
- *cpuset = dwprevaffinitymask;
- return 0;
+ ret = SetThreadAffinityMask(thread_handle, prev_affinity_mask);
+ if (ret == 0) {
+ RTE_LOG_WIN32_ERR("SetThreadAffinityMask()");
+ goto close_handle;
+ }
+
+ memset(cpuset, 0, cpuset_size);
+ *cpuset->_bits = prev_affinity_mask;
+
+close_handle:
+ if (CloseHandle(thread_handle) == 0) {
+ RTE_LOG_WIN32_ERR("SetThreadAffinityMask()");
+ return -1;
+ }
+ return (ret == 0) ? -1 : 0;
}
static inline int
-eal_create_thread(void *threadid, const void *threadattr, void *threadfunc,
+pthread_create(void *threadid, const void *threadattr, void *threadfunc,
void *args)
{
RTE_SET_USED(threadattr);
@@ -31,6 +31,7 @@
#define INITGUID
#endif
#include <initguid.h>
+#include <rte_log.h>
/**
* Log GetLastError() with context, usually a Win32 API function and arguments.