kern/100683: syscons screen savers can eat up to 75% of CPU
Gareth McCaughan
gmccaughan at synaptics-uk.com
Fri Jul 21 19:00:42 UTC 2006
>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:
More information about the freebsd-bugs
mailing list