xref: /freebsd/sys/kern/kern_idle.c (revision ba228f6d9632d96ba3303ae329172f2f96f4463f)
10384fff8SJason Evans /*-
20384fff8SJason Evans  * Copyright (c) 2000, All rights reserved.  See /usr/src/COPYRIGHT
30384fff8SJason Evans  *
40384fff8SJason Evans  * $FreeBSD$
50384fff8SJason Evans  */
60384fff8SJason Evans 
70384fff8SJason Evans #include "opt_ktrace.h"
80384fff8SJason Evans 
90384fff8SJason Evans #include <sys/param.h>
100384fff8SJason Evans #include <sys/systm.h>
110384fff8SJason Evans #include <sys/kernel.h>
120384fff8SJason Evans #include <sys/ktr.h>
13ba228f6dSJohn Baldwin #include <sys/kthread.h>
14fb919e4dSMark Murray #include <sys/lock.h>
15fb919e4dSMark Murray #include <sys/mutex.h>
16ba228f6dSJohn Baldwin #include <sys/pcpu.h>
17fb919e4dSMark Murray #include <sys/proc.h>
180384fff8SJason Evans #include <sys/resourcevar.h>
19ba228f6dSJohn Baldwin #include <sys/smp.h>
200384fff8SJason Evans #include <sys/unistd.h>
21ba228f6dSJohn Baldwin #if 0
220384fff8SJason Evans #include <vm/vm.h>
230384fff8SJason Evans #include <vm/vm_extern.h>
24ba228f6dSJohn Baldwin #endif
250384fff8SJason Evans #ifdef KTRACE
260384fff8SJason Evans #include <sys/uio.h>
270384fff8SJason Evans #include <sys/ktrace.h>
280384fff8SJason Evans #endif
290384fff8SJason Evans 
300384fff8SJason Evans static void idle_setup(void *dummy);
310384fff8SJason Evans SYSINIT(idle_setup, SI_SUB_SCHED_IDLE, SI_ORDER_FIRST, idle_setup, NULL)
320384fff8SJason Evans 
330384fff8SJason Evans static void idle_proc(void *dummy);
340384fff8SJason Evans 
350384fff8SJason Evans /*
367ecfc090SJohn Baldwin  * Setup per-cpu idle process contexts.  The AP's shouldn't be running or
377ecfc090SJohn Baldwin  * accessing their idle processes at this point, so don't bother with
387ecfc090SJohn Baldwin  * locking.
390384fff8SJason Evans  */
400384fff8SJason Evans static void
410384fff8SJason Evans idle_setup(void *dummy)
420384fff8SJason Evans {
436caa8a15SJohn Baldwin #ifdef SMP
440384fff8SJason Evans 	struct globaldata *gd;
456caa8a15SJohn Baldwin #endif
466caa8a15SJohn Baldwin 	struct proc *p;
470384fff8SJason Evans 	int error;
480384fff8SJason Evans 
490384fff8SJason Evans #ifdef SMP
506caa8a15SJohn Baldwin 	SLIST_FOREACH(gd, &cpuhead, gd_allcpu) {
516caa8a15SJohn Baldwin 		error = kthread_create(idle_proc, NULL, &p,
526caa8a15SJohn Baldwin 		    RFSTOPPED | RFHIGHPID, "idle: cpu%d", gd->gd_cpuid);
536caa8a15SJohn Baldwin 		gd->gd_idleproc = p;
546caa8a15SJohn Baldwin 		if (gd->gd_curproc == NULL)
556caa8a15SJohn Baldwin 			gd->gd_curproc = p;
560384fff8SJason Evans #else
576caa8a15SJohn Baldwin 		error = kthread_create(idle_proc, NULL, &p,
580384fff8SJason Evans 		    RFSTOPPED | RFHIGHPID, "idle");
596caa8a15SJohn Baldwin 		PCPU_SET(idleproc, p);
600384fff8SJason Evans #endif
610384fff8SJason Evans 		if (error)
620384fff8SJason Evans 			panic("idle_setup: kthread_create error %d\n", error);
630384fff8SJason Evans 
646caa8a15SJohn Baldwin 		p->p_flag |= P_NOLOAD;
656caa8a15SJohn Baldwin 		p->p_stat = SRUN;
666caa8a15SJohn Baldwin #ifdef SMP
670384fff8SJason Evans 	}
686caa8a15SJohn Baldwin #endif
690384fff8SJason Evans }
700384fff8SJason Evans 
710384fff8SJason Evans /*
720384fff8SJason Evans  * idle process context
730384fff8SJason Evans  */
740384fff8SJason Evans static void
750384fff8SJason Evans idle_proc(void *dummy)
760384fff8SJason Evans {
773650b375SJohn Baldwin #ifdef DIAGNOSTIC
780384fff8SJason Evans 	int count;
793650b375SJohn Baldwin #endif
800384fff8SJason Evans 
810384fff8SJason Evans 	for (;;) {
820384fff8SJason Evans 		mtx_assert(&Giant, MA_NOTOWNED);
830384fff8SJason Evans 
843650b375SJohn Baldwin #ifdef DIAGNOSTIC
850384fff8SJason Evans 		count = 0;
860384fff8SJason Evans 
870384fff8SJason Evans 		while (count >= 0 && procrunnable() == 0) {
883650b375SJohn Baldwin #else
893650b375SJohn Baldwin 		while (procrunnable() == 0) {
903650b375SJohn Baldwin #endif
910384fff8SJason Evans 		/*
920384fff8SJason Evans 		 * This is a good place to put things to be done in
930384fff8SJason Evans 		 * the background, including sanity checks.
940384fff8SJason Evans 		 */
95bdf3d8b9SMike Smith 
963650b375SJohn Baldwin #ifdef DIAGNOSTIC
970384fff8SJason Evans 			if (count++ < 0)
980384fff8SJason Evans 				CTR0(KTR_PROC, "idle_proc: timed out waiting"
990384fff8SJason Evans 				    " for a process");
1003650b375SJohn Baldwin #endif
1013650b375SJohn Baldwin 
102d5a08a60SJake Burkholder #if 0
1033650b375SJohn Baldwin 			if (vm_page_zero_idle() != 0)
1043650b375SJohn Baldwin 				continue;
105d5a08a60SJake Burkholder #endif
106bdf3d8b9SMike Smith 
107dc13e6dfSJohn Baldwin #ifdef __i386__
108dc13e6dfSJohn Baldwin 			cpu_idle();
109dc13e6dfSJohn Baldwin #endif
1100384fff8SJason Evans 		}
1110384fff8SJason Evans 
1129ed346baSBosko Milekic 		mtx_lock_spin(&sched_lock);
1137ecfc090SJohn Baldwin 		curproc->p_stats->p_ru.ru_nvcsw++;
1140384fff8SJason Evans 		mi_switch();
1159ed346baSBosko Milekic 		mtx_unlock_spin(&sched_lock);
1160384fff8SJason Evans 	}
1170384fff8SJason Evans }
118