kernel: hold TaskSet mutex across exitPtrace() and exitChildren()

This just saves needlessly bouncing the mutex. Compare Linux
kernel/exit.c:exit_notify() => write_lock_irq(&tasklist_lock);
forget_original_parent() => exit_ptrace().

PiperOrigin-RevId: 681181467
This commit is contained in:
Jamie Liu
2024-10-01 15:10:50 -07:00
committed by gVisor bot
parent a32d047f68
commit baaaf47fc2
2 changed files with 12 additions and 12 deletions
+4 -4
View File
@@ -567,10 +567,10 @@ func (t *Task) ptraceDetach(target *Task, sig linux.Signal) error {
return nil
}
// exitPtrace is called in the exit path to detach all of t's tracees.
func (t *Task) exitPtrace() {
t.tg.pidns.owner.mu.Lock()
defer t.tg.pidns.owner.mu.Unlock()
// exitPtraceLocked is called in the exit path to detach all of t's tracees.
//
// Preconditions: The TaskSet mutex must be locked for writing.
func (t *Task) exitPtraceLocked() {
for target := range t.ptraceTracees {
if target.ptraceOpts.ExitKill {
target.tg.signalHandlers.mu.Lock()
+8 -8
View File
@@ -315,14 +315,15 @@ func (*runExitMain) execute(t *Task) taskRunState {
t.tg.Release(t)
}
t.tg.pidns.owner.mu.Lock()
// Detach tracees.
t.exitPtrace()
t.exitPtraceLocked()
// Reparent the task's children.
t.exitChildren()
t.exitChildrenLocked()
t.tg.pidns.owner.mu.Unlock()
// Don't tail-call runExitNotify, as exitChildren may have initiated a stop
// to wait for a PID namespace to die.
// Don't tail-call runExitNotify, as exitChildrenLocked may have initiated
// a stop to wait for a PID namespace to die.
return (*runExitNotify)(nil)
}
@@ -360,9 +361,8 @@ func (t *Task) exitThreadGroup() bool {
return last
}
func (t *Task) exitChildren() {
t.tg.pidns.owner.mu.Lock()
defer t.tg.pidns.owner.mu.Unlock()
// Preconditions: The TaskSet mutex must be locked for writing.
func (t *Task) exitChildrenLocked() {
newParent := t.findReparentTargetLocked()
if newParent == nil {
// "If the init process of a PID namespace terminates, the kernel