I found no clear solution online, but the general consensus is that the BIOS is needlessly filling all eight entries in the variable MTRR list. It's quite easy to rearrange them by writing to /proc/mtrr, and in the case of my particular machine (probably all AOA150's) entry #1 in particular is useless. To get rid of this, you just do:
# echo "disable=1" > /proc/mtrr
The problem is that the i915/drm modules have already tried to do their stuff at this point. In fact, it happens in the initramfs image, which is well before rc.local, for instance.
So I needed to do it as early as possible, and someone on Superuser suggested he'd edited his initramfs image to do it. Great, and it turns out you can script it.
/usr/share/initramfs-tools/scripts/init-top/ contains "early" scripts, and some clues were scripts called 'udev' and 'framebuffer'. Looks like the right spot. They are not ordered explicitly, but specify prerequisites (so the 'framebuffer' script requires 'udev' to be run etc).
I simply added a new file called 'aoa150_mtrr' and based it on the 'udev' one. It now looks like this:
Really, only the last line is interesting, the rest is scaffolding. So what it does is to clear the #1 MTRR entry. To ensure that the script is run before the graphics initialize, I added a reference to PREREQ in the 'framebuffer' script:
#!/bin/sh -e
# initramfs init-top script for AOA150 mtrr fixups
PREREQ=""
# Output pre-requisites
prereqs()
{
echo "$PREREQ"
}
case "$1" in
prereqs)
prereqs
exit 0
;;
esac
# Remove one unnecessary mtrr entry.
echo "disable=1" > /proc/mtrr
PREREQ="udev aoa150_mtrr"
Then,
# update-initramfs -u -k 3.2.0-17-generic
Obviously replace the version with whatever kernel you're running.
Reboot and... no more MTRR error message! The drm module no longer complains, and cat /proc/mtrr clearly shows that it has succeeded in setting up write combining:
reg00: base=0x0fffe0000 ( 4095MB), size= 128KB, count=1: write-protect
reg01: base=0x040000000 ( 1024MB), size= 256MB, count=1: write-combining
reg02: base=0x000000000 ( 0MB), size= 512MB, count=1: write-back
reg03: base=0x020000000 ( 512MB), size= 512MB, count=1: write-back
reg04: base=0x03f800000 ( 1016MB), size= 8MB, count=1: uncachable
reg05: base=0x03f600000 ( 1014MB), size= 2MB, count=1: uncachable
reg06: base=0x03f500000 ( 1013MB), size= 1MB, count=1: uncachable
reg07: base=0x000000000 ( 0MB), size= 128KB, count=1: uncachable
Yay! However... I've yet to measure any performance difference. :/
gtkperf hovers around 22.50 (YMMV) and glxgears gives me about 350 fps.
I'll maybe look for a more direct benchmark for CPU->VRAM writes which is what this fix should help with.
Troubleshooting #1: If you're using a custom kernel, DO ENSURE that i915, drm etc are modules and not compiled directly into the kernel, because otherwise they will initialize way too early! I have no clue how to get around that, so try lsmod | grep i915 to confirm that it's a module.
Inga kommentarer:
Skicka en kommentar