git: 626d6992ca6d - main - Move fork_rfppwait() check into ast()

From: Edward Tomasz Napierala <trasz_at_FreeBSD.org>
Date: Wed, 29 Dec 2021 13:47:44 UTC
The branch main has been updated by trasz:

URL: https://cgit.FreeBSD.org/src/commit/?id=626d6992ca6deff3c4738a01e8c4798989cc9ec7

commit 626d6992ca6deff3c4738a01e8c4798989cc9ec7
Author:     Edward Tomasz Napierala <trasz@FreeBSD.org>
AuthorDate: 2021-12-26 17:22:16 +0000
Commit:     Edward Tomasz Napierala <trasz@FreeBSD.org>
CommitDate: 2021-12-26 17:22:21 +0000

    Move fork_rfppwait() check into ast()
    
    This will always sleep at least once, so it's a slow path by definition.
    
    Reviewed By:    kib
    Sponsored By:   EPSRC
    Differential Revision:  https://reviews.freebsd.org/D33387
---
 sys/kern/kern_fork.c    | 6 ++++++
 sys/kern/subr_syscall.c | 3 ---
 sys/kern/subr_trap.c    | 2 ++
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 5b518a0183d8..a6d83fc8049d 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -484,6 +484,12 @@ do_fork(struct thread *td, struct fork_req *fr, struct proc *p2, struct thread *
 	 */
 	thread_lock(td);
 	sched_fork(td, td2);
+	/*
+	 * Request AST to check for TDP_RFPPWAIT.  Do it here
+	 * to avoid calling thread_lock() again.
+	 */
+	if ((fr->fr_flags & RFPPWAIT) != 0)
+		td->td_flags |= TDF_ASTPENDING;
 	thread_unlock(td);
 
 	/*
diff --git a/sys/kern/subr_syscall.c b/sys/kern/subr_syscall.c
index dacd82f4c466..fa5dcb482f2c 100644
--- a/sys/kern/subr_syscall.c
+++ b/sys/kern/subr_syscall.c
@@ -285,7 +285,4 @@ syscallret(struct thread *td)
 		td->td_dbgflags &= ~(TDB_SCX | TDB_EXEC | TDB_FORK);
 		PROC_UNLOCK(p);
 	}
-
-	if (__predict_false(td->td_pflags & TDP_RFPPWAIT))
-		fork_rfppwait(td);
 }
diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c
index 2b86fe75776f..ec8f686a497d 100644
--- a/sys/kern/subr_trap.c
+++ b/sys/kern/subr_trap.c
@@ -259,6 +259,8 @@ ast(struct trapframe *framep)
 	if (PMC_IS_PENDING_CALLCHAIN(td))
 		PMC_CALL_HOOK_UNLOCKED(td, PMC_FN_USER_CALLCHAIN_SOFT, (void *) framep);
 #endif
+	if ((td->td_pflags & TDP_RFPPWAIT) != 0)
+		fork_rfppwait(td);
 	if (flags & TDF_ALRMPEND) {
 		PROC_LOCK(p);
 		kern_psignal(p, SIGVTALRM);