When primary process exits, it should notify the secondary
processes. This allows for clean shutdown and eliminates need
for MP handling in applications (such as test-pmd).
Bugzilla ID: 1942
Fixes: 85d6815fa6d0 ("eal: close multi-process socket during cleanup")
Cc: [email protected]
Signed-off-by: Stephen Hemminger <[email protected]>
---
lib/eal/common/eal_common_proc.c | 51 ++++++++++++++++++++++++++++++--
1 file changed, 49 insertions(+), 2 deletions(-)
diff --git a/lib/eal/common/eal_common_proc.c b/lib/eal/common/eal_common_proc.c
index 06f151818c..4369892e44 100644
--- a/lib/eal/common/eal_common_proc.c
+++ b/lib/eal/common/eal_common_proc.c
@@ -60,6 +60,15 @@ enum mp_type {
MP_IGN, /* Response telling requester to ignore this response */
};
+/* Message sent from primary EAL to secondary EAL */
+#define EAL_MP "mp_eal"
+struct eal_mp_req {
+ enum {
+ MP_REQ_NOP = 0,
+ MP_REQ_QUIT,
+ } type;
+};
+
struct mp_msg_internal {
int type;
struct rte_mp_msg msg;
@@ -614,6 +623,25 @@ close_socket_fd(int fd)
unlink(path);
}
+/* callback in secondary when primary has exited */
+static int
+mp_primary_exited(const struct rte_mp_msg *msg, const void *peer __rte_unused)
+{
+ const struct eal_mp_req *req;
+
+ if (msg->len_param != sizeof(*req)) {
+ EAL_LOG(ERR, "invalid request from primary");
+ return -EINVAL;
+ }
+
+ req = (const struct eal_mp_req *)msg->param;
+ if (req->type == MP_REQ_QUIT)
+ rte_mp_channel_cleanup();
+
+ /* no reply needed */
+ return 0;
+}
+
int
rte_mp_channel_init(void)
{
@@ -661,6 +689,10 @@ rte_mp_channel_init(void)
return -1;
}
+ /* listen for quit message from primary */
+ if (rte_eal_process_type() == RTE_PROC_SECONDARY)
+ rte_mp_action_register(EAL_MP, mp_primary_exited);
+
if (rte_thread_create_internal_control(&mp_handle_tid, "mp-msg",
mp_handle, NULL) < 0) {
EAL_LOG(ERR, "failed to create mp thread: %s",
@@ -682,12 +714,27 @@ rte_mp_channel_cleanup(void)
{
int fd;
+ /* Primary exiting, tell all secondary processes */
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ struct rte_mp_msg msg = { .name = EAL_MP };
+ struct eal_mp_req req = { .type = MP_REQ_QUIT };
+
+ memcpy(&msg.param, &req, sizeof(req));
+ msg.len_param = sizeof(req);
+
+ rte_mp_sendmsg(&msg);
+ } else {
+ rte_mp_action_unregister(EAL_MP);
+ }
+
fd = rte_atomic_exchange_explicit(&mp_fd, -1, rte_memory_order_relaxed);
if (fd < 0)
return;
- pthread_cancel((pthread_t)mp_handle_tid.opaque_id);
- rte_thread_join(mp_handle_tid, NULL);
+ if (pthread_self() != (pthread_t)mp_handle_tid.opaque_id) {
+ pthread_cancel((pthread_t)mp_handle_tid.opaque_id);
+ rte_thread_join(mp_handle_tid, NULL);
+ }
close_socket_fd(fd);
}
--
2.53.0