From GMcCaughan@synaptics-uk.com  Fri Jul 21 18:52:10 2006
Return-Path: <GMcCaughan@synaptics-uk.com>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 363E516A4E0
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 21 Jul 2006 18:52:10 +0000 (UTC)
	(envelope-from GMcCaughan@synaptics-uk.com)
Received: from mx2.synaptics-uk.com (mx2.synaptics-uk.com [194.203.111.209])
	by mx1.FreeBSD.org (Postfix) with ESMTP id D12BE43D64
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 21 Jul 2006 18:51:57 +0000 (GMT)
	(envelope-from GMcCaughan@synaptics-uk.com)
Received: from firewall.synaptics-uk.com ([194.203.111.212] helo=ukexchange2k.synaptics-inc.local)
	by mx2.synaptics-uk.com with esmtp (Exim 4.62)
	(envelope-from <GMcCaughan@synaptics-uk.com>)
	id 1G406O-0008WD-Ab
	for FreeBSD-gnats-submit@freebsd.org; Fri, 21 Jul 2006 19:51:56 +0100
Received: from dogbert.synaptics-uk.com ([172.20.11.5]) by ukexchange2k.synaptics-inc.local with Microsoft SMTPSVC(5.0.2195.6713);
	 Fri, 21 Jul 2006 19:51:51 +0100
Received: by dogbert.synaptics-uk.com (Postfix, from userid 109)
	id 0F67C22E26; Fri, 21 Jul 2006 19:51:51 +0100 (BST)
Message-Id: <20060721185151.0F67C22E26@dogbert.synaptics-uk.com>
Date: Fri, 21 Jul 2006 19:51:51 +0100 (BST)
From: Gareth McCaughan <gareth.mccaughan@pobox.com>
Reply-To: gareth.mccaughan@pobox.com
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: syscons screen savers can eat up to 75% of CPU
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         100683
>Category:       kern
>Synopsis:       [syscons] [patch] syscons screen savers can eat up to 75% of CPU
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    philip
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Jul 21 19:00:31 GMT 2006
>Closed-Date:    Wed Feb 21 12:27:50 GMT 2007
>Last-Modified:  Wed Feb 21 12:30:16 GMT 2007
>Originator:     Gareth McCaughan
>Release:        FreeBSD 6.1-STABLE i386
>Organization:
International Pedant Conspiracy
>Environment:
	System: FreeBSD 6-STABLE as of 2006-07-21
>Description:
	The "fire", "logo", "rain" and "warp" syscons screen savers
	make many calls to set_origin on each update. On some systems
	each such call involves two very slow BIOS calls, which can
	result in lots of CPU time being wasted. (On one of my machines,
	the figure for "warp" is about 75%.) The most visible symptoms
	are a very slow-running machine, and a "ps" entry for a
	kernel ithread with a name like "[swi4: clock sio]" taking up
	a lot of cycles.
>How-To-Repeat:
	Have a machine on which the graphics card is handled using VESA VBE
	and int 10h 4f/05 (bank switch) is slow.
	Choose one of the savers listed above as your syscons screen saver,
	either by setting "saver" in rc.conf or by kldload-ing it. Wait for
	the screen saver to kick in. Observe, remotely, that everything
	runs slower and that the "clock sio" ithread is eating CPU.
>Fix:
	Apply the following patch (unidiff in /usr/src/sys/dev/syscons).
	It reduces the number of expensive set_origin calls in those
	savers by not bothering to make them when the origin isn't
	actually changing. It *doesn't* (1) make vesa_set_origin always
	perform this check or (2) monitor all syscons screen savers and
	take any sort of remedial action if they use too much CPU; #1
	might be worth doing instead, and #2 might be worth doing as well.

---------- patch begins ----------
diff -u -r fire.ORIG/fire_saver.c fire/fire_saver.c
--- fire.ORIG/fire_saver.c	Fri Jul 21 18:20:05 2006
+++ fire/fire_saver.c	Fri Jul 21 19:12:23 2006
@@ -52,6 +52,8 @@
 #define GREEN(n)	 ((n) * 3 + 1)
 #define BLUE(n)		 ((n) * 3 + 2)
 
+#define SET_ORIGIN(adp, o) do { int oo=o; if (oo != last_origin) set_origin(adp, last_origin=oo); } while (0)
+
 static u_char		*buf;
 static u_char		*vid;
 static int		 banksize, scrmode, bpsl, scrw, scrh;
@@ -63,6 +65,7 @@
 {
 	int x, y;
 	int o, p;
+	int last_origin = -1;
 
 	/* make a new bottom line */
 	for (x = 0, y = scrh; x < scrw; x++)
@@ -87,12 +90,12 @@
 			p -= banksize;
 			o += banksize;
 		}
-		set_origin(adp, o);
+		SET_ORIGIN(adp, o);
 		if (p + scrw < banksize) {
 			bcopy(buf + y * scrw, vid + p, scrw);
 		} else {
 			bcopy(buf + y * scrw, vid + p, banksize - p);
-			set_origin(adp, o + banksize);
+			SET_ORIGIN(adp, o + banksize);
 			bcopy(buf + y * scrw + (banksize - p), vid,
 			      scrw - (banksize - p));
 			p -= banksize;
diff -u -r logo.ORIG/logo_saver.c logo/logo_saver.c
--- logo.ORIG/logo_saver.c	Fri Jul 21 18:20:10 2006
+++ logo/logo_saver.c	Fri Jul 21 19:12:33 2006
@@ -42,6 +42,8 @@
 
 #define SAVER_NAME	 "logo_saver"
 
+#define SET_ORIGIN(adp, o) do { int oo=o; if (oo != last_origin) set_origin(adp, last_origin=oo); } while (0)
+
 extern unsigned int	 logo_w;
 extern unsigned int	 logo_h;
 extern unsigned char	 logo_pal[];
@@ -56,10 +58,11 @@
 logo_blit(video_adapter_t *adp, int x, int y)
 {
 	int d, l, o, p;
+	int last_origin = -1;
 	
 	for (o = 0, p = y * bpsl + x; p > banksize; p -= banksize)
 		o += banksize;
-	set_origin(adp, o);
+	SET_ORIGIN(adp, o);
 	
 	for (d = 0; d < logo_img_size; d += logo_w) {
 		if (p + logo_w < banksize) {
@@ -68,12 +71,12 @@
 		} else if (p < banksize) {
 			l = banksize - p;
 			bcopy(logo_img + d, vid + p, l);
-			set_origin(adp, (o += banksize));
+			SET_ORIGIN(adp, (o += banksize));
 			bcopy(logo_img + d + l, vid, logo_w - l);
 			p += bpsl - banksize;
 		} else {
 			p -= banksize;
-			set_origin(adp, (o += banksize));
+			SET_ORIGIN(adp, (o += banksize));
 			bcopy(logo_img + d, vid + p, logo_w);
 			p += bpsl;
 		}
diff -u -r rain.ORIG/rain_saver.c rain/rain_saver.c
--- rain.ORIG/rain_saver.c	Fri Jul 21 18:20:13 2006
+++ rain/rain_saver.c	Fri Jul 21 19:12:28 2006
@@ -51,6 +51,8 @@
 #define GREEN(n)	 ((n) * 3 + 1)
 #define BLUE(n)		 ((n) * 3 + 2)
 
+#define SET_ORIGIN(adp, o) do { int oo=o; if (oo != last_origin) set_origin(adp, last_origin=oo); } while (0)
+
 static u_char		*vid;
 static int		 banksize, scrmode, bpsl, scrw, scrh;
 static u_char		 rain_pal[768];
@@ -73,6 +75,7 @@
 {
 	int i, j, o, p, pl;
 	u_char temp;
+	int last_origin = -1;
 
 	if (blank) {
 		/* switch to graphics mode */
@@ -87,18 +90,18 @@
 			bpsl = adp->va_line_width;
 			splx(pl);
 			for (i = 0; i < bpsl*scrh; i += banksize) {
-				set_origin(adp, i);
+				SET_ORIGIN(adp, i);
 				if ((bpsl * scrh - i) < banksize)
 					bzero(vid, bpsl * scrh - i);
 				else
 					bzero(vid, banksize);
 			}
-			set_origin(adp, 0);
+			SET_ORIGIN(adp, 0);
 			for (i = 0, o = 0, p = 0; i < scrw; i += 2, p += 2) {
 				if (p > banksize) {
 					p -= banksize;
 					o += banksize;
-					set_origin(adp, o);
+					SET_ORIGIN(adp, o);
 				}
 				vid[p] = 1 + (random() % MAX);
 			}
@@ -109,12 +112,12 @@
 					p -= banksize;
 					o += banksize;
 				}
-				set_origin(adp, o);
+				SET_ORIGIN(adp, o);
 				temp = (vid[p] < MAX) ? 1 + vid[p] : 1;
 				if (p + bpsl < banksize) {
 					vid[p + bpsl] = temp;
 				} else {
-					set_origin(adp, o + banksize);
+					SET_ORIGIN(adp, o + banksize);
 					vid[p + bpsl - banksize] = temp;
 				}
 			  }
diff -u -r warp.ORIG/warp_saver.c warp/warp_saver.c
--- warp.ORIG/warp_saver.c	Fri Jul 21 18:20:17 2006
+++ warp/warp_saver.c	Fri Jul 21 19:12:17 2006
@@ -44,6 +44,8 @@
 #define SPP		 15
 #define STARS		 (SPP * (1 + 2 + 4 + 8))
 
+#define SET_ORIGIN(adp, o) do { int oo=o; if (oo != last_origin) set_origin(adp, last_origin=oo); } while (0)
+
 static u_char		*vid;
 static int		 banksize, scrmode, bpsl, scrw, scrh;
 static int		 blanked;
@@ -61,6 +63,7 @@
 warp_update(video_adapter_t *adp)
 {
 	int i, j, k, n, o, p;
+	int last_origin = -1;
 
 	for (i = 1, k = 0, n = SPP*8; i < 5; i++, n /= 2) {
 		for (j = 0; j < n; j++, k++) {
@@ -70,7 +73,7 @@
 				p -= banksize;
 				o += banksize;
 			}
-			set_origin(adp, o);
+			SET_ORIGIN(adp, o);
 			vid[p] = 0;
 			star[k] += i;
 			if (star[k] > scrw*scrh)
@@ -81,7 +84,7 @@
 				p -= banksize;
 				o += banksize;
 			}
-			set_origin(adp, o);
+			SET_ORIGIN(adp, o);
 			vid[p] = i;
 		}
 	}
---------- patch ends ----------
>Release-Note:
>Audit-Trail:

From: Gareth McCaughan <gareth.mccaughan@pobox.com>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/100683: [syscons] [patch] syscons screen savers can eat up to 75% of CPU
Date: Thu, 7 Dec 2006 13:49:42 +0000

 (Apologies if I just submitted an empty followup; typo.)
 
 It's getting on for 6 months since this was submitted.
 It appears to be being entirely ignored.
 
 Is there anything I, as submitter and patch-writer, can
 do to help get it sorted? For instance, if the patch I
 supplied is considered unsatisfactory in some way then
 I can try to provide a better one. Or is the problem
 simply that the project doesn't have the resources to
 pay any attention to non-critical bugs? (Fair enough
 if so, I guess.)

From: Gareth McCaughan <gareth.mccaughan@pobox.com>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/100683: [syscons] [patch] syscons screen savers can eat up to 75% of CPU
Date: Thu, 7 Dec 2006 19:28:08 +0000

 Incidentally: the e-mail address in the original submission no longer works;
 my former employer is closing its office in the UK and I am now working
 for someone else. Please use gareth.mccaughan@pobox.com instead. Thanks!

 [linimon note: the From and Reply-To seem to be the @pobox.com one]
Responsible-Changed-From-To: freebsd-bugs->philip 
Responsible-Changed-By: philip 
Responsible-Changed-When: Fri Feb 16 12:57:55 UTC 2007 
Responsible-Changed-Why:  
I'll take it. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=100683 
State-Changed-From-To: open->closed 
State-Changed-By: philip 
State-Changed-When: Wed Feb 21 12:27:49 UTC 2007 
State-Changed-Why:  
Committed, with minor changes. Thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=100683 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/100683: commit references a PR
Date: Wed, 21 Feb 2007 12:27:20 +0000 (UTC)

 philip      2007-02-21 12:27:12 UTC
 
   FreeBSD src repository
 
   Modified files:
     sys/dev/syscons/fire fire_saver.c 
     sys/dev/syscons/logo logo_saver.c 
     sys/dev/syscons/rain rain_saver.c 
     sys/dev/syscons/warp warp_saver.c 
   Log:
   Optimize set_origin() use in some screensavers to stop them eating
   cpu power when the origin hasn't changed.
   
   PR:             kern/100683
   Submitted by:   Gareth McCaughan <gareth -dot- mccaughan -at- pobox.com>
   MFC after:      3 days
   
   Revision  Changes    Path
   1.11      +9 -2      src/sys/dev/syscons/fire/fire_saver.c
   1.13      +10 -3     src/sys/dev/syscons/logo/logo_saver.c
   1.13      +12 -5     src/sys/dev/syscons/rain/rain_saver.c
   1.14      +9 -2      src/sys/dev/syscons/warp/warp_saver.c
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 
>Unformatted:
