Second major scheduler patch. This corrects interactive issues that were
authorMatthew Dillon <dillon@dragonflybsd.org>
Tue, 30 Mar 2004 19:14:18 +0000 (19:14 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Tue, 30 Mar 2004 19:14:18 +0000 (19:14 +0000)
commit0a3f9b4712574b03a70559adc293147ac99e6109
treeb93b165d90cc6feb7689f813b0be0ffc5bec9b5c
parentd78bc3183683880396282a30a66c00a6db4794d2
Second major scheduler patch.  This corrects interactive issues that were
introduced in the pipe sf_buf patch.

Split need_resched() into need_user_resched() and need_lwkt_resched().
Userland reschedules are requested when a process is scheduled with a higher
priority then the currently running process, and LWKT reschedules are
requested when a thread is scheduled with a higher priority then the
currently running thread.  As before, these are ASTs, LWKTs are not
preemptively switch while running in the kernel.

Exclusively use the resched wanted flags to determine whether to reschedule
or call lwkt_switch() upon return to user mode.  We were previously also
testing the LWKT run queue for higher priority threads, but this was causing
inefficient scheduler interactions when two processes are doing tightly
bound synchronous IPC (e.g. using PIPEs) because in DragonFly the LWKT
priority of a thread is raised when it enters the kernel, and lowered when
it tries to return to userland.  The wakeups occuring in the pipe code
were causing extra quick-flip thread switches.

Introduce a new tsleep() flag which disables the need_lwkt_resched() call
when the sleeping thread is woken up.   This is used by the PIPE code in
the synchronous direct-write PIPE case to avoid the above problem.

Redocument and revamp the ESTCPU code.  The original changes reduced the
interrupt rate from 100Hz (FBsd-4 and FBsd-5) to 20Hz, but did not compensate
for the slower ramp-up time.  This commit introduces a 'virtual' ESTCPU
frequency which compensates without us having to bump up the actual systimer
interrupt rate.

Redo the P_CURPROC methodology, which is used by the userland scheduler
to manage processes running in userland.  Create a globaldata->gd_uschedcp
process pointer which represents the current running-in-userland (or about
to be running in userland) process, and carefully recode acquire_curproc()
to allow this gd_uschedcp designation to be stolen from other threads trying
to return to userland without having to request a reschedule (which would
have to switch back to those threads to release the designation).  This
reduces the number of unnecessary context switches that occur due to
scheduler interactions.  Also note that this specifically solves the case
where there might be several threads running in the kernel which are trying
to return to userland at the same time.  A heuristic check against gd_upri
is used to select the correct thread for schedling to userland 'most of the
time'.  When the correct thread is not selected, we fall back to the old
behavior of forcing a reschedule.

Add debugging sysctl variables to better track userland scheduler efficiency.

With these changes pipe statistics are further improved.  Though some
scheduling aberrations still exist(1), the previous scheduler had totally
broken interactive processes and this one does not.

BLKSIZE BEFORE NEWPIPE NOW     Tests on AMD64
MBytes/s MBytes/s MBytes/s 3200+ FN85MB
    (64KB L1, 1MB L2)
256KB 1900 2200 2250
 64KB 1800 2200 2250
 32KB - - 3300
 16KB 1650 2500-3000 2600-3200
  8KB 1400 2300 2000-2400(1)
  4KB 1300 1400-1500 1500-1700
28 files changed:
sys/amd64/amd64/genassym.c
sys/cpu/i386/include/cpu.h
sys/emulation/posix4/ksched.c
sys/i386/i386/genassym.c
sys/i386/i386/sys_machdep.c
sys/i386/i386/trap.c
sys/i386/include/cpu.h
sys/i386/isa/intr_machdep.c
sys/i386/isa/ipl.s
sys/kern/init_main.c
sys/kern/kern_clock.c
sys/kern/kern_exit.c
sys/kern/kern_fork.c
sys/kern/kern_sched.c
sys/kern/kern_switch.c
sys/kern/kern_synch.c
sys/kern/lwkt_thread.c
sys/kern/sys_pipe.c
sys/platform/pc32/i386/genassym.c
sys/platform/pc32/i386/sys_machdep.c
sys/platform/pc32/i386/trap.c
sys/platform/pc32/isa/intr_machdep.c
sys/platform/pc32/isa/ipl.s
sys/platform/vkernel/i386/genassym.c
sys/sys/globaldata.h
sys/sys/param.h
sys/sys/proc.h
sys/sys/thread.h