NetBSD Problem Report #59361
From www@netbsd.org Sat Apr 26 16:34:53 2025
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
client-signature RSA-PSS (2048 bits) client-digest SHA256)
(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
by mollari.NetBSD.org (Postfix) with ESMTPS id CD8721A923C
for <gnats-bugs@gnats.NetBSD.org>; Sat, 26 Apr 2025 16:34:52 +0000 (UTC)
Message-Id: <20250426163451.94F421A923E@mollari.NetBSD.org>
Date: Sat, 26 Apr 2025 16:34:51 +0000 (UTC)
From: campbell+netbsd@mumble.net
Reply-To: campbell+netbsd@mumble.net
To: gnats-bugs@NetBSD.org
Subject: paging up in less(1) under qemu vga console is slow
X-Send-Pr-Version: www-1.0
>Number: 59361
>Category: port-amd64
>Synopsis: paging up in less(1) under qemu vga console is slow
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: port-amd64-maintainer
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Apr 26 16:35:00 +0000 2025
>Last-Modified: Mon Oct 27 00:00:01 +0000 2025
>Originator: Taylor R Campbell
>Release: current
>Organization:
The Slow386BSD Emulation
>Environment:
>Description:
Paging _down_ in less(1) under qemu vga console is reasonably quick. Not instantaneous -- I still see a flicker sometimes -- but quick enough.
Paging _up_ in less(1) under qemu vga console is excruciatingly slow, takes multiple seconds to go a single page in a 25x80 display.
>How-To-Repeat:
1. run NetBSD/amd64 under qemu-system-x86_64
2. dmesg | less, or whatever
3. hit SPC to page down, hit b to page up
>Fix:
Yes, please!
Someone should alert the resident graphics expert.
>Audit-Trail:
From: RVP <rvp@SDF.ORG>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: port-amd64/59361: paging up in less(1) under qemu vga console
is slow
Date: Sun, 26 Oct 2025 22:35:24 +0000 (UTC)
On Sat, 26 Apr 2025, campbell+netbsd@mumble.net wrote:
>> Description:
> Paging _down_ in less(1) under qemu vga console is reasonably quick. Not instantaneous -- I still see a flicker sometimes -- but quick enough.
>
> Paging _up_ in less(1) under qemu vga console is excruciatingly slow, takes multiple seconds to go a single page in a 25x80 display.
>
There are a few workarounds:
Userspace:
----------
1. `export LESS=-c' or run `less -c' to that less(1) repaints rather than scrolls
up from the bottom. (This also works around most, not all, delays in the
`vt100' terminfo entry.)
2. Don't use `-accel nvmm' :(. (TCG, the default accel doesn't seem to suffer
from this.)
Bootloader:
-----------
Force use of VESA:
boot> vesa on
Kernel:
-------
Scrolling up (erasure of 1st line, followed by moving the rest of the lines up)
seems to do a backwards copy. Use plain memmove(3) instead:
```
--- sys/dev/ic/vga.c.orig 2021-08-07 16:19:12.000000000 +0000
+++ sys/dev/ic/vga.c 2025-05-20 04:02:12.133432513 +0000
@@ -544,8 +544,8 @@
&vh->vh_ioh_6845))
panic("vga_init: couldn't map 6845 io");
- if (bus_space_map(vh->vh_memt, 0xa0000, 0x20000,
- BUS_SPACE_MAP_CACHEABLE, &vh->vh_allmemh))
+ if (bus_space_map(vh->vh_memt, 0xa0000, 0x20000,
+ BUS_SPACE_MAP_PREFETCHABLE | BUS_SPACE_MAP_LINEAR, &vh->vh_allmemh))
panic("vga_init: couldn't map memory");
if (bus_space_subregion(vh->vh_memt, vh->vh_allmemh,
@@ -1168,10 +1168,15 @@
scr->pcs.cursorrow, scr->pcs.cursorcol);
#endif
} else {
+ bus_space_handle_t dst = memh + scr->pcs.dispoffset + dstoff * 2;
+ bus_space_handle_t src = memh + scr->pcs.dispoffset + srcoff * 2;
+ memmove((void* )dst, (void* )src, nrows * ncols * 2);
+#if 0
bus_space_copy_region_2(memt, memh,
scr->pcs.dispoffset + srcoff * 2,
memh, scr->pcs.dispoffset + dstoff * 2,
nrows * ncols);
+#endif
}
} else
memcpy(&scr->pcs.mem[dstoff], &scr->pcs.mem[srcoff],
```
HTH,
-RVP
From: Taylor R Campbell <riastradh@NetBSD.org>
To: RVP <rvp@SDF.ORG>
Cc: gnats-bugs@NetBSD.org, netbsd-bugs@NetBSD.org
Subject: Re: port-amd64/59361: paging up in less(1) under qemu vga console
is slow
Date: Sun, 26 Oct 2025 23:55:09 +0000
> Date: Sun, 26 Oct 2025 22:35:24 +0000 (UTC)
> From: RVP <rvp@SDF.ORG>
>=20
> Scrolling up (erasure of 1st line, followed by moving the rest of the lin=
es up)
> seems to do a backwards copy. Use plain memmove(3) instead:
> =20
> @@ -1168,10 +1168,15 @@
> scr->pcs.cursorrow, scr->pcs.cursorcol);
> #endif
> } else {
> + bus_space_handle_t dst =3D memh + scr->pcs.dispoffset + dstoff * 2;
> + bus_space_handle_t src =3D memh + scr->pcs.dispoffset + srcoff * 2;
> + memmove((void* )dst, (void* )src, nrows * ncols * 2);
> +#if 0
> bus_space_copy_region_2(memt, memh,
> scr->pcs.dispoffset + srcoff * 2,
> memh, scr->pcs.dispoffset + dstoff * 2,
> nrows * ncols);
> +#endif
Thanks, I bet bus_space_copy_region_2 is slow under nvmm because it
has to do a VM exit for every pair of bytes copied, and VM exits are
costly:
811 if (x86_bus_space_is_io(t)) {
812 if (addr1 >=3D addr2) {
813 /* src after dest: copy forward */
814 for (; c !=3D 0; c--, addr1 +=3D 2, addr2 +=3D 2)
815 outw(addr2, inw(addr1));
816 } else {
817 /* dest after src: copy backwards */
818 for (addr1 +=3D 2 * (c - 1), addr2 +=3D 2 * (c - 1);
819 c !=3D 0; c--, addr1 -=3D 2, addr2 -=3D 2)
820 outw(addr2, inw(addr1));
821 }
https://nxr.netbsd.org/xref/src/sys/arch/x86/x86/bus_space.c?r=3D1.47#811
I don't think there's any I/O port equivalent of REP MOV, so there
might not be a better way to do this properly (and still support VGA
in I/O space rather than memory-mapped, as well as machines where
access must be 2-bytes-at-a-time) other than a larger temporary
buffer.
(Contact us)
$NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2025
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.