From b698380f33ef8d2ea0a8836ba696ccd7ec4e9f08 Mon Sep 17 00:00:00 2001 From: Bruce Evans Date: Sun, 9 Nov 2003 13:45:54 +0000 Subject: Quick fix for scaling of statclock ticks in the SMP case. As explained in the log message for kern_sched.c 1.83 (which should have been repo-copied to preserve history for this file), the (4BSD) scheduler algorithm only works right if stathz is nearly 128 Hz. The old commit lock said 64 Hz; the scheduler actually wants nearly 16 Hz but there was a scale factor of 4 to give the requirement of 64 Hz, and rev.1.83 changed the scale factor so that the requirement became 128 Hz. The change of the scale factor was incomplete in the SMP case. Then scheduling ticks are provided by smp_ncpu CPUs, and the scheduler cannot tell the difference between this and 1 CPU providing scheduling ticks smp_ncpu times faster, so we need another scale factor of smp_ncp or an algorithm change. This quick fix uses the scale factor without even trying to optimize the runtime divisions required for this as is done for the other scale factor. The main algorithmic problem is the clamp on the scheduling tick counts. This was 295; it is now approximately 295 * smp_ncpu. When the limit is reached, threads get free timeslices and scheduling becomes very unfair to the threads that don't hit the limit. The limit can be reached and maintained in the worst case if the load average is larger than (limit / effective_stathz - 1) / 2 = 0.65 now (was just 0.08 with 2 CPUs before this change), so there are algorithmic problems even for a load average of 1. Fortunately, the worst case isn't common enough for the problem to be very noticeable (it is mainly for niced CPU hogs competing with less nice CPU hogs). --- sys/kern/sched_4bsd.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sys/kern/sched_4bsd.c') diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c index be4b16ae5d74..bfde41e2c1da 100644 --- a/sys/kern/sched_4bsd.c +++ b/sys/kern/sched_4bsd.c @@ -59,7 +59,11 @@ __FBSDID("$FreeBSD$"); #define ESTCPULIM(e) \ min((e), INVERSE_ESTCPU_WEIGHT * (NICE_WEIGHT * (PRIO_MAX - PRIO_MIN) - \ RQ_PPQ) + INVERSE_ESTCPU_WEIGHT - 1) +#ifdef SMP +#define INVERSE_ESTCPU_WEIGHT (8 * smp_cpus) +#else #define INVERSE_ESTCPU_WEIGHT 8 /* 1 / (priorities per estcpu level). */ +#endif #define NICE_WEIGHT 1 /* Priorities per nice level. */ struct ke_sched { -- cgit v1.2.3