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> 210384fff8SJason Evans #ifdef KTRACE 220384fff8SJason Evans #include <sys/uio.h> 230384fff8SJason Evans #include <sys/ktrace.h> 240384fff8SJason Evans #endif 250384fff8SJason Evans 260384fff8SJason Evans static void idle_setup(void *dummy); 270384fff8SJason Evans SYSINIT(idle_setup, SI_SUB_SCHED_IDLE, SI_ORDER_FIRST, idle_setup, NULL) 280384fff8SJason Evans 290384fff8SJason Evans static void idle_proc(void *dummy); 300384fff8SJason Evans 310384fff8SJason Evans /* 327ecfc090SJohn Baldwin * Setup per-cpu idle process contexts. The AP's shouldn't be running or 337ecfc090SJohn Baldwin * accessing their idle processes at this point, so don't bother with 347ecfc090SJohn Baldwin * locking. 350384fff8SJason Evans */ 360384fff8SJason Evans static void 370384fff8SJason Evans idle_setup(void *dummy) 380384fff8SJason Evans { 396caa8a15SJohn Baldwin #ifdef SMP 400bbc8826SJohn Baldwin struct pcpu *pc; 416caa8a15SJohn Baldwin #endif 426caa8a15SJohn Baldwin struct proc *p; 43e602ba25SJulian Elischer struct thread *td; 440384fff8SJason Evans int error; 450384fff8SJason Evans 460384fff8SJason Evans #ifdef SMP 470bbc8826SJohn Baldwin SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { 486caa8a15SJohn Baldwin error = kthread_create(idle_proc, NULL, &p, 490bbc8826SJohn Baldwin RFSTOPPED | RFHIGHPID, "idle: cpu%d", pc->pc_cpuid); 50079b7badSJulian Elischer pc->pc_idlethread = FIRST_THREAD_IN_PROC(p); 517e1f6dfeSJohn Baldwin if (pc->pc_curthread == NULL) { 520bbc8826SJohn Baldwin pc->pc_curthread = pc->pc_idlethread; 537e1f6dfeSJohn Baldwin pc->pc_idlethread->td_critnest = 0; 547e1f6dfeSJohn Baldwin } 550384fff8SJason Evans #else 566caa8a15SJohn Baldwin error = kthread_create(idle_proc, NULL, &p, 570384fff8SJason Evans RFSTOPPED | RFHIGHPID, "idle"); 58079b7badSJulian Elischer PCPU_SET(idlethread, FIRST_THREAD_IN_PROC(p)); 590384fff8SJason Evans #endif 600384fff8SJason Evans if (error) 610384fff8SJason Evans panic("idle_setup: kthread_create error %d\n", error); 620384fff8SJason Evans 636caa8a15SJohn Baldwin p->p_flag |= P_NOLOAD; 64e602ba25SJulian Elischer td = FIRST_THREAD_IN_PROC(p); 65e602ba25SJulian Elischer td->td_state = TDS_RUNQ; 66e602ba25SJulian Elischer td->td_kse->ke_state = KES_ONRUNQ; 67e602ba25SJulian Elischer td->td_kse->ke_flags |= KEF_IDLEKSE; 686caa8a15SJohn Baldwin #ifdef SMP 690384fff8SJason Evans } 706caa8a15SJohn Baldwin #endif 710384fff8SJason Evans } 720384fff8SJason Evans 730384fff8SJason Evans /* 740384fff8SJason Evans * idle process context 750384fff8SJason Evans */ 760384fff8SJason Evans static void 770384fff8SJason Evans idle_proc(void *dummy) 780384fff8SJason Evans { 793650b375SJohn Baldwin #ifdef DIAGNOSTIC 800384fff8SJason Evans int count; 813650b375SJohn Baldwin #endif 82e602ba25SJulian Elischer struct thread *td; 83e602ba25SJulian Elischer struct proc *p; 840384fff8SJason Evans 85e602ba25SJulian Elischer td = curthread; 86e602ba25SJulian Elischer p = td->td_proc; 87e602ba25SJulian Elischer td->td_state = TDS_RUNNING; 88e602ba25SJulian Elischer td->td_kse->ke_state = KES_RUNNING; 890384fff8SJason Evans for (;;) { 900384fff8SJason Evans mtx_assert(&Giant, MA_NOTOWNED); 910384fff8SJason Evans 923650b375SJohn Baldwin #ifdef DIAGNOSTIC 930384fff8SJason Evans count = 0; 940384fff8SJason Evans 95e602ba25SJulian Elischer while (count >= 0 && kserunnable() == 0) { 963650b375SJohn Baldwin #else 97e602ba25SJulian Elischer while (kserunnable() == 0) { 983650b375SJohn Baldwin #endif 990384fff8SJason Evans /* 1000384fff8SJason Evans * This is a good place to put things to be done in 1010384fff8SJason Evans * the background, including sanity checks. 1020384fff8SJason Evans */ 103bdf3d8b9SMike Smith 1043650b375SJohn Baldwin #ifdef DIAGNOSTIC 1050384fff8SJason Evans if (count++ < 0) 1060384fff8SJason Evans CTR0(KTR_PROC, "idle_proc: timed out waiting" 1070384fff8SJason Evans " for a process"); 1083650b375SJohn Baldwin #endif 1093650b375SJohn Baldwin 110dc13e6dfSJohn Baldwin #ifdef __i386__ 111dc13e6dfSJohn Baldwin cpu_idle(); 112dc13e6dfSJohn Baldwin #endif 1130384fff8SJason Evans } 1140384fff8SJason Evans 1159ed346baSBosko Milekic mtx_lock_spin(&sched_lock); 116e602ba25SJulian Elischer p->p_stats->p_ru.ru_nvcsw++; 1170384fff8SJason Evans mi_switch(); 118e602ba25SJulian Elischer td->td_kse->ke_state = KES_RUNNING; 1199ed346baSBosko Milekic mtx_unlock_spin(&sched_lock); 1200384fff8SJason Evans } 1210384fff8SJason Evans } 122