git: 008b2e65442a - main - Make stop_all_proc_block interruptible to avoid deadlock with parallel suspension
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 13 Jun 2022 19:33:38 UTC
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=008b2e65442a0d65bc5be9ca625616ddfa6f9ce2
commit 008b2e65442a0d65bc5be9ca625616ddfa6f9ce2
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2022-04-30 23:29:25 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2022-06-13 19:30:03 +0000
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
---
sys/kern/kern_proc.c | 7 ++++---
sys/kern/kern_procctl.c | 4 ++--
sys/sys/proc.h | 2 +-
3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index 6796d672afd7..67299472231a 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -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:
diff --git a/sys/kern/kern_procctl.c b/sys/kern/kern_procctl.c
index 6919fac71c5a..b6e48b46bb5c 100644
--- a/sys/kern/kern_procctl.c
+++ b/sys/kern/kern_procctl.c
@@ -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) {
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index cdb9cc17945d..5521f8321e2b 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -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);