Hi! I dual-boot Kubuntu, so I interact with Grub daily.
Running Grub at 2560x1440 was painfully slow, and even at 1280x720 it's no fun.
So I asked a friendly robot to look at it.

It wrote a script that set MTRR registers, as a menu item in Grub -- as a test.
I tried it, and then 2560x1440 worked like butter! Menu, console, everything 
snappy.

Now I'm not a "kernel developer", I have no idea how this works.
So rather then pretend, here's the robot's report:

-------

Main cause, at least on this machine: the firmware leaves the GOP
framebuffer uncached, and GRUB writes to it as it is. Drawing every
pixel in software isn't slow in itself; sending every pixel to the
graphics card as its own uncached PCIe write is.

Machine: ASUS PRIME B350M-A (AMI firmware 6223, 2024-04-08), AMD Ryzen 7
5700X, NVIDIA GeForce RTX 5060 Ti with Resizable BAR (the firmware puts
the 16 GiB BAR 1 at 0x7800000000), 2560x1440 monitor on DisplayPort.
Ubuntu 26.04 (Kubuntu), grub-efi-amd64-signed 1.215+2.14-2ubuntu1,
Secure Boot off.

Symptom: with gfxterm and a theme at 2560x1440 (GOP offers it and
reports it as the EDID preferred mode), each up/down in the menu took
half a second to a second, and keys typed at the console often came out
twice. At 1280x720 it is usable but still laggy.

GRUB's rdmsr module shows the MTRRs the firmware left:

  MTRRcap      0xFE  = 0x508           8 variable MTRRs, WC supported
  MTRRdefType  0x2FF = 0xc00           MTRRs on, default type 0 = UC
  var 0  base 0x6         mask 0xffff80000800   0 - 2 GiB WB
  var 1  base 0x80000006  mask 0xffffc0000800   2 - 3 GiB WB
  var 2  base 0xc0000006  mask 0xfffff0000800   3 - 3.25 GiB WB
  var 3  base 0xca750000  mask 0xffffffff0800   64 KiB UC
  var 4-7                 unused
  AMD SYSCFG 0xC0010010 = 0x740000     RAM above 4 GiB is WB via TOM2

Nothing covers the framebuffer at 0x7800000000, so it gets the default
type, UC (assuming the firmware's page tables use plain WB there, which
leaves the MTRR type in charge).

Experiment, from GRUB's console (diagnostic only: this skips the cache-
disable sequence the CPU manuals ask for when changing MTRRs; it lasts
until the next reset):

  insmod wrmsr
  wrmsr 0x208 0x7800000001        # var MTRR 4: base 0x7800000000, type 1 = WC
  wrmsr 0x209 0xfffc00000800      # 16 GiB mask, valid
  set gfxmode=2560x1440
  terminal_output console
  terminal_output gfxterm

After that, GRUB at 2560x1440 was instant: the menu, the console, no
doubled keys. Same resolution, same theme, same CPU work; only the
memory type changed.

So a fix could be for GRUB's efi_gop driver to ask the firmware for
write-combining on the framebuffer after setting the mode, e.g. through
the PI DXE Services SetMemorySpaceAttributes(base, size, EFI_MEMORY_WC)
when the GCD descriptor allows WC, and leave it as is otherwise. Linux
does the equivalent for its own early framebuffer (efifb/simpledrm map
it write-combining), which is why the console is fast once the kernel
runs.


-------

Me again. Pretty wild stuff.

This also seemed to be related from 2014:
  
https://forums.freebsd.org/threads/xorg-vesa-driver-massive-speedup-using-mtrr-write-combine.46723/


Cheers!

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/480159

Title:
  grub console is ridiculously slow

To manage notifications about this bug go to:
https://bugs.launchpad.net/grub/+bug/480159/+subscriptions


-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to