aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/livepatch/transition.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/livepatch/transition.c')
-rw-r--r--kernel/livepatch/transition.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c
index 300273819674..ea7697bb753e 100644
--- a/kernel/livepatch/transition.c
+++ b/kernel/livepatch/transition.c
@@ -29,10 +29,14 @@
29#define MAX_STACK_ENTRIES 100 29#define MAX_STACK_ENTRIES 100
30#define STACK_ERR_BUF_SIZE 128 30#define STACK_ERR_BUF_SIZE 128
31 31
32#define SIGNALS_TIMEOUT 15
33
32struct klp_patch *klp_transition_patch; 34struct klp_patch *klp_transition_patch;
33 35
34static int klp_target_state = KLP_UNDEFINED; 36static int klp_target_state = KLP_UNDEFINED;
35 37
38static unsigned int klp_signals_cnt;
39
36/* 40/*
37 * This work can be performed periodically to finish patching or unpatching any 41 * This work can be performed periodically to finish patching or unpatching any
38 * "straggler" tasks which failed to transition in the first attempt. 42 * "straggler" tasks which failed to transition in the first attempt.
@@ -393,6 +397,10 @@ void klp_try_complete_transition(void)
393 put_online_cpus(); 397 put_online_cpus();
394 398
395 if (!complete) { 399 if (!complete) {
400 if (klp_signals_cnt && !(klp_signals_cnt % SIGNALS_TIMEOUT))
401 klp_send_signals();
402 klp_signals_cnt++;
403
396 /* 404 /*
397 * Some tasks weren't able to be switched over. Try again 405 * Some tasks weren't able to be switched over. Try again
398 * later and/or wait for other methods like kernel exit 406 * later and/or wait for other methods like kernel exit
@@ -454,6 +462,8 @@ void klp_start_transition(void)
454 if (task->patch_state != klp_target_state) 462 if (task->patch_state != klp_target_state)
455 set_tsk_thread_flag(task, TIF_PATCH_PENDING); 463 set_tsk_thread_flag(task, TIF_PATCH_PENDING);
456 } 464 }
465
466 klp_signals_cnt = 0;
457} 467}
458 468
459/* 469/*
@@ -578,14 +588,14 @@ void klp_copy_process(struct task_struct *child)
578 588
579/* 589/*
580 * Sends a fake signal to all non-kthread tasks with TIF_PATCH_PENDING set. 590 * Sends a fake signal to all non-kthread tasks with TIF_PATCH_PENDING set.
581 * Kthreads with TIF_PATCH_PENDING set are woken up. Only admin can request this 591 * Kthreads with TIF_PATCH_PENDING set are woken up.
582 * action currently.
583 */ 592 */
584void klp_send_signals(void) 593void klp_send_signals(void)
585{ 594{
586 struct task_struct *g, *task; 595 struct task_struct *g, *task;
587 596
588 pr_notice("signaling remaining tasks\n"); 597 if (klp_signals_cnt == SIGNALS_TIMEOUT)
598 pr_notice("signaling remaining tasks\n");
589 599
590 read_lock(&tasklist_lock); 600 read_lock(&tasklist_lock);
591 for_each_process_thread(g, task) { 601 for_each_process_thread(g, task) {