Make stop_all_proc_block interruptible to avoid deadlock with parallel suspension
If we try to single-thread a process which thread entered procctl(REAP_KILL_SUBTREE), and sleeping waiting for us unlocking stop_all_proc_blocker, we must be able to finish single-threading. This requires the sleep to be interruptible. Reported and tested by: pho Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 2 weeks Differential revision: https://reviews.freebsd.org/D35310
This commit is contained in:
parent
2d5ef216b6
commit
008b2e6544
@ -3399,10 +3399,10 @@ static SYSCTL_NODE(_kern_proc, KERN_PROC_VM_LAYOUT, vm_layout, CTLFLAG_RD |
|
||||
static struct sx stop_all_proc_blocker;
|
||||
SX_SYSINIT(stop_all_proc_blocker, &stop_all_proc_blocker, "sapblk");
|
||||
|
||||
void
|
||||
bool
|
||||
stop_all_proc_block(void)
|
||||
{
|
||||
sx_xlock(&stop_all_proc_blocker);
|
||||
return (sx_xlock_sig(&stop_all_proc_blocker) == 0);
|
||||
}
|
||||
|
||||
void
|
||||
@ -3426,7 +3426,8 @@ stop_all_proc(void)
|
||||
int r, gen;
|
||||
bool restart, seen_stopped, seen_exiting, stopped_some;
|
||||
|
||||
stop_all_proc_block();
|
||||
if (!stop_all_proc_block())
|
||||
return;
|
||||
|
||||
cp = curproc;
|
||||
allproc_loop:
|
||||
|
@ -1063,8 +1063,8 @@ kern_procctl(struct thread *td, idtype_t idtype, id_t id, int com, void *data)
|
||||
sapblk = false;
|
||||
if (cmd_info->sapblk != NULL) {
|
||||
sapblk = cmd_info->sapblk(td, data);
|
||||
if (sapblk)
|
||||
stop_all_proc_block();
|
||||
if (sapblk && !stop_all_proc_block())
|
||||
return (ERESTART);
|
||||
}
|
||||
|
||||
switch (cmd_info->lock_tree) {
|
||||
|
@ -1238,7 +1238,7 @@ void thread_unlink(struct thread *td);
|
||||
void thread_unsuspend(struct proc *p);
|
||||
void thread_wait(struct proc *p);
|
||||
|
||||
void stop_all_proc_block(void);
|
||||
bool stop_all_proc_block(void);
|
||||
void stop_all_proc_unblock(void);
|
||||
void stop_all_proc(void);
|
||||
void resume_all_proc(void);
|
||||
|
Loading…
Reference in New Issue
Block a user