git: 33be1632047c - main - racct: Fix accounting of CPU time for the system idle process

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Thu, 01 May 2025 14:22:39 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=33be1632047c05dbfcc139476e05f49c3a86d560

commit 33be1632047c05dbfcc139476e05f49c3a86d560
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2025-05-01 13:59:55 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-05-01 14:22:25 +0000

    racct: Fix accounting of CPU time for the system idle process
    
    - Add a flag which cleanly indicates that a given process is the system
      idle process.
    - Modify racctd() to skip over the idle proc when aggregating CPU time
      and other metrics which don't apply to the idle thread.
    - Remove handling for idle threads from racct_getpcpu().
    
    PR:             269097
    Reviewed by:    olce, kib
    Sponsored by:   Klara, Inc.
    Differential Revision:  https://reviews.freebsd.org/D50073
---
 sys/kern/kern_idle.c  |  3 +++
 sys/kern/kern_racct.c | 22 ++++------------------
 sys/sys/proc.h        |  2 +-
 3 files changed, 8 insertions(+), 19 deletions(-)

diff --git a/sys/kern/kern_idle.c b/sys/kern/kern_idle.c
index a8126de265b2..6be2a96958ed 100644
--- a/sys/kern/kern_idle.c
+++ b/sys/kern/kern_idle.c
@@ -82,4 +82,7 @@ idle_setup(void *dummy)
 #ifdef SMP
 	}
 #endif
+	PROC_LOCK(p);
+	p->p_flag |= P_IDLEPROC;
+	PROC_UNLOCK(p);
 }
diff --git a/sys/kern/kern_racct.c b/sys/kern/kern_racct.c
index d900078fe5e2..cc84356cfc4e 100644
--- a/sys/kern/kern_racct.c
+++ b/sys/kern/kern_racct.c
@@ -322,15 +322,13 @@ racct_getpcpu(struct proc *p, u_int pcpu)
 	u_int swtime;
 #ifdef SCHED_4BSD
 	fixpt_t pctcpu, pctcpu_next;
-#endif
-#ifdef SMP
-	struct pcpu *pc;
-	int found;
 #endif
 	fixpt_t p_pctcpu;
 	struct thread *td;
 
 	ASSERT_RACCT_ENABLED();
+	KASSERT((p->p_flag & P_IDLEPROC) == 0,
+	    ("racct_getpcpu: idle process %p", p));
 
 	swtime = (ticks - p->p_swtick) / hz;
 
@@ -344,19 +342,6 @@ racct_getpcpu(struct proc *p, u_int pcpu)
 
 	p_pctcpu = 0;
 	FOREACH_THREAD_IN_PROC(p, td) {
-		if (td == PCPU_GET(idlethread))
-			continue;
-#ifdef SMP
-		found = 0;
-		STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) {
-			if (td == pc->pc_idlethread) {
-				found = 1;
-				break;
-			}
-		}
-		if (found)
-			continue;
-#endif
 		thread_lock(td);
 #ifdef SCHED_4BSD
 		pctcpu = sched_pctcpu(td);
@@ -1252,7 +1237,8 @@ racctd(void)
 
 		FOREACH_PROC_IN_SYSTEM(p) {
 			PROC_LOCK(p);
-			if (p->p_state != PRS_NORMAL) {
+			if (p->p_state != PRS_NORMAL ||
+			    (p->p_flag & P_IDLEPROC) != 0) {
 				if (p->p_state == PRS_ZOMBIE)
 					racct_set(p, RACCT_PCTCPU, 0);
 				PROC_UNLOCK(p);
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 46482f26e0ef..eb0b66618a9d 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -803,7 +803,7 @@ struct proc {
 					   lock. */
 #define	P_CONTROLT	0x00000002	/* Has a controlling terminal. */
 #define	P_KPROC		0x00000004	/* Kernel process. */
-#define	P_UNUSED3	0x00000008	/* --available-- */
+#define	P_IDLEPROC	0x00000008	/* Container for system idle threads. */
 #define	P_PPWAIT	0x00000010	/* Parent is waiting for child to
 					   exec/exit. */
 #define	P_PROFIL	0x00000020	/* Has started profiling. */