From owner-freebsd-bugs@FreeBSD.ORG Fri Jul 21 19:00:42 2006 Return-Path: X-Original-To: freebsd-bugs@hub.freebsd.org Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 6F4FB16A594 for ; Fri, 21 Jul 2006 19:00:42 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 62D7543D5C for ; Fri, 21 Jul 2006 19:00:32 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id k6LJ0WL7064661 for ; Fri, 21 Jul 2006 19:00:32 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id k6LJ0W70064659; Fri, 21 Jul 2006 19:00:32 GMT (envelope-from gnats) Resent-Date: Fri, 21 Jul 2006 19:00:32 GMT Resent-Message-Id: <200607211900.k6LJ0W70064659@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Gareth McCaughan Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 363E516A4E0 for ; 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 ; 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 ) 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 To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Cc: Subject: kern/100683: syscons screen savers can eat up to 75% of CPU X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Gareth McCaughan List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 21 Jul 2006 19:00:42 -0000 >Number: 100683 >Category: kern >Synopsis: syscons screen savers can eat up to 75% of CPU >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Fri Jul 21 19:00:31 GMT 2006 >Closed-Date: >Last-Modified: >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: >Unformatted: