xref: /freebsd/sys/kern/kern_idle.c (revision 9207b4cff7b8d483f4dd3c62266c2b58819eb7f9)
1 /*-
2  * Copyright (c) 2000, All rights reserved.  See /usr/src/COPYRIGHT
3  *
4  * $FreeBSD$
5  */
6 
7 #include "opt_ktrace.h"
8 
9 #include <sys/param.h>
10 #include <sys/systm.h>
11 #include <sys/kernel.h>
12 #include <sys/ktr.h>
13 #include <sys/kthread.h>
14 #include <sys/lock.h>
15 #include <sys/mutex.h>
16 #include <sys/pcpu.h>
17 #include <sys/proc.h>
18 #include <sys/resourcevar.h>
19 #include <sys/smp.h>
20 #include <sys/unistd.h>
21 #ifdef KTRACE
22 #include <sys/uio.h>
23 #include <sys/ktrace.h>
24 #endif
25 
26 static void idle_setup(void *dummy);
27 SYSINIT(idle_setup, SI_SUB_SCHED_IDLE, SI_ORDER_FIRST, idle_setup, NULL)
28 
29 static void idle_proc(void *dummy);
30 
31 /*
32  * Setup per-cpu idle process contexts.  The AP's shouldn't be running or
33  * accessing their idle processes at this point, so don't bother with
34  * locking.
35  */
36 static void
37 idle_setup(void *dummy)
38 {
39 #ifdef SMP
40 	struct pcpu *pc;
41 #endif
42 	struct proc *p;
43 	int error;
44 
45 #ifdef SMP
46 	SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
47 		error = kthread_create(idle_proc, NULL, &p,
48 		    RFSTOPPED | RFHIGHPID, "idle: cpu%d", pc->pc_cpuid);
49 		pc->pc_idlethread = &p->p_thread;
50 		if (pc->pc_curthread == NULL)
51 			pc->pc_curthread = pc->pc_idlethread;
52 #else
53 		error = kthread_create(idle_proc, NULL, &p,
54 		    RFSTOPPED | RFHIGHPID, "idle");
55 		PCPU_SET(idlethread, &p->p_thread);
56 #endif
57 		if (error)
58 			panic("idle_setup: kthread_create error %d\n", error);
59 
60 		p->p_flag |= P_NOLOAD;
61 		p->p_stat = SRUN;
62 #ifdef SMP
63 	}
64 #endif
65 }
66 
67 /*
68  * idle process context
69  */
70 static void
71 idle_proc(void *dummy)
72 {
73 #ifdef DIAGNOSTIC
74 	int count;
75 #endif
76 
77 	for (;;) {
78 		mtx_assert(&Giant, MA_NOTOWNED);
79 
80 #ifdef DIAGNOSTIC
81 		count = 0;
82 
83 		while (count >= 0 && procrunnable() == 0) {
84 #else
85 		while (procrunnable() == 0) {
86 #endif
87 		/*
88 		 * This is a good place to put things to be done in
89 		 * the background, including sanity checks.
90 		 */
91 
92 #ifdef DIAGNOSTIC
93 			if (count++ < 0)
94 				CTR0(KTR_PROC, "idle_proc: timed out waiting"
95 				    " for a process");
96 #endif
97 
98 #ifdef __i386__
99 			cpu_idle();
100 #endif
101 		}
102 
103 		mtx_lock_spin(&sched_lock);
104 		curproc->p_stats->p_ru.ru_nvcsw++;
105 		mi_switch();
106 		mtx_unlock_spin(&sched_lock);
107 	}
108 }
109