From ce03437d567717bcee61ff464bc45f0a98dd3eb9 Mon Sep 17 00:00:00 2001 From: Matt Delco Date: Tue, 21 Jan 2020 15:01:50 -0800 Subject: tests: avoid internal error in pause test When running plugin tests it's not uncommon to see: vcpu 0 has internal error Though the tests don't actually fail on this problem. This seems to occur as a side effect of the plugin_vcpu_pause.c calling crosvm_destory_memory() before the test VM has actually finished running. The main thread will call read() on the 'kill' eventfd 5 times for: init, pause, unpause, unpause, kill The vcpu thread will call write() on the eventfd up to 8 times: init, pause #1, unpause #1, pause #2, unpause #2, pause #3, unpause #3, kill The main thread's third pause request might occur before the second pause request has been processed, in which case the vcpu thread will only be paused twice (thus there will only be 6 calls to write()). Given the unpredictable # of events I've opted to split the init/pause/unpause events to a separate eventfd and keep the 'kill' eventfd solely for its intended purpose. BUG=None TEST=ran ./build_test several times and observed no failures in the pause plugin test. Change-Id: Ie0817a4419ae6199fcc5c53496360b2bd81556e3 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2012788 Reviewed-by: Matt Delco Commit-Queue: Matt Delco Tested-by: Matt Delco Tested-by: kokoro --- tests/plugin_vcpu_pause.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'tests') diff --git a/tests/plugin_vcpu_pause.c b/tests/plugin_vcpu_pause.c index ff69b04..010d0fa 100644 --- a/tests/plugin_vcpu_pause.c +++ b/tests/plugin_vcpu_pause.c @@ -13,8 +13,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -36,6 +38,7 @@ #define KILL_ADDRESS 0x3f9 static char g_serial_out[16]; +static int g_next_evt; static int g_kill_evt; static bool g_paused; @@ -70,7 +73,7 @@ static void *vcpu_thread_fn(void *arg) { /* Signal the main thread that init is done */ uint64_t dummy = 1; - write(g_kill_evt, &dummy, sizeof(dummy)); + write(g_next_evt, &dummy, sizeof(dummy)); } else if (evt.kind == CROSVM_VCPU_EVENT_KIND_IO_ACCESS && evt.io_access.address_space == CROSVM_ADDRESS_SPACE_IOPORT && @@ -85,7 +88,7 @@ static void *vcpu_thread_fn(void *arg) { else if (evt.kind == CROSVM_VCPU_EVENT_KIND_PAUSED) { /* Signal that we paused */ uint64_t dummy = 1; - write(g_kill_evt, &dummy, sizeof(dummy)); + write(g_next_evt, &dummy, sizeof(dummy)); /* Wait till we can continue again */ pthread_mutex_lock(&g_pause_mutex); @@ -101,7 +104,7 @@ static void *vcpu_thread_fn(void *arg) { } /* Signal that we are no longer paused */ - write(g_kill_evt, &dummy, sizeof(dummy)); + write(g_next_evt, &dummy, sizeof(dummy)); pthread_mutex_unlock(&g_pause_mutex); } @@ -147,6 +150,12 @@ int main(int argc, char** argv) { 0xf4 }; + g_next_evt = eventfd(0, 0); + if (g_next_evt == -1) { + fprintf(stderr, "failed to create eventfd: %d\n", errno); + return 1; + } + struct crosvm *crosvm; int ret = crosvm_connect(&crosvm); if (ret) { @@ -220,7 +229,7 @@ int main(int argc, char** argv) { /* Wait till VCPU thread tells us that its initialization is done */ uint64_t dummy; - read(g_kill_evt, &dummy, sizeof(dummy)); + read(g_next_evt, &dummy, sizeof(dummy)); ret = signal_pause(crosvm); if (ret) { @@ -229,7 +238,7 @@ int main(int argc, char** argv) { } /* Wait till VCPU thread tells us it is paused */ - read(g_kill_evt, &dummy, sizeof(dummy)); + read(g_next_evt, &dummy, sizeof(dummy)); /* Try pausing VCPUs 2nd time to make sure we do not deadlock */ ret = signal_pause(crosvm); @@ -241,7 +250,7 @@ int main(int argc, char** argv) { signal_unpause(crosvm, false); /* Wait until VCPU thread tells us that it is no longer paused */ - read(g_kill_evt, &dummy, sizeof(dummy)); + read(g_next_evt, &dummy, sizeof(dummy)); /* * Try pausing VCPUs 3rd time to see if we will miss pause @@ -255,9 +264,6 @@ int main(int argc, char** argv) { signal_unpause(crosvm, true); - /* Wait until VCPU thread tells us that it is no longer paused */ - read(g_kill_evt, &dummy, sizeof(dummy)); - /* Wait for crosvm to request that we exit otherwise we will be killed. */ read(g_kill_evt, &dummy, sizeof(dummy)); -- cgit 1.4.1