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