From b4d753d05e7c4273e5e2de9d3b1e73b262358ccc Mon Sep 17 00:00:00 2001 From: Joe Lawrence Date: Thu, 2 Jun 2022 16:32:33 -0400 Subject: [PATCH] selftests/livepatch: better synchronize test_klp_callbacks_busy [ Upstream commit 4e3523b8da916c67ebc612043bd51b4a97a099ae ] The test_klp_callbacks_busy module conditionally blocks a future livepatch transition by busy waiting inside its workqueue function, busymod_work_func(). After scheduling this work, a test livepatch is loaded, introducing the transition under test. Both events are marked in the kernel log for later verification, but there is no synchronization to ensure that busymod_work_func() logs its function entry message before subsequent selftest commands log their own messages. This can lead to a rare test failure due to unexpected ordering like: # --- expected # +++ result # @@ -1,7 +1,7 @@ # % modprobe test_klp_callbacks_busy block_transition=Y # test_klp_callbacks_busy: test_klp_callbacks_busy_init # -test_klp_callbacks_busy: busymod_work_func enter # % modprobe test_klp_callbacks_demo # +test_klp_callbacks_busy: busymod_work_func enter # livepatch: enabling patch 'test_klp_callbacks_demo' # livepatch: 'test_klp_callbacks_demo': initializing patching transition # test_klp_callbacks_demo: pre_patch_callback: vmlinux Force the module init function to wait until busymod_work_func() has started (and logged its message), before exiting to the next selftest steps. Fixes: 243adb36ed6d ("selftests/livepatch: simplify test-klp-callbacks busy target tests") Signed-off-by: Joe Lawrence Reviewed-by: Petr Mladek Signed-off-by: Petr Mladek Link: https://lore.kernel.org/r/20220602203233.979681-1-joe.lawrence@redhat.com Signed-off-by: Sasha Levin --- lib/livepatch/test_klp_callbacks_busy.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/livepatch/test_klp_callbacks_busy.c b/lib/livepatch/test_klp_callbacks_busy.c index 7ac845f65be56..133929e0ce8ff 100644 --- a/lib/livepatch/test_klp_callbacks_busy.c +++ b/lib/livepatch/test_klp_callbacks_busy.c @@ -16,10 +16,12 @@ MODULE_PARM_DESC(block_transition, "block_transition (default=false)"); static void busymod_work_func(struct work_struct *work); static DECLARE_WORK(work, busymod_work_func); +static DECLARE_COMPLETION(busymod_work_started); static void busymod_work_func(struct work_struct *work) { pr_info("%s enter\n", __func__); + complete(&busymod_work_started); while (READ_ONCE(block_transition)) { /* @@ -37,6 +39,12 @@ static int test_klp_callbacks_busy_init(void) pr_info("%s\n", __func__); schedule_work(&work); + /* + * To synchronize kernel messages, hold the init function from + * exiting until the work function's entry message has printed. + */ + wait_for_completion(&busymod_work_started); + if (!block_transition) { /* * Serialize output: print all messages from the work -- 2.39.5