From: Yafang Shao <laoar.shao@gmail.com>
To: jpoimboe@kernel.org, jikos@kernel.org, mbenes@suse.cz,
pmladek@suse.com, joe.lawrence@redhat.com
Cc: live-patching@vger.kernel.org, Yafang Shao <laoar.shao@gmail.com>
Subject: [PATCH 2/3] livepatch: Avoid blocking tasklist_lock too long
Date: Tue, 11 Feb 2025 14:24:36 +0800 [thread overview]
Message-ID: <20250211062437.46811-3-laoar.shao@gmail.com> (raw)
In-Reply-To: <20250211062437.46811-1-laoar.shao@gmail.com>
I encountered a hard lockup when attempting to reproduce the panic issue
occurred on our production servers [0]. The hard lockup is as follows,
[15852778.150191] livepatch: klp_try_switch_task: grpc_executor:421106 is sleeping on function do_exit
[15852778.169471] livepatch: klp_try_switch_task: grpc_executor:421244 is sleeping on function do_exit
[15852778.188746] livepatch: klp_try_switch_task: grpc_executor:421457 is sleeping on function do_exit
[15852778.208021] livepatch: klp_try_switch_task: grpc_executor:422407 is sleeping on function do_exit
[15852778.227292] livepatch: klp_try_switch_task: grpc_executor:423184 is sleeping on function do_exit
[15852778.246576] livepatch: klp_try_switch_task: grpc_executor:423582 is sleeping on function do_exit
[15852778.265863] livepatch: klp_try_switch_task: grpc_executor:423738 is sleeping on function do_exit
[15852778.285149] livepatch: klp_try_switch_task: grpc_executor:423739 is sleeping on function do_exit
[15852778.304446] livepatch: klp_try_switch_task: grpc_executor:423833 is sleeping on function do_exit
[15852778.323738] livepatch: klp_try_switch_task: grpc_executor:423893 is sleeping on function do_exit
[15852778.343017] livepatch: klp_try_switch_task: grpc_executor:423894 is sleeping on function do_exit
[15852778.362292] livepatch: klp_try_switch_task: grpc_executor:423976 is sleeping on function do_exit
[15852778.381565] livepatch: klp_try_switch_task: grpc_executor:423977 is sleeping on function do_exit
[15852778.400847] livepatch: klp_try_switch_task: grpc_executor:424610 is sleeping on function do_exit
[15852778.412319] NMI watchdog: Watchdog detected hard LOCKUP on cpu 15
...
[15852778.412374] CPU: 15 PID: 1 Comm: systemd Kdump: loaded Tainted: G S W O K 6.1.52-3
[15852778.412378] RIP: 0010:queued_write_lock_slowpath+0x75/0x135
...
[15852778.412397] Call Trace:
[15852778.412398] <NMI>
[15852778.412400] ? show_regs.cold+0x1a/0x1f
[15852778.412403] ? watchdog_overflow_callback.cold+0x1e/0x70
[15852778.412406] ? __perf_event_overflow+0x102/0x1e0
[15852778.412409] ? perf_event_overflow+0x19/0x20
[15852778.412411] ? x86_pmu_handle_irq+0xf7/0x160
[15852778.412415] ? flush_tlb_one_kernel+0xe/0x30
[15852778.412418] ? __set_pte_vaddr+0x2d/0x40
[15852778.412421] ? set_pte_vaddr_p4d+0x3d/0x50
[15852778.412423] ? set_pte_vaddr+0x6d/0xa0
[15852778.412424] ? __native_set_fixmap+0x28/0x40
[15852778.412426] ? native_set_fixmap+0x54/0x60
[15852778.412428] ? ghes_copy_tofrom_phys+0x75/0x120
[15852778.412431] ? __ghes_peek_estatus.isra.0+0x4e/0xb0
[15852778.412434] ? ghes_in_nmi_queue_one_entry.constprop.0+0x3d/0x240
[15852778.412437] ? amd_pmu_handle_irq+0x48/0xc0
[15852778.412438] ? perf_event_nmi_handler+0x2d/0x50
[15852778.412440] ? nmi_handle+0x60/0x120
[15852778.412443] ? default_do_nmi+0x45/0x120
[15852778.412446] ? exc_nmi+0x118/0x150
[15852778.412447] ? end_repeat_nmi+0x16/0x67
[15852778.412450] ? copy_process+0xf01/0x19f0
[15852778.412452] ? queued_write_lock_slowpath+0x75/0x135
[15852778.412455] ? queued_write_lock_slowpath+0x75/0x135
[15852778.412457] ? queued_write_lock_slowpath+0x75/0x135
[15852778.412459] </NMI>
[15852778.412460] <TASK>
[15852778.412461] _raw_write_lock_irq+0x43/0x50
[15852778.412463] copy_process+0xf01/0x19f0
[15852778.412466] kernel_clone+0x9d/0x3e0
[15852778.412468] ? autofs_dev_ioctl_requester+0x100/0x100
[15852778.412471] __do_sys_clone+0x66/0x90
[15852778.412475] __x64_sys_clone+0x25/0x30
[15852778.412477] do_syscall_64+0x38/0x90
[15852778.412478] entry_SYSCALL_64_after_hwframe+0x64/0xce
[15852778.412481] RIP: 0033:0x7f426bb3b9c1
...
Notebly, the dynamic_debug is enabled to collect the debug information
when applying a livepatch. Therefore, there're numerous debug
information.
As the execution of klp_try_switch_task() has been holding the
tasklist_lock, if another task is trying to hold it again, it will have to
spin on it. In the copy_process() path, the irq lock is disabled as well,
and thus this hard lockup occurs. We can avoid this hard lockup by checking
the spinlock contention.
This change is based on code originally developed by Petr[1].
Link: https://lore.kernel.org/all/CALOAHbA9WHPjeZKUcUkwULagQjTMfqAdAg+akqPzbZ7Byc=qrw@mail.gmail.com/ [0]
Link: https://lore.kernel.org/all/Z6Tmqro6CSm0h-E3@pathway.suse.cz/ [1]
Originally-by: Petr Mladek <pmladek@suse.com>
Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
kernel/livepatch/transition.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c
index ba069459c101..04704a19dcfe 100644
--- a/kernel/livepatch/transition.c
+++ b/kernel/livepatch/transition.c
@@ -450,6 +450,7 @@ static void klp_send_signals(void)
*/
void klp_try_complete_transition(void)
{
+ unsigned long timeout, proceed_pending_processes;
unsigned int cpu;
struct task_struct *g, *task;
struct klp_patch *patch;
@@ -467,9 +468,30 @@ void klp_try_complete_transition(void)
* unless the patch includes changes to a very common function.
*/
read_lock(&tasklist_lock);
- for_each_process_thread(g, task)
+ timeout = jiffies + HZ;
+ proceed_pending_processes = 0;
+ for_each_process_thread(g, task) {
+ /* check if this task has already switched over */
+ if (task->patch_state == klp_target_state)
+ continue;
+
+ proceed_pending_processes++;
+
if (!klp_try_switch_task(task))
complete = false;
+
+ /*
+ * Prevent hardlockup by not blocking tasklist_lock for too long.
+ * But guarantee the forward progress by making sure at least
+ * some pending processes were checked.
+ */
+ if (rwlock_is_contended(&tasklist_lock) &&
+ time_after(jiffies, timeout) &&
+ proceed_pending_processes > 100) {
+ complete = false;
+ break;
+ }
+ }
read_unlock(&tasklist_lock);
/*
--
2.43.5
next prev parent reply other threads:[~2025-02-11 6:24 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-11 6:24 [PATCH 0/3] livepatch: Some improvements Yafang Shao
2025-02-11 6:24 ` [PATCH 1/3] livepatch: Add comment to clarify klp_add_nops() Yafang Shao
2025-02-12 12:51 ` Petr Mladek
2025-02-13 5:49 ` Yafang Shao
2025-02-11 6:24 ` Yafang Shao [this message]
2025-02-12 0:40 ` [PATCH 2/3] livepatch: Avoid blocking tasklist_lock too long Josh Poimboeuf
2025-02-12 2:34 ` Yafang Shao
2025-02-12 11:54 ` Yafang Shao
2025-02-12 15:42 ` Petr Mladek
2025-02-13 1:36 ` Josh Poimboeuf
2025-02-13 5:53 ` Yafang Shao
2025-02-13 9:48 ` Petr Mladek
2025-02-13 17:32 ` Josh Poimboeuf
2025-02-14 14:44 ` Petr Mladek
2025-02-14 18:12 ` Josh Poimboeuf
2025-02-18 2:37 ` Yafang Shao
2025-02-13 2:47 ` Josh Poimboeuf
2025-02-13 11:19 ` Find root of the stall: was: " Petr Mladek
2025-02-13 12:32 ` Yafang Shao
2025-02-13 12:39 ` Yafang Shao
2025-02-14 2:44 ` Yafang Shao
2025-02-14 8:36 ` Josh Poimboeuf
2025-02-14 11:37 ` Petr Mladek
2025-02-18 2:19 ` Yafang Shao
2025-02-14 9:46 ` Petr Mladek
2025-02-11 6:24 ` [PATCH 3/3] livepatch: Avoid potential RCU stalls in klp transition Yafang Shao
2025-02-12 0:52 ` Josh Poimboeuf
2025-02-12 2:42 ` Yafang Shao
2025-02-13 1:58 ` Josh Poimboeuf
2025-02-13 5:51 ` Yafang Shao
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250211062437.46811-3-laoar.shao@gmail.com \
--to=laoar.shao@gmail.com \
--cc=jikos@kernel.org \
--cc=joe.lawrence@redhat.com \
--cc=jpoimboe@kernel.org \
--cc=live-patching@vger.kernel.org \
--cc=mbenes@suse.cz \
--cc=pmladek@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox