Module Name: src Committed By: martin Date: Sun May 6 09:53:27 UTC 2018
Modified Files: src/sys/kern [netbsd-7]: kern_runq.c Log Message: Pull up following revision(s) (requested by mlelstv in ticket #1603): sys/kern/kern_runq.c: revision 1.46 When balancing threads over multiple CPUs, use fixpoint arithmetic for averages. Otherwise the decisions can be heavily biased by rounding errors. Add sysctl kern.sched_average_weight to change the weight of historical data, the default is 50%. To generate a diff of this commit: cvs rdiff -u -r1.43 -r1.43.2.1 src/sys/kern/kern_runq.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/kern_runq.c diff -u src/sys/kern/kern_runq.c:1.43 src/sys/kern/kern_runq.c:1.43.2.1 --- src/sys/kern/kern_runq.c:1.43 Sun Aug 3 19:14:24 2014 +++ src/sys/kern/kern_runq.c Sun May 6 09:53:27 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_runq.c,v 1.43 2014/08/03 19:14:24 wiz Exp $ */ +/* $NetBSD: kern_runq.c,v 1.43.2.1 2018/05/06 09:53:27 martin Exp $ */ /* * Copyright (c) 2007, 2008 Mindaugas Rasiukevicius <rmind at NetBSD org> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_runq.c,v 1.43 2014/08/03 19:14:24 wiz Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_runq.c,v 1.43.2.1 2018/05/06 09:53:27 martin Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -78,7 +78,7 @@ typedef struct { uint32_t r_bitmap[PRI_COUNT >> BITMAP_SHIFT]; /* Counters */ u_int r_count; /* Count of the threads */ - u_int r_avgcount; /* Average count of threads */ + u_int r_avgcount; /* Average count of threads (* 256) */ u_int r_mcount; /* Count of migratable threads */ /* Runqueues */ queue_t r_rt_queue[PRI_RT_COUNT]; @@ -116,6 +116,7 @@ int sched_kpreempt_pri = 1000; static u_int cacheht_time; /* Cache hotness time */ static u_int min_catch; /* Minimal LWP count for catching */ static u_int balance_period; /* Balance period */ +static u_int average_weight; /* Weight old thread count average */ static struct cpu_info *worker_ci; /* Victim CPU */ #ifdef MULTIPROCESSOR static struct callout balance_ch; /* Callout of balancer */ @@ -132,6 +133,8 @@ runq_init(void) /* Minimal count of LWPs for catching */ min_catch = 1; + /* Weight of historical average */ + average_weight = 50; /* 0.5 */ /* Initialize balancing callout and run it */ #ifdef MULTIPROCESSOR @@ -519,6 +522,10 @@ sched_balance(void *nocallout) runqueue_t *ci_rq; CPU_INFO_ITERATOR cii; u_int highest; + u_int weight; + + /* sanitize sysctl value */ + weight = MIN(average_weight, 100); hci = curcpu(); highest = 0; @@ -527,8 +534,15 @@ sched_balance(void *nocallout) for (CPU_INFO_FOREACH(cii, ci)) { ci_rq = ci->ci_schedstate.spc_sched_info; - /* Average count of the threads */ - ci_rq->r_avgcount = (ci_rq->r_avgcount + ci_rq->r_mcount) >> 1; + /* + * Average count of the threads + * + * The average is computed as a fixpoint number with + * 8 fractional bits. + */ + ci_rq->r_avgcount = ( + weight * ci_rq->r_avgcount + (100 - weight) * 256 * ci_rq->r_mcount + ) / 100; /* Look for CPU with the highest average */ if (ci_rq->r_avgcount > highest) { @@ -831,6 +845,12 @@ SYSCTL_SETUP(sysctl_sched_setup, "sysctl CTL_CREATE, CTL_EOL); sysctl_createv(clog, 0, &node, NULL, CTLFLAG_PERMANENT | CTLFLAG_READWRITE, + CTLTYPE_INT, "average_weight", + SYSCTL_DESCR("Thread count averaging weight (in percent)"), + NULL, 0, &average_weight, 0, + CTL_CREATE, CTL_EOL); + sysctl_createv(clog, 0, &node, NULL, + CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, "min_catch", SYSCTL_DESCR("Minimal count of threads for catching"), NULL, 0, &min_catch, 0,