From 72e6d1b94bd7c173af0500369e5bc34be8e58ec1 Mon Sep 17 00:00:00 2001 From: Harry van Haaren Date: Tue, 9 Jan 2018 13:37:41 +0000 Subject: [PATCH] service: fix service core launch This patch fixes a potential bug, which was not consistently showing up in the unit tests. The issue was that the service- lcore being started was not in a "WAIT" state, and hence EAL would return -EBUSY instead of launching the lcore. In order to ensure a core is in a launch-ready state, the application must call rte_eal_wait_lcore, to ensure that the core has completed its previous task, and that EAL is ready to re-launch it. The call to rte_eal_wait_lcore() is explicitly not in the service core function, to make it visible to the application. Requiring an explicit function call ensures the developer sees that a lcore could block in the rte_eal_wait_lcore() function if the core hasn't returned from its previous function. From a usability perspective, hiding the wait_lcore() inside service cores would cause confusion. This patch adds rte_eal_wait_lcore() calls to the unit tests, to ensure that the lcores for testing functionality are ready to run the test. Fixes: 21698354c832 ("service: introduce service cores concept") Cc: stable@dpdk.org Signed-off-by: Harry van Haaren Acked-by: Pavan Nikhilesh --- lib/librte_eal/common/include/rte_service.h | 4 +++- test/test/test_service_cores.c | 10 +++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/librte_eal/common/include/rte_service.h b/lib/librte_eal/common/include/rte_service.h index 5a763831e5..95def4cc22 100644 --- a/lib/librte_eal/common/include/rte_service.h +++ b/lib/librte_eal/common/include/rte_service.h @@ -246,7 +246,9 @@ int32_t rte_service_run_iter_on_app_lcore(uint32_t id, * Start a service core. * * Starting a core makes the core begin polling. Any services assigned to it - * will be run as fast as possible. + * will be run as fast as possible. The application must ensure that the lcore + * is in a launchable state: e.g. call *rte_eal_lcore_wait* on the lcore_id + * before calling this function. * * @retval 0 Success * @retval -EINVAL Failed to start core. The *lcore_id* passed in is not diff --git a/test/test/test_service_cores.c b/test/test/test_service_cores.c index 7d09f5cc3b..2972a801d4 100644 --- a/test/test/test_service_cores.c +++ b/test/test/test_service_cores.c @@ -320,6 +320,7 @@ service_lcore_en_dis_able(void) /* call remote_launch to verify that app can launch ex-service lcore */ service_remote_launch_flag = 0; + rte_eal_wait_lcore(slcore_id); int ret = rte_eal_remote_launch(service_remote_launch_func, NULL, slcore_id); TEST_ASSERT_EQUAL(0, ret, "Ex-service core remote launch failed."); @@ -334,7 +335,7 @@ static int service_lcore_running_check(void) { uint64_t tick = service_tick; - rte_delay_ms(SERVICE_DELAY * 10); + rte_delay_ms(SERVICE_DELAY * 100); /* if (tick != service_tick) we know the lcore as polled the service */ return tick != service_tick; } @@ -477,6 +478,10 @@ service_threaded_test(int mt_safe) if (!mt_safe) test_params[1] = 1; + /* wait for lcores before start() */ + rte_eal_wait_lcore(slcore_1); + rte_eal_wait_lcore(slcore_2); + rte_service_lcore_start(slcore_1); rte_service_lcore_start(slcore_2); @@ -490,6 +495,8 @@ service_threaded_test(int mt_safe) TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 0), "Failed to stop MT Safe service"); + rte_eal_wait_lcore(slcore_1); + rte_eal_wait_lcore(slcore_2); unregister_all(); /* return the value of the callback pass_test variable to caller */ @@ -583,6 +590,7 @@ service_app_lcore_poll_impl(const int mt_safe) rte_service_runstate_set(id, 1); uint32_t app_core2 = rte_get_next_lcore(slcore_id, 1, 1); + rte_eal_wait_lcore(app_core2); int app_core2_ret = rte_eal_remote_launch(service_run_on_app_core_func, &id, app_core2); -- 2.20.1