* [RFC 1/6] eal: avoid using pthread_cancel
2025-09-24 16:51 [RFC 0/6] get rid of pthread_cancel Stephen Hemminger
@ 2025-09-24 16:51 ` Stephen Hemminger
2025-09-24 16:51 ` [RFC 2/6] eventdev: avoid use of pthread_cancel Stephen Hemminger
` (4 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Stephen Hemminger @ 2025-09-24 16:51 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Anatoly Burakov, Tyler Retzlaff
The multi-process handling thread can be managed more safely
by closing the underlying socket rather than pthread_cancel.
Closing the socket in the main thread will cause the read()
in the MP handler to unblock.
The use of atomic for updating the socket fd is not needed.
The fd for the socket is set before the thread is created
and not modified again until handler has exited.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/eal/common/eal_common_proc.c | 24 ++++++------------------
1 file changed, 6 insertions(+), 18 deletions(-)
diff --git a/lib/eal/common/eal_common_proc.c b/lib/eal/common/eal_common_proc.c
index 0dea787e38..8e60e815ed 100644
--- a/lib/eal/common/eal_common_proc.c
+++ b/lib/eal/common/eal_common_proc.c
@@ -34,7 +34,7 @@
#include "eal_filesystem.h"
#include "eal_internal_cfg.h"
-static RTE_ATOMIC(int) mp_fd = -1;
+static int mp_fd = -1;
static rte_thread_t mp_handle_tid;
static char mp_filter[PATH_MAX]; /* Filter for secondary process sockets */
static char mp_dir_path[PATH_MAX]; /* The directory path for all mp sockets */
@@ -406,17 +406,9 @@ mp_handle(void *arg __rte_unused)
{
struct mp_msg_internal msg;
struct sockaddr_un sa;
- int fd;
-
- while ((fd = rte_atomic_load_explicit(&mp_fd, rte_memory_order_relaxed)) >= 0) {
- int ret;
-
- ret = read_msg(fd, &msg, &sa);
- if (ret <= 0)
- break;
+ while (read_msg(mp_fd, &msg, &sa) > 0)
process_msg(&msg, &sa);
- }
return 0;
}
@@ -656,7 +648,7 @@ rte_mp_channel_init(void)
EAL_LOG(ERR, "failed to create mp thread: %s",
strerror(errno));
close(dir_fd);
- close(rte_atomic_exchange_explicit(&mp_fd, -1, rte_memory_order_relaxed));
+ close(mp_fd);
return -1;
}
@@ -670,15 +662,11 @@ rte_mp_channel_init(void)
void
rte_mp_channel_cleanup(void)
{
- int fd;
-
- fd = rte_atomic_exchange_explicit(&mp_fd, -1, rte_memory_order_relaxed);
- if (fd < 0)
- return;
+ /* shutdown() will cause recvmsg to unblock */
+ shutdown(mp_fd, SHUT_RDWR);
- pthread_cancel((pthread_t)mp_handle_tid.opaque_id);
rte_thread_join(mp_handle_tid, NULL);
- close_socket_fd(fd);
+ close_socket_fd(mp_fd);
}
/**
--
2.47.3
^ permalink raw reply [flat|nested] 9+ messages in thread
* [RFC 2/6] eventdev: avoid use of pthread_cancel
2025-09-24 16:51 [RFC 0/6] get rid of pthread_cancel Stephen Hemminger
2025-09-24 16:51 ` [RFC 1/6] eal: avoid using pthread_cancel Stephen Hemminger
@ 2025-09-24 16:51 ` Stephen Hemminger
2025-09-24 16:51 ` [RFC 3/6] raw/ifpga: " Stephen Hemminger
` (3 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Stephen Hemminger @ 2025-09-24 16:51 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Naga Harish K S V, Jerin Jacob
To control the rx event thread is simpler and safer to
just close the file descriptor rather than using pthread_cancel().
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/eventdev/rte_event_eth_rx_adapter.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/lib/eventdev/rte_event_eth_rx_adapter.c b/lib/eventdev/rte_event_eth_rx_adapter.c
index 994f256322..95ceb35c5a 100644
--- a/lib/eventdev/rte_event_eth_rx_adapter.c
+++ b/lib/eventdev/rte_event_eth_rx_adapter.c
@@ -1173,9 +1173,11 @@ rxa_intr_thread(void *arg)
while (1) {
n = rte_epoll_wait(rx_adapter->epd, epoll_events,
RTE_EVENT_ETH_INTR_RING_SIZE, -1);
- if (unlikely(n < 0))
- RTE_EDEV_LOG_ERR("rte_epoll_wait returned error %d",
- n);
+ if (unlikely(n < 0)) {
+ RTE_EDEV_LOG_ERR("rte_epoll_wait returned error %d", n);
+ break;
+ }
+
for (i = 0; i < n; i++) {
rxa_intr_ring_enqueue(rx_adapter,
epoll_events[i].epdata.data);
@@ -1643,10 +1645,12 @@ rxa_destroy_intr_thread(struct event_eth_rx_adapter *rx_adapter)
{
int err;
- err = pthread_cancel((pthread_t)rx_adapter->rx_intr_thread.opaque_id);
- if (err)
- RTE_EDEV_LOG_ERR("Can't cancel interrupt thread err = %d",
- err);
+ /*
+ * close the epoll fd used in the interrupt thread
+ * this will unblock the rte_epoll_wait().
+ */
+ close(rx_adapter->epd);
+ rx_adapter->epd = INIT_FD;
err = rte_thread_join(rx_adapter->rx_intr_thread, NULL);
if (err)
@@ -1671,9 +1675,6 @@ rxa_free_intr_resources(struct event_eth_rx_adapter *rx_adapter)
if (ret)
return ret;
- close(rx_adapter->epd);
- rx_adapter->epd = INIT_FD;
-
return ret;
}
--
2.47.3
^ permalink raw reply [flat|nested] 9+ messages in thread
* [RFC 3/6] raw/ifpga: avoid use of pthread_cancel
2025-09-24 16:51 [RFC 0/6] get rid of pthread_cancel Stephen Hemminger
2025-09-24 16:51 ` [RFC 1/6] eal: avoid using pthread_cancel Stephen Hemminger
2025-09-24 16:51 ` [RFC 2/6] eventdev: avoid use of pthread_cancel Stephen Hemminger
@ 2025-09-24 16:51 ` Stephen Hemminger
2025-09-24 16:51 ` [RFC 4/6] dma/skeleton: " Stephen Hemminger
` (2 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Stephen Hemminger @ 2025-09-24 16:51 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Rosen Xu
Use refcnt to do controlled shutdown of control thread
rather than using pthread_cancel().
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
drivers/raw/ifpga/ifpga_rawdev.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c
index 5b9b596435..d61927f193 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.c
+++ b/drivers/raw/ifpga/ifpga_rawdev.c
@@ -573,13 +573,7 @@ ifpga_monitor_stop_func(struct ifpga_rawdev *dev)
dev->poll_enabled = 0;
- if (!(rte_atomic_fetch_sub_explicit(&ifpga_monitor_refcnt, 1,
- rte_memory_order_relaxed) - 1) &&
- ifpga_monitor_start_thread.opaque_id != 0) {
- ret = pthread_cancel((pthread_t)ifpga_monitor_start_thread.opaque_id);
- if (ret)
- IFPGA_RAWDEV_PMD_ERR("Can't cancel the thread");
-
+ if (rte_atomic_fetch_sub_explicit(&ifpga_monitor_refcnt, 1, rte_memory_order_relaxed) == 1) {
ret = rte_thread_join(ifpga_monitor_start_thread, NULL);
if (ret)
IFPGA_RAWDEV_PMD_ERR("Can't join the thread");
--
2.47.3
^ permalink raw reply [flat|nested] 9+ messages in thread
* [RFC 4/6] dma/skeleton: avoid use of pthread_cancel
2025-09-24 16:51 [RFC 0/6] get rid of pthread_cancel Stephen Hemminger
` (2 preceding siblings ...)
2025-09-24 16:51 ` [RFC 3/6] raw/ifpga: " Stephen Hemminger
@ 2025-09-24 16:51 ` Stephen Hemminger
2025-09-25 1:20 ` fengchengwen
2025-09-24 16:51 ` [RFC 5/6] intel/ipn3ke: " Stephen Hemminger
2025-09-24 16:51 ` [RFC 6/6] intel/iavf: remove " Stephen Hemminger
5 siblings, 1 reply; 9+ messages in thread
From: Stephen Hemminger @ 2025-09-24 16:51 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Chengwen Feng, Kevin Laatz, Bruce Richardson
Can use exit_flag to do controlled shutdown of the control thread.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
drivers/dma/skeleton/skeleton_dmadev.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/dma/skeleton/skeleton_dmadev.c b/drivers/dma/skeleton/skeleton_dmadev.c
index e287802eb9..62a25f9d34 100644
--- a/drivers/dma/skeleton/skeleton_dmadev.c
+++ b/drivers/dma/skeleton/skeleton_dmadev.c
@@ -5,8 +5,6 @@
#include <inttypes.h>
#include <stdlib.h>
-#include <pthread.h>
-
#include <bus_vdev_driver.h>
#include <rte_cycles.h>
#include <rte_eal.h>
@@ -215,10 +213,9 @@ skeldma_stop(struct rte_dma_dev *dev)
{
struct skeldma_hw *hw = dev->data->dev_private;
+ /* setting exit flag causes cpuwork_thread to exit polling loop */
hw->exit_flag = true;
- rte_delay_ms(1);
- (void)pthread_cancel((pthread_t)hw->thread.opaque_id);
rte_thread_join(hw->thread, NULL);
return 0;
--
2.47.3
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFC 4/6] dma/skeleton: avoid use of pthread_cancel
2025-09-24 16:51 ` [RFC 4/6] dma/skeleton: " Stephen Hemminger
@ 2025-09-25 1:20 ` fengchengwen
0 siblings, 0 replies; 9+ messages in thread
From: fengchengwen @ 2025-09-25 1:20 UTC (permalink / raw)
To: Stephen Hemminger, dev; +Cc: Kevin Laatz, Bruce Richardson
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
On 9/25/2025 12:51 AM, Stephen Hemminger wrote:
> Can use exit_flag to do controlled shutdown of the control thread.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
> drivers/dma/skeleton/skeleton_dmadev.c | 5 +----
> 1 file changed, 1 insertion(+), 4 deletions(-)
^ permalink raw reply [flat|nested] 9+ messages in thread
* [RFC 5/6] intel/ipn3ke: avoid use of pthread_cancel
2025-09-24 16:51 [RFC 0/6] get rid of pthread_cancel Stephen Hemminger
` (3 preceding siblings ...)
2025-09-24 16:51 ` [RFC 4/6] dma/skeleton: " Stephen Hemminger
@ 2025-09-24 16:51 ` Stephen Hemminger
2025-09-24 16:51 ` [RFC 6/6] intel/iavf: remove " Stephen Hemminger
5 siblings, 0 replies; 9+ messages in thread
From: Stephen Hemminger @ 2025-09-24 16:51 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Rosen Xu
Can use the existing reference count (scan_num) to control
the thread without using pthread_cancel.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
drivers/net/intel/ipn3ke/ipn3ke_representor.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/net/intel/ipn3ke/ipn3ke_representor.c b/drivers/net/intel/ipn3ke/ipn3ke_representor.c
index feb57420c3..4e831c6924 100644
--- a/drivers/net/intel/ipn3ke/ipn3ke_representor.c
+++ b/drivers/net/intel/ipn3ke/ipn3ke_representor.c
@@ -26,7 +26,7 @@
#include "ipn3ke_logs.h"
#include "ipn3ke_ethdev.h"
-static int ipn3ke_rpst_scan_num;
+static volatile int ipn3ke_rpst_scan_num;
static rte_thread_t ipn3ke_rpst_scan_thread;
/** Double linked list of representor port. */
@@ -2578,7 +2578,7 @@ ipn3ke_rpst_scan_handle_request(__rte_unused void *param)
#define MS 1000
#define SCAN_NUM 32
- for (;;) {
+ while (ipn3ke_rpst_scan_num > 0) {
num = 0;
TAILQ_FOREACH(rpst, &ipn3ke_rpst_list, next) {
if (rpst->i40e_pf_eth &&
@@ -2612,10 +2612,6 @@ ipn3ke_rpst_scan_check(void)
return -1;
}
} else if (ipn3ke_rpst_scan_num == 0) {
- ret = pthread_cancel((pthread_t)ipn3ke_rpst_scan_thread.opaque_id);
- if (ret)
- IPN3KE_AFU_PMD_ERR("Can't cancel the thread");
-
ret = rte_thread_join(ipn3ke_rpst_scan_thread, NULL);
if (ret)
IPN3KE_AFU_PMD_ERR("Can't join the thread");
--
2.47.3
^ permalink raw reply [flat|nested] 9+ messages in thread
* [RFC 6/6] intel/iavf: remove use of pthread_cancel
2025-09-24 16:51 [RFC 0/6] get rid of pthread_cancel Stephen Hemminger
` (4 preceding siblings ...)
2025-09-24 16:51 ` [RFC 5/6] intel/ipn3ke: " Stephen Hemminger
@ 2025-09-24 16:51 ` Stephen Hemminger
2025-09-25 15:11 ` Bruce Richardson
5 siblings, 1 reply; 9+ messages in thread
From: Stephen Hemminger @ 2025-09-24 16:51 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Vladimir Medvedkin
The iavf driver uses a pipe to communicate with control thread.
By closing the write side of the pipe, the main thread can
tell the control thread to exit without use of pthread_cancel.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
drivers/net/intel/iavf/iavf_vchnl.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/intel/iavf/iavf_vchnl.c b/drivers/net/intel/iavf/iavf_vchnl.c
index b1b7a5bf94..781bae11be 100644
--- a/drivers/net/intel/iavf/iavf_vchnl.c
+++ b/drivers/net/intel/iavf/iavf_vchnl.c
@@ -161,14 +161,14 @@ iavf_dev_event_handler_fini(void)
if (rte_atomic_fetch_sub_explicit(&handler->ndev, 1, rte_memory_order_relaxed) - 1 != 0)
return;
- int unused = pthread_cancel((pthread_t)handler->tid.opaque_id);
- RTE_SET_USED(unused);
- close(handler->fd[0]);
+ /* closing the write side of the pipe will cause read() to return 0 in thread */
close(handler->fd[1]);
- handler->fd[0] = -1;
handler->fd[1] = -1;
rte_thread_join(handler->tid, NULL);
+ close(handler->fd[0]);
+ handler->fd[0] = -1;
+
pthread_mutex_destroy(&handler->lock);
struct iavf_event_element *pos, *save_next;
--
2.47.3
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [RFC 6/6] intel/iavf: remove use of pthread_cancel
2025-09-24 16:51 ` [RFC 6/6] intel/iavf: remove " Stephen Hemminger
@ 2025-09-25 15:11 ` Bruce Richardson
0 siblings, 0 replies; 9+ messages in thread
From: Bruce Richardson @ 2025-09-25 15:11 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev, Vladimir Medvedkin
On Wed, Sep 24, 2025 at 09:51:13AM -0700, Stephen Hemminger wrote:
> The iavf driver uses a pipe to communicate with control thread.
> By closing the write side of the pipe, the main thread can
> tell the control thread to exit without use of pthread_cancel.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
> drivers/net/intel/iavf/iavf_vchnl.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/intel/iavf/iavf_vchnl.c b/drivers/net/intel/iavf/iavf_vchnl.c
> index b1b7a5bf94..781bae11be 100644
> --- a/drivers/net/intel/iavf/iavf_vchnl.c
> +++ b/drivers/net/intel/iavf/iavf_vchnl.c
> @@ -161,14 +161,14 @@ iavf_dev_event_handler_fini(void)
> if (rte_atomic_fetch_sub_explicit(&handler->ndev, 1, rte_memory_order_relaxed) - 1 != 0)
> return;
>
> - int unused = pthread_cancel((pthread_t)handler->tid.opaque_id);
> - RTE_SET_USED(unused);
> - close(handler->fd[0]);
> + /* closing the write side of the pipe will cause read() to return 0 in thread */
> close(handler->fd[1]);
> - handler->fd[0] = -1;
> handler->fd[1] = -1;
>
> rte_thread_join(handler->tid, NULL);
> + close(handler->fd[0]);
> + handler->fd[0] = -1;
> +
> pthread_mutex_destroy(&handler->lock);
>
> struct iavf_event_element *pos, *save_next;
> --
> 2.47.3
>
^ permalink raw reply [flat|nested] 9+ messages in thread