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> 13fb919e4dSMark Murray #include <sys/lock.h> 14fb919e4dSMark Murray #include <sys/mutex.h> 15fb919e4dSMark Murray #include <sys/proc.h> 160384fff8SJason Evans #include <sys/signalvar.h> 176caa8a15SJohn Baldwin #include <sys/smp.h> 180384fff8SJason Evans #include <sys/resourcevar.h> 190384fff8SJason Evans #include <sys/vmmeter.h> 200384fff8SJason Evans #include <sys/sysctl.h> 210384fff8SJason Evans #include <sys/unistd.h> 221931cf94SJohn Baldwin #include <sys/ipl.h> 230384fff8SJason Evans #include <sys/kthread.h> 240384fff8SJason Evans #include <sys/queue.h> 25bdf3d8b9SMike Smith #include <sys/eventhandler.h> 260384fff8SJason Evans #include <vm/vm.h> 270384fff8SJason Evans #include <vm/vm_extern.h> 280384fff8SJason Evans #ifdef KTRACE 290384fff8SJason Evans #include <sys/uio.h> 300384fff8SJason Evans #include <sys/ktrace.h> 310384fff8SJason Evans #endif 320384fff8SJason Evans 330384fff8SJason Evans #include <machine/cpu.h> 343650b375SJohn Baldwin #include <machine/md_var.h> 350384fff8SJason Evans 360384fff8SJason Evans #include <machine/globaldata.h> 370384fff8SJason Evans #include <machine/globals.h> 380384fff8SJason Evans 390384fff8SJason Evans static void idle_setup(void *dummy); 400384fff8SJason Evans SYSINIT(idle_setup, SI_SUB_SCHED_IDLE, SI_ORDER_FIRST, idle_setup, NULL) 410384fff8SJason Evans 420384fff8SJason Evans static void idle_proc(void *dummy); 430384fff8SJason Evans 440384fff8SJason Evans /* 457ecfc090SJohn Baldwin * Setup per-cpu idle process contexts. The AP's shouldn't be running or 467ecfc090SJohn Baldwin * accessing their idle processes at this point, so don't bother with 477ecfc090SJohn Baldwin * locking. 480384fff8SJason Evans */ 490384fff8SJason Evans static void 500384fff8SJason Evans idle_setup(void *dummy) 510384fff8SJason Evans { 526caa8a15SJohn Baldwin #ifdef SMP 530384fff8SJason Evans struct globaldata *gd; 546caa8a15SJohn Baldwin #endif 556caa8a15SJohn Baldwin struct proc *p; 560384fff8SJason Evans int error; 570384fff8SJason Evans 580384fff8SJason Evans #ifdef SMP 596caa8a15SJohn Baldwin SLIST_FOREACH(gd, &cpuhead, gd_allcpu) { 606caa8a15SJohn Baldwin error = kthread_create(idle_proc, NULL, &p, 616caa8a15SJohn Baldwin RFSTOPPED | RFHIGHPID, "idle: cpu%d", gd->gd_cpuid); 626caa8a15SJohn Baldwin gd->gd_idleproc = p; 636caa8a15SJohn Baldwin if (gd->gd_curproc == NULL) 646caa8a15SJohn Baldwin gd->gd_curproc = p; 650384fff8SJason Evans #else 666caa8a15SJohn Baldwin error = kthread_create(idle_proc, NULL, &p, 670384fff8SJason Evans RFSTOPPED | RFHIGHPID, "idle"); 686caa8a15SJohn Baldwin PCPU_SET(idleproc, p); 690384fff8SJason Evans #endif 700384fff8SJason Evans if (error) 710384fff8SJason Evans panic("idle_setup: kthread_create error %d\n", error); 720384fff8SJason Evans 736caa8a15SJohn Baldwin p->p_flag |= P_NOLOAD; 746caa8a15SJohn Baldwin p->p_stat = SRUN; 756caa8a15SJohn Baldwin #ifdef SMP 760384fff8SJason Evans } 776caa8a15SJohn Baldwin #endif 780384fff8SJason Evans } 790384fff8SJason Evans 800384fff8SJason Evans /* 810384fff8SJason Evans * idle process context 820384fff8SJason Evans */ 830384fff8SJason Evans static void 840384fff8SJason Evans idle_proc(void *dummy) 850384fff8SJason Evans { 863650b375SJohn Baldwin #ifdef DIAGNOSTIC 870384fff8SJason Evans int count; 883650b375SJohn Baldwin #endif 890384fff8SJason Evans 900384fff8SJason Evans for (;;) { 910384fff8SJason Evans mtx_assert(&Giant, MA_NOTOWNED); 920384fff8SJason Evans 933650b375SJohn Baldwin #ifdef DIAGNOSTIC 940384fff8SJason Evans count = 0; 950384fff8SJason Evans 960384fff8SJason Evans while (count >= 0 && procrunnable() == 0) { 973650b375SJohn Baldwin #else 983650b375SJohn Baldwin while (procrunnable() == 0) { 993650b375SJohn Baldwin #endif 1000384fff8SJason Evans /* 1010384fff8SJason Evans * This is a good place to put things to be done in 1020384fff8SJason Evans * the background, including sanity checks. 1030384fff8SJason Evans */ 104bdf3d8b9SMike Smith 1053650b375SJohn Baldwin #ifdef DIAGNOSTIC 1060384fff8SJason Evans if (count++ < 0) 1070384fff8SJason Evans CTR0(KTR_PROC, "idle_proc: timed out waiting" 1080384fff8SJason Evans " for a process"); 1093650b375SJohn Baldwin #endif 1103650b375SJohn Baldwin 111d5a08a60SJake Burkholder #if 0 1123650b375SJohn Baldwin if (vm_page_zero_idle() != 0) 1133650b375SJohn Baldwin continue; 114d5a08a60SJake Burkholder #endif 115bdf3d8b9SMike Smith 116dc13e6dfSJohn Baldwin #ifdef __i386__ 117dc13e6dfSJohn Baldwin cpu_idle(); 118dc13e6dfSJohn Baldwin #endif 1190384fff8SJason Evans } 1200384fff8SJason Evans 1219ed346baSBosko Milekic mtx_lock_spin(&sched_lock); 1227ecfc090SJohn Baldwin curproc->p_stats->p_ru.ru_nvcsw++; 1230384fff8SJason Evans mi_switch(); 1249ed346baSBosko Milekic mtx_unlock_spin(&sched_lock); 1250384fff8SJason Evans } 1260384fff8SJason Evans } 127