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,

Reply via email to