Skip to content

Commit 9784db2

Browse files
Khadem1bluca
authored andcommitted
app/testpmd: stop forwarding in secondary process
[ upstream commit f96273c ] When the secondary process testpmd application running any fwd_engine and after that primary has exited will cause a crash. This patch forces secondary process forwarding lcores in fwd_engine to stop before the primary process exits. Fixes: a550baf ("app/testpmd: support multi-process") Signed-off-by: Khadem Ullah <[email protected]> Signed-off-by: Stephen Hemminger <[email protected]>
1 parent 42105cc commit 9784db2

File tree

1 file changed

+99
-4
lines changed

1 file changed

+99
-4
lines changed

app/test-pmd/testpmd.c

Lines changed: 99 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3708,6 +3708,83 @@ detach_devargs(char *identifier)
37083708
rte_devargs_reset(&da);
37093709
}
37103710

3711+
#ifndef RTE_EXEC_ENV_WINDOWS
3712+
3713+
enum testpmd_req_type {
3714+
TESTPMD_REQ_TYPE_EXIT,
3715+
};
3716+
3717+
struct testpmd_mp_req {
3718+
enum testpmd_req_type t;
3719+
};
3720+
3721+
struct testpmd_mp_resp {
3722+
int result;
3723+
};
3724+
3725+
#define TESTPMD_MP "mp_testpmd"
3726+
3727+
/* Send reply to this peer when testpmd exits */
3728+
static const char *primary_name;
3729+
3730+
static void
3731+
reply_to_primary(const char *peer, int result)
3732+
{
3733+
struct rte_mp_msg reply = { };
3734+
struct testpmd_mp_resp *resp = (struct testpmd_mp_resp *) &reply.param;
3735+
3736+
strlcpy(reply.name, TESTPMD_MP, RTE_MP_MAX_NAME_LEN);
3737+
reply.len_param = sizeof(*resp);
3738+
resp->result = result;
3739+
3740+
printf("Replying %d to primary\n", result);
3741+
fflush(stdout);
3742+
3743+
if (rte_mp_reply(&reply, peer) < 0)
3744+
printf("Failed to send response to primary:%s", strerror(rte_errno));
3745+
}
3746+
3747+
/* Primary process is exiting, stop secondary process */
3748+
static void
3749+
pmd_notify_secondary(void)
3750+
{
3751+
struct testpmd_mp_req request = {
3752+
.t = TESTPMD_REQ_TYPE_EXIT,
3753+
};
3754+
struct rte_mp_msg mp_req = {
3755+
.name = TESTPMD_MP,
3756+
.len_param = sizeof(request),
3757+
};
3758+
struct rte_mp_reply reply;
3759+
struct timespec ts = {.tv_sec = 5, .tv_nsec = 0};
3760+
3761+
printf("\nPrimary: Sending 'stop_req' request to secondary...\n");
3762+
fflush(stdout);
3763+
3764+
memcpy(mp_req.param, &request, sizeof(request));
3765+
rte_mp_request_sync(&mp_req, &reply, &ts);
3766+
}
3767+
3768+
static int
3769+
handle_testpmd_request(const struct rte_mp_msg *request, const void *peer)
3770+
{
3771+
const struct testpmd_mp_req *req = (const struct testpmd_mp_req *)request->param;
3772+
3773+
if (req->t == TESTPMD_REQ_TYPE_EXIT) {
3774+
printf("\nReceived notification of primary exiting\n");
3775+
fflush(stdout);
3776+
3777+
/* Response is sent after forwarding loop exits */
3778+
primary_name = peer;
3779+
3780+
kill(getpid(), SIGINT);
3781+
} else {
3782+
reply_to_primary(peer, -EINVAL);
3783+
}
3784+
return 0;
3785+
}
3786+
#endif
3787+
37113788
void
37123789
pmd_test_exit(void)
37133790
{
@@ -3719,6 +3796,10 @@ pmd_test_exit(void)
37193796
stop_packet_forwarding();
37203797

37213798
#ifndef RTE_EXEC_ENV_WINDOWS
3799+
/* Tell secondary to exit */
3800+
if (rte_eal_process_type() == RTE_PROC_PRIMARY)
3801+
pmd_notify_secondary();
3802+
37223803
for (i = 0 ; i < RTE_DIM(mempools) ; i++) {
37233804
if (mempools[i]) {
37243805
if (mp_alloc_type == MP_ALLOC_ANON)
@@ -4497,9 +4578,12 @@ main(int argc, char** argv)
44974578
rte_strerror(rte_errno));
44984579

44994580
#ifndef RTE_EXEC_ENV_WINDOWS
4500-
if (rte_eal_process_type() == RTE_PROC_SECONDARY &&
4501-
enable_primary_monitor() < 0)
4502-
rte_exit(EXIT_FAILURE, "Cannot setup primary monitor");
4581+
if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
4582+
if (enable_primary_monitor() < 0)
4583+
rte_exit(EXIT_FAILURE, "Cannot setup primary monitor");
4584+
if (rte_mp_action_register(TESTPMD_MP, handle_testpmd_request) < 0)
4585+
rte_exit(EXIT_FAILURE, "Failed to register message action\n");
4586+
}
45034587
#endif
45044588

45054589
/* allocate port structures, and init them */
@@ -4700,12 +4784,23 @@ main(int argc, char** argv)
47004784
}
47014785

47024786
#ifndef RTE_EXEC_ENV_WINDOWS
4703-
if (rte_eal_process_type() == RTE_PROC_SECONDARY)
4787+
if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
47044788
disable_primary_monitor();
4789+
rte_mp_action_unregister(TESTPMD_MP);
4790+
}
47054791
#endif
47064792

47074793
pmd_test_exit();
47084794

4795+
#ifndef RTE_EXEC_ENV_WINDOWS
4796+
if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
4797+
const char *peer = primary_name;
4798+
primary_name = NULL;
4799+
if (peer)
4800+
reply_to_primary(peer, 0);
4801+
}
4802+
#endif
4803+
47094804
#ifdef RTE_LIB_PDUMP
47104805
/* uninitialize packet capture framework */
47114806
rte_pdump_uninit();

0 commit comments

Comments
 (0)