Skip to content

Commit f895fcc

Browse files
committed
fix(process): wake reparented child wait owner
Publish the completed natural-parent notification before taking a fresh parent snapshot under the ptrace relation lock. Wake both the original notification owner and a different completion-time parent so a concurrent zombie reparent cannot strand wait4 after observing the transient Pending state. Signed-off-by: longjin <longjin@dragonos.org>
1 parent f117481 commit f895fcc

1 file changed

Lines changed: 14 additions & 0 deletions

File tree

kernel/src/process/manager/exit.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,15 @@ impl ProcessManager {
273273
child.sighand().complete_natural_parent_notify(token),
274274
"natural-parent notification ownership changed"
275275
);
276+
// Reparenting is serialized by PTRACE_RELATION_LOCK. If it completed
277+
// before this snapshot, wake the new wait owner after publishing Done;
278+
// if it happens later, the reparent path wakes after Done is visible
279+
// to the waiter. This closes the Pending -> reparent lost-wakeup
280+
// window without holding the relation lock across signal delivery.
281+
let completion_parent = {
282+
let _relation_guard = crate::process::PTRACE_RELATION_LOCK.lock_irqsave();
283+
child.real_parent_pcb()
284+
};
276285

277286
if let Some((signal, mut info)) = notification {
278287
if let Err(e) =
@@ -288,6 +297,11 @@ impl ProcessManager {
288297
}
289298

290299
ProcessManager::wake_wait_parent(&parent);
300+
if let Some(completion_parent) = completion_parent {
301+
if !Arc::ptr_eq(&completion_parent, &parent) {
302+
ProcessManager::wake_wait_parent(&completion_parent);
303+
}
304+
}
291305

292306
if child.is_kthread() {
293307
KernelThreadMechanism::notify_daemon();

0 commit comments

Comments
 (0)