Index: sys/kern/kern_runq.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_runq.c,v retrieving revision 1.45 diff -p -u -r1.45 kern_runq.c --- sys/kern/kern_runq.c 7 Jul 2016 06:55:43 -0000 1.45 +++ sys/kern/kern_runq.c 27 Nov 2016 07:54:03 -0000 @@ -80,7 +80,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]; @@ -118,6 +118,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 */ @@ -138,6 +139,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 @@ -525,6 +528,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; @@ -533,8 +540,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) { @@ -840,6 +854,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,