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/proc.h> 120384fff8SJason Evans #include <sys/kernel.h> 130384fff8SJason Evans #include <sys/ktr.h> 140384fff8SJason Evans #include <sys/signalvar.h> 150384fff8SJason Evans #include <sys/resourcevar.h> 160384fff8SJason Evans #include <sys/vmmeter.h> 170384fff8SJason Evans #include <sys/sysctl.h> 180384fff8SJason Evans #include <sys/unistd.h> 191931cf94SJohn Baldwin #include <sys/ipl.h> 200384fff8SJason Evans #include <sys/kthread.h> 2135e0e5b3SJohn Baldwin #include <sys/mutex.h> 220384fff8SJason Evans #include <sys/queue.h> 23bdf3d8b9SMike Smith #include <sys/eventhandler.h> 240384fff8SJason Evans #include <vm/vm.h> 250384fff8SJason Evans #include <vm/vm_extern.h> 260384fff8SJason Evans #ifdef KTRACE 270384fff8SJason Evans #include <sys/uio.h> 280384fff8SJason Evans #include <sys/ktrace.h> 290384fff8SJason Evans #endif 300384fff8SJason Evans 310384fff8SJason Evans #include <machine/cpu.h> 323650b375SJohn Baldwin #include <machine/md_var.h> 330384fff8SJason Evans #include <machine/smp.h> 340384fff8SJason Evans 350384fff8SJason Evans #include <machine/globaldata.h> 360384fff8SJason Evans #include <machine/globals.h> 370384fff8SJason Evans 380384fff8SJason Evans static void idle_setup(void *dummy); 390384fff8SJason Evans SYSINIT(idle_setup, SI_SUB_SCHED_IDLE, SI_ORDER_FIRST, idle_setup, NULL) 400384fff8SJason Evans 410384fff8SJason Evans static void idle_proc(void *dummy); 420384fff8SJason Evans 430384fff8SJason Evans /* 447ecfc090SJohn Baldwin * Setup per-cpu idle process contexts. The AP's shouldn't be running or 457ecfc090SJohn Baldwin * accessing their idle processes at this point, so don't bother with 467ecfc090SJohn Baldwin * locking. 470384fff8SJason Evans */ 480384fff8SJason Evans static void 490384fff8SJason Evans idle_setup(void *dummy) 500384fff8SJason Evans { 510384fff8SJason Evans struct globaldata *gd; 520384fff8SJason Evans int error; 530384fff8SJason Evans 540384fff8SJason Evans SLIST_FOREACH(gd, &cpuhead, gd_allcpu) { 550384fff8SJason Evans #ifdef SMP 560384fff8SJason Evans error = kthread_create(idle_proc, NULL, &gd->gd_idleproc, 570384fff8SJason Evans RFSTOPPED|RFHIGHPID, "idle: cpu%d", 580384fff8SJason Evans gd->gd_cpuid); 590384fff8SJason Evans #else 600384fff8SJason Evans error = kthread_create(idle_proc, NULL, &gd->gd_idleproc, 610384fff8SJason Evans RFSTOPPED|RFHIGHPID, "idle"); 620384fff8SJason Evans #endif 630384fff8SJason Evans if (error) 640384fff8SJason Evans panic("idle_setup: kthread_create error %d\n", error); 650384fff8SJason Evans 667ab37af1SJohn Baldwin gd->gd_idleproc->p_flag |= P_NOLOAD; 67f6a0af80SJohn Baldwin gd->gd_idleproc->p_stat = SRUN; 687ecfc090SJohn Baldwin if (gd->gd_curproc == NULL) 697ecfc090SJohn Baldwin gd->gd_curproc = gd->gd_idleproc; 700384fff8SJason Evans } 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 820384fff8SJason Evans 830384fff8SJason Evans for (;;) { 840384fff8SJason Evans mtx_assert(&Giant, MA_NOTOWNED); 850384fff8SJason Evans 863650b375SJohn Baldwin #ifdef DIAGNOSTIC 870384fff8SJason Evans count = 0; 880384fff8SJason Evans 890384fff8SJason Evans while (count >= 0 && procrunnable() == 0) { 903650b375SJohn Baldwin #else 913650b375SJohn Baldwin while (procrunnable() == 0) { 923650b375SJohn Baldwin #endif 930384fff8SJason Evans /* 940384fff8SJason Evans * This is a good place to put things to be done in 950384fff8SJason Evans * the background, including sanity checks. 960384fff8SJason Evans */ 97bdf3d8b9SMike Smith 983650b375SJohn Baldwin #ifdef DIAGNOSTIC 990384fff8SJason Evans if (count++ < 0) 1000384fff8SJason Evans CTR0(KTR_PROC, "idle_proc: timed out waiting" 1010384fff8SJason Evans " for a process"); 1023650b375SJohn Baldwin #endif 1033650b375SJohn Baldwin 1043650b375SJohn Baldwin if (vm_page_zero_idle() != 0) 1053650b375SJohn Baldwin continue; 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