diff options
Diffstat (limited to 'kernel/livepatch/transition.c')
-rw-r--r-- | kernel/livepatch/transition.c | 16 |
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 | |||
32 | struct klp_patch *klp_transition_patch; | 34 | struct klp_patch *klp_transition_patch; |
33 | 35 | ||
34 | static int klp_target_state = KLP_UNDEFINED; | 36 | static int klp_target_state = KLP_UNDEFINED; |
35 | 37 | ||
38 | static 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 | */ |
584 | void klp_send_signals(void) | 593 | void 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) { |