From owner-svn-src-stable-8@FreeBSD.ORG Sat Oct 6 14:04:37 2012 Return-Path: Delivered-To: svn-src-stable-8@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 0A3FD106566B; Sat, 6 Oct 2012 14:04:37 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id E7A238FC12; Sat, 6 Oct 2012 14:04:36 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q96E4amF076731; Sat, 6 Oct 2012 14:04:36 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q96E4aFA076728; Sat, 6 Oct 2012 14:04:36 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201210061404.q96E4aFA076728@svn.freebsd.org> From: Alexander Motin Date: Sat, 6 Oct 2012 14:04:36 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r241254 - stable/8/sys/kern X-BeenThere: svn-src-stable-8@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for only the 8-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 06 Oct 2012 14:04:37 -0000 Author: mav Date: Sat Oct 6 14:04:36 2012 New Revision: 241254 URL: http://svn.freebsd.org/changeset/base/241254 Log: MFC r239185, r239196: Some minor tunings/cleanups inspired by bde@ after previous commits: - remove extra dynamic variable initializations; - restore (4BSD) and implement (ULE) hogticks variable setting; - make sched_rr_interval() more tolerant to options; - restore (4BSD) and implement (ULE) kern.sched.quantum sysctl, a more user-friendly wrapper for sched_slice; - tune some sysctl descriptions; - make some style fixes. Modified: stable/8/sys/kern/sched_4bsd.c stable/8/sys/kern/sched_ule.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/kern/ (props changed) Modified: stable/8/sys/kern/sched_4bsd.c ============================================================================== --- stable/8/sys/kern/sched_4bsd.c Sat Oct 6 13:43:56 2012 (r241253) +++ stable/8/sys/kern/sched_4bsd.c Sat Oct 6 14:04:36 2012 (r241254) @@ -119,9 +119,9 @@ struct td_sched { static struct td_sched td_sched0; struct mtx sched_lock; -static int realstathz; /* stathz is sometimes 0 and run off of hz. */ +static int realstathz = 127; /* stathz is sometimes 0 and run off of hz. */ static int sched_tdcnt; /* Total runnable threads in the system. */ -static int sched_slice = 1; /* Thread run time before rescheduling. */ +static int sched_slice = 12; /* Thread run time before rescheduling. */ static void setup_runqs(void); static void schedcpu(void); @@ -183,12 +183,33 @@ setup_runqs(void) runq_init(&runq); } +static int +sysctl_kern_quantum(SYSCTL_HANDLER_ARGS) +{ + int error, new_val, period; + + period = 1000000 / realstathz; + new_val = period * sched_slice; + error = sysctl_handle_int(oidp, &new_val, 0, req); + if (error != 0 || req->newptr == NULL) + return (error); + if (new_val <= 0) + return (EINVAL); + sched_slice = imax(1, (new_val + period / 2) / period); + hogticks = imax(1, (2 * hz * sched_slice + realstathz / 2) / + realstathz); + return (0); +} + SYSCTL_NODE(_kern, OID_AUTO, sched, CTLFLAG_RD, 0, "Scheduler"); SYSCTL_STRING(_kern_sched, OID_AUTO, name, CTLFLAG_RD, "4BSD", 0, "Scheduler name"); +SYSCTL_PROC(_kern_sched, OID_AUTO, quantum, CTLTYPE_INT | CTLFLAG_RW, + NULL, 0, sysctl_kern_quantum, "I", + "Quantum for timeshare threads in microseconds"); SYSCTL_INT(_kern_sched, OID_AUTO, slice, CTLFLAG_RW, &sched_slice, 0, - "Slice size for timeshare threads"); + "Quantum for timeshare threads in stathz ticks"); #ifdef SMP /* Enable forwarding of wakeups to all other cpus */ SYSCTL_NODE(_kern_sched, OID_AUTO, ipiwakeup, CTLFLAG_RD, NULL, "Kernel SMP"); @@ -636,21 +657,15 @@ resetpriority_thread(struct thread *td) static void sched_setup(void *dummy) { - setup_runqs(); - /* - * To avoid divide-by-zero, we set realstathz a dummy value - * in case which sched_clock() called before sched_initticks(). - */ - realstathz = hz; - sched_slice = realstathz / 10; /* ~100ms */ + setup_runqs(); /* Account for thread0. */ sched_load_add(); } /* - * This routine determines the sched_slice after stathz and hz are setup. + * This routine determines time constants after stathz and hz are setup. */ static void sched_initticks(void *dummy) @@ -658,6 +673,8 @@ sched_initticks(void *dummy) realstathz = stathz ? stathz : hz; sched_slice = realstathz / 10; /* ~100ms */ + hogticks = imax(1, (2 * hz * sched_slice + realstathz / 2) / + realstathz); } /* External interfaces start here */ @@ -696,7 +713,7 @@ sched_rr_interval(void) { /* Convert sched_slice from stathz to hz. */ - return (hz / (realstathz / sched_slice)); + return (imax(1, (sched_slice * hz + realstathz / 2) / realstathz)); } /* @@ -731,9 +748,9 @@ sched_clock(struct thread *td) /* * Force a context switch if the current thread has used up a full - * quantum (default quantum is 100ms). + * time slice (default is 100ms). */ - if (!TD_IS_IDLETHREAD(td) && (--ts->ts_slice <= 0)) { + if (!TD_IS_IDLETHREAD(td) && --ts->ts_slice <= 0) { ts->ts_slice = sched_slice; td->td_flags |= TDF_NEEDRESCHED | TDF_SLICEEND; } Modified: stable/8/sys/kern/sched_ule.c ============================================================================== --- stable/8/sys/kern/sched_ule.c Sat Oct 6 13:43:56 2012 (r241253) +++ stable/8/sys/kern/sched_ule.c Sat Oct 6 14:04:36 2012 (r241254) @@ -199,9 +199,9 @@ static struct td_sched td_sched0; * preempt_thresh: Priority threshold for preemption and remote IPIs. */ static int sched_interact = SCHED_INTERACT_THRESH; -static int realstathz; -static int tickincr; -static int sched_slice = 1; +static int realstathz = 127; +static int tickincr = 8 << SCHED_TICK_SHIFT;; +static int sched_slice = 12; #ifdef PREEMPTION #ifdef FULL_PREEMPTION static int preempt_thresh = PRI_MAX_IDLE; @@ -1356,13 +1356,6 @@ sched_setup(void *dummy) #else tdq_setup(tdq); #endif - /* - * To avoid divide-by-zero, we set realstathz a dummy value - * in case which sched_clock() called before sched_initticks(). - */ - realstathz = hz; - sched_slice = (realstathz/10); /* ~100ms */ - tickincr = 1 << SCHED_TICK_SHIFT; /* Add thread0's load since it's running. */ TDQ_LOCK(tdq); @@ -1373,7 +1366,7 @@ sched_setup(void *dummy) } /* - * This routine determines the tickincr after stathz and hz are setup. + * This routine determines time constants after stathz and hz are setup. */ /* ARGSUSED */ static void @@ -1382,7 +1375,9 @@ sched_initticks(void *dummy) int incr; realstathz = stathz ? stathz : hz; - sched_slice = (realstathz/10); /* ~100ms */ + sched_slice = realstathz / 10; /* ~100ms */ + hogticks = imax(1, (2 * hz * sched_slice + realstathz / 2) / + realstathz); /* * tickincr is shifted out by 10 to avoid rounding errors due to @@ -1597,8 +1592,8 @@ int sched_rr_interval(void) { - /* Convert sched_slice to hz */ - return (hz/(realstathz/sched_slice)); + /* Convert sched_slice from stathz to hz. */ + return (imax(1, (sched_slice * hz + realstathz / 2) / realstathz)); } /* @@ -2238,16 +2233,15 @@ sched_clock(struct thread *td) sched_interact_update(td); sched_priority(td); } + /* - * We used up one time slice. - */ - if (--ts->ts_slice > 0) - return; - /* - * We're out of time, force a requeue at userret(). + * Force a context switch if the current thread has used up a full + * time slice (default is 100ms). */ - ts->ts_slice = sched_slice; - td->td_flags |= TDF_NEEDRESCHED | TDF_SLICEEND; + if (!TD_IS_IDLETHREAD(td) && --ts->ts_slice <= 0) { + ts->ts_slice = sched_slice; + td->td_flags |= TDF_NEEDRESCHED | TDF_SLICEEND; + } } /* @@ -2814,21 +2808,44 @@ sysctl_kern_sched_topology_spec(SYSCTL_H } #endif +static int +sysctl_kern_quantum(SYSCTL_HANDLER_ARGS) +{ + int error, new_val, period; + + period = 1000000 / realstathz; + new_val = period * sched_slice; + error = sysctl_handle_int(oidp, &new_val, 0, req); + if (error != 0 || req->newptr == NULL) + return (error); + if (new_val <= 0) + return (EINVAL); + sched_slice = imax(1, (new_val + period / 2) / period); + hogticks = imax(1, (2 * hz * sched_slice + realstathz / 2) / + realstathz); + return (0); +} + SYSCTL_NODE(_kern, OID_AUTO, sched, CTLFLAG_RW, 0, "Scheduler"); SYSCTL_STRING(_kern_sched, OID_AUTO, name, CTLFLAG_RD, "ULE", 0, "Scheduler name"); +SYSCTL_PROC(_kern_sched, OID_AUTO, quantum, CTLTYPE_INT | CTLFLAG_RW, + NULL, 0, sysctl_kern_quantum, "I", + "Quantum for timeshare threads in microseconds"); SYSCTL_INT(_kern_sched, OID_AUTO, slice, CTLFLAG_RW, &sched_slice, 0, - "Slice size for timeshare threads"); + "Quantum for timeshare threads in stathz ticks"); SYSCTL_INT(_kern_sched, OID_AUTO, interact, CTLFLAG_RW, &sched_interact, 0, - "Interactivity score threshold"); -SYSCTL_INT(_kern_sched, OID_AUTO, preempt_thresh, CTLFLAG_RW, &preempt_thresh, - 0,"Min priority for preemption, lower priorities have greater precedence"); -SYSCTL_INT(_kern_sched, OID_AUTO, static_boost, CTLFLAG_RW, &static_boost, - 0,"Controls whether static kernel priorities are assigned to sleeping threads."); -SYSCTL_INT(_kern_sched, OID_AUTO, idlespins, CTLFLAG_RW, &sched_idlespins, - 0,"Number of times idle will spin waiting for new work."); -SYSCTL_INT(_kern_sched, OID_AUTO, idlespinthresh, CTLFLAG_RW, &sched_idlespinthresh, - 0,"Threshold before we will permit idle spinning."); + "Interactivity score threshold"); +SYSCTL_INT(_kern_sched, OID_AUTO, preempt_thresh, CTLFLAG_RW, + &preempt_thresh, 0, + "Maximal (lowest) priority for preemption"); +SYSCTL_INT(_kern_sched, OID_AUTO, static_boost, CTLFLAG_RW, &static_boost, 0, + "Assign static kernel priorities to sleeping threads"); +SYSCTL_INT(_kern_sched, OID_AUTO, idlespins, CTLFLAG_RW, &sched_idlespins, 0, + "Number of times idle thread will spin waiting for new work"); +SYSCTL_INT(_kern_sched, OID_AUTO, idlespinthresh, CTLFLAG_RW, + &sched_idlespinthresh, 0, + "Threshold before we will permit idle thread spinning"); #ifdef SMP SYSCTL_INT(_kern_sched, OID_AUTO, affinity, CTLFLAG_RW, &affinity, 0, "Number of hz ticks to keep thread affinity for"); @@ -2836,15 +2853,13 @@ SYSCTL_INT(_kern_sched, OID_AUTO, balanc "Enables the long-term load balancer"); SYSCTL_INT(_kern_sched, OID_AUTO, balance_interval, CTLFLAG_RW, &balance_interval, 0, - "Average frequency in stathz ticks to run the long-term balancer"); + "Average period in stathz ticks to run the long-term balancer"); SYSCTL_INT(_kern_sched, OID_AUTO, steal_idle, CTLFLAG_RW, &steal_idle, 0, "Attempts to steal work from other cores before idling"); SYSCTL_INT(_kern_sched, OID_AUTO, steal_thresh, CTLFLAG_RW, &steal_thresh, 0, - "Minimum load on remote cpu before we'll steal"); - -/* Retrieve SMP topology */ + "Minimum load on remote CPU before we'll steal"); SYSCTL_PROC(_kern_sched, OID_AUTO, topology_spec, CTLTYPE_STRING | - CTLFLAG_RD, NULL, 0, sysctl_kern_sched_topology_spec, "A", + CTLFLAG_RD, NULL, 0, sysctl_kern_sched_topology_spec, "A", "XML dump of detected CPU topology"); #endif