Updating Intel CPU microcode from Gentoo Linux

Updates to CPU microcode have to be re-applied each time the computer is booted, because the memory updated is volatile (despite the term ‘firmware’ also being used for microcode). Below I describe two methods (there are others) of applying CPU microcode updates in Gentoo Linux. My main laptop has an Intel CPU so I focus here on Intel microcode updates. The procedure is almost the same for AMD CPUs, but the AMD CPU binary update file (‘binary blob’) is installed by the sys-kernel/linux-firmware package.

METHOD 1: Use an initscript in the boot runlevel with a kernel module

Until recently I was using an initscript named microcode_ctl, which uses a program (also named microcode_ctl) and a kernel module (microcode.ko) to update the Intel CPU microcode during boot. This was straightforward to set up in Gentoo Linux:

1. Build the kernel with CONFIG_MICROCODE=m and CONFIG_MICROCODE_INTEL=y.

This is what I configured in the kernel:

# grep -i microcode /usr/src/linux/.config
CONFIG_MICROCODE=m
CONFIG_MICROCODE_INTEL=y
# CONFIG_MICROCODE_AMD is not set
CONFIG_MICROCODE_OLD_INTERFACE=y
# CONFIG_MICROCODE_INTEL_EARLY is not set
# CONFIG_MICROCODE_AMD_EARLY is not set

2. Install two packages and add an OpenRC initscript to the boot runlevel:

# emerge microcode-data microcode-ctl
# rc-update add microcode_ctl boot

The initscript will re-update the CPU microcode every time the computer is rebooted.

Installing the package microcode-data downloads a compressed file (microcode-yyyymmdd.tgz) from the Intel Download Centre, extracts a text file named microcode.dat and parses the text in it to create a set of binary ‘blobs’ in the directory /lib/firmware/intel-ucode/ (one blob for each model of Intel CPU).

Before rebooting, check the revision of microcode in the CPU (the microcode revision is shown for each logical core):

# This is for the Core i7-720QM CPU in my Compal NBLB2 laptop.
# grep microcode /proc/cpuinfo
microcode : 0x3
microcode : 0x3
microcode : 0x3
microcode : 0x3
microcode : 0x3
microcode : 0x3
microcode : 0x3
microcode : 0x3

If I use this method of updating the microcode, the initscript runs after the message ‘Waiting for uevents to be processed ...‘ is displayed on VT1 while booting. After the module has performed the update, the microcode revision in the CPU’s logical cores has changed:

# grep microcode /proc/cpuinfo
microcode : 0x7
microcode : 0x7
microcode : 0x7
microcode : 0x7
microcode : 0x7
microcode : 0x7
microcode : 0x7
microcode : 0x7
# dmesg | grep microcode
[ 15.749533] microcode: CPU0 sig=0x106e5, pf=0x10, revision=0x3
[ 15.834790] microcode: CPU0 sig=0x106e5, pf=0x10, revision=0x3
[ 15.835530] microcode: CPU0 updated to revision 0x7, date = 2013-08-20
[ 15.835544] microcode: CPU1 sig=0x106e5, pf=0x10, revision=0x3
[ 15.835587] microcode: CPU1 sig=0x106e5, pf=0x10, revision=0x3
[ 15.836241] microcode: CPU1 updated to revision 0x7, date = 2013-08-20
[ 15.836257] microcode: CPU2 sig=0x106e5, pf=0x10, revision=0x3
[ 15.836299] microcode: CPU2 sig=0x106e5, pf=0x10, revision=0x3
[ 15.836953] microcode: CPU2 updated to revision 0x7, date = 2013-08-20
[ 15.837063] microcode: CPU3 sig=0x106e5, pf=0x10, revision=0x3
[ 15.837128] microcode: CPU3 sig=0x106e5, pf=0x10, revision=0x3
[ 15.837767] microcode: CPU3 updated to revision 0x7, date = 2013-08-20
[ 15.837857] microcode: CPU4 sig=0x106e5, pf=0x10, revision=0x3
[ 15.837968] microcode: CPU4 sig=0x106e5, pf=0x10, revision=0x3
[ 15.838605] microcode: CPU4 updated to revision 0x7, date = 2013-08-20
[ 15.838634] microcode: CPU5 sig=0x106e5, pf=0x10, revision=0x3
[ 15.838681] microcode: CPU5 sig=0x106e5, pf=0x10, revision=0x3
[ 15.839357] microcode: CPU5 updated to revision 0x7, date = 2013-08-20
[ 15.839390] microcode: CPU6 sig=0x106e5, pf=0x10, revision=0x3
[ 15.839453] microcode: CPU6 sig=0x106e5, pf=0x10, revision=0x3
[ 15.840121] microcode: CPU6 updated to revision 0x7, date = 2013-08-20
[ 15.840180] microcode: CPU7 sig=0x106e5, pf=0x10, revision=0x3
[ 15.840274] microcode: CPU7 sig=0x106e5, pf=0x10, revision=0x3
[ 15.840911] microcode: CPU7 updated to revision 0x7, date = 2013-08-20
[ 15.840997] microcode: Microcode Update Driver: v2.00 , Peter Oruba
[ 26.940662] microcode: Microcode Update Driver: v2.00 removed.

Notice that the microcode update occurred in the period from 15.749533 to 15.840997 seconds after the kernel started, and the microcode was updated from revision 0×3 to 0×7.

METHOD 2: Use the kernel’s built-in Early Update driver

Although the initscript method works perfectly in my case and the update is complete by the time the laptop has finished booting, I wanted to update the CPU microcode earlier. Updating microcode early can fix CPU issues before they occur during kernel boot time. It is possible to configure the kernel to update microcode early by setting CONFIG_MICROCODE_EARLY and CONFIG_MICROCODE_INTEL_EARLY in the kernel. See /usr/src/linux/Documentation/x86/early-microcode.txt for details. That document only refers to initrd files, but, in fact, it also applies to initramfs files.

The Early Update kernel driver will align misaligned microcode data (see Notes on Intel Microcode Updates and [PATCH 7/8] x86, microcode, intel: guard against misaligned microcode data), but you can pre-align the data yourself if you wish by using a .padding file as explained on the latter page. However I did not bother doing that; I leave the Early Update kernel driver to take care of aligning the microcode, as the time penalty to align it is small compared to the overall update time.

It is possible to download the latest compressed Intel microcode data file yourself from the Intel Download Centre. The latest file released is microcode-20140913.tgz at the time of writing. It contains only a text file named microcode.dat, not the required binary blob. Actually, microcode.dat contains data in text format for several Intel CPU models. The microcode.dat file should reside in the directory /lib/firmware/. In the case of Gentoo it is a waste of time manually obtaining the microcode.dat file this way, as there is no tool in Gentoo specifically for creating a binary blob from the microcode.dat file. Therefore just install the Gentoo package sys-apps/microcode-data (which you would have done in any case if you were using the microcode_ctl initscript to load the microcode update to the CPU) and it will automatically download the compressed file from the Intel Web site, unpack it, copy the file microcode.dat to /lib/firmware/ and create the binary blobs in the directory /lib/firmware/intel-ucode/.

You may have read of a tool named intel-microcode2ucode used in other Linux distributions. Gentoo does not build intel-microcode2ucode (the source code of which is included in the Gentoo package sys-apps/microcode-data) as a stand-alone tool, but the act of installing microcode-data creates the required binary files in /lib/firmware/intel-ucode/. i.e. the following command does the complete job:

# emerge microcode-data

Check that the microcode files for the various CPU models were created when microcode-data was installed:

# ls /lib/firmware/intel-ucode/
06-03-02 06-05-03 06-06-0d 06-08-01 06-09-05 06-0b-04 06-0f-02 06-0f-0b 06-17-07 06-1c-02 06-1e-05 06-2a-07 06-3a-09 06-3e-07 0f-00-07 0f-02-05 0f-03-02 0f-04-03 0f-04-09 0f-06-05
06-05-00 06-06-00 06-07-01 06-08-03 06-0a-00 06-0d-06 06-0f-06 06-0f-0d 06-17-0a 06-1c-0a 06-25-02 06-2d-06 06-3c-03 06-3f-02 0f-00-0a 0f-02-06 0f-03-03 0f-04-04 0f-04-0a 0f-06-08
06-05-01 06-06-05 06-07-02 06-08-06 06-0a-01 06-0e-08 06-0f-07 06-16-01 06-1a-04 06-1d-01 06-25-05 06-2d-07 06-3e-04 06-45-01 0f-01-02 0f-02-07 0f-03-04 0f-04-07 0f-06-02
06-05-02 06-06-0a 06-07-03 06-08-0a 06-0b-01 06-0e-0c 06-0f-0a 06-17-06 06-1a-05 06-1e-04 06-26-01 06-2f-02 06-3e-06 06-46-01 0f-02-04 0f-02-09 0f-04-01 0f-04-08 0f-06-04

I looked in /proc/cpuinfo to confirm the model of CPU in my laptop:

$ grep model /proc/cpuinfo
model : 30
model name : Intel(R) Core(TM) i7 CPU Q 720 @ 1.60GHz
model : 30
model name : Intel(R) Core(TM) i7 CPU Q 720 @ 1.60GHz
model : 30
model name : Intel(R) Core(TM) i7 CPU Q 720 @ 1.60GHz
model : 30
model name : Intel(R) Core(TM) i7 CPU Q 720 @ 1.60GHz
model : 30
model name : Intel(R) Core(TM) i7 CPU Q 720 @ 1.60GHz
model : 30
model name : Intel(R) Core(TM) i7 CPU Q 720 @ 1.60GHz
model : 30
model name : Intel(R) Core(TM) i7 CPU Q 720 @ 1.60GHz
model : 30
model name : Intel(R) Core(TM) i7 CPU Q 720 @ 1.60GHz

I was able to find the CPUID and other data for that model from the Web site CPU World:

CPUID 106E5
Family 6 (06 hex)
Model 30 (1E hex)
Stepping 5 (05 hex)

Therefore the file /lib/firmware/intel-ucode/06-1e-05 (Family-Model-Stepping in hexadecimal) is the binary blob for my specific CPU model.

First I used genkernel to rebuild the current kernel with CONFIG_MICROCODE_EARLY=y and CONFIG_MICROCODE_INTEL_EARLY=y.

# mount /dev/sda3 /boot # /boot is on a separate partition in my installation.

# Backup the files of the existing kernel image and initramfs:
# cp /boot/initramfs-genkernel-x86_64-3.17.1-gentoo-r1 /home/fitzcarraldo/initramfs-genkernel-x86_64-3.17.1-gentoo-r1.bak
# cp /boot/kernel-genkernel-x86_64-3.17.1-gentoo-r1 /home/fitzcarraldo/kernel-genkernel-x86_64-3.17.1-gentoo-r1.bak
# cp /boot/System.map-genkernel-x86_64-3.17.1-gentoo-r1 /boot/fitzcarraldo/System.map-genkernel-x86_64-3.17.1-gentoo-r1.bak

# Now rebuild the kernel:
# zcat /proc/config.gz > /usr/src/config
# genkernel --kernel-config=/usr/src/config --menuconfig --splash=Emergance --disklabel all # Set CONFIG_MICROCODE_EARLY and CONFIG_MICROCODE_INTEL_EARLY.
# emerge @module-rebuild
# grub2-mkconfig -o /boot/grub/grub.cfg

This is what I have after rebuilding the kernel:

# grep -i microcode /usr/src/linux/.config
CONFIG_MICROCODE=y
CONFIG_MICROCODE_INTEL=y
# CONFIG_MICROCODE_AMD is not set
CONFIG_MICROCODE_OLD_INTERFACE=y
CONFIG_MICROCODE_INTEL_EARLY=y
# CONFIG_MICROCODE_AMD_EARLY is not set
CONFIG_MICROCODE_EARLY=y

Then I prepended the cpio file containing the binary blob to the initramfs file (see the instructions in /usr/src/linux/Documentation/x86/early-microcode.txt):

# mkdir -p /boot/initrd/kernel/x86/microcode
# cd /boot/initrd
# cp /lib/firmware/intel-ucode/06-1e-05 kernel/x86/microcode/GenuineIntel.bin
# find . | cpio -o -H newc >../ucode.cpio
# cd ..
# cp /boot/initramfs-genkernel-x86_64-3.17.1-gentoo-r1 /home/fitzcarraldo/initramfs-genkernel-x86_64-3.17.1-gentoo-r1.bak.early # Backup the recently-built initramfs first.
# cat ucode.cpio /boot/initramfs-genkernel-x86_64-3.17.1-gentoo-r1 >/boot/initramfs-genkernel-x86_64-3.17.1-gentoo-r1.ucode
# cp /boot/initramfs-genkernel-x86_64-3.17.1-gentoo-r1.ucode /boot/initramfs-genkernel-x86_64-3.17.1-gentoo-r1
# rm /boot/initramfs-genkernel-x86_64-3.17.1-gentoo-r1.ucode
# umount /boot
# rc-update del microcode_ctl boot # Disable the initscript so that microcode.ko will no longer be used when I reboot.

Reboot.

Use the following commands to check if the CPU microcode has been updated:

# grep microcode /proc/cpuinfo
# dmesg | grep microcode

There is no point looking in /var/log/messages, because syslog-ng has not started running when the early microcode update occurs.

# grep microcode /proc/cpuinfo
microcode : 0x7
microcode : 0x7
microcode : 0x7
microcode : 0x7
microcode : 0x7
microcode : 0x7
microcode : 0x7
microcode : 0x7
# dmesg | grep microcode
[ 0.252234] CPU1 microcode updated early to revision 0x7, date = 2013-08-20
[ 0.265389] CPU2 microcode updated early to revision 0x7, date = 2013-08-20
[ 0.278696] CPU3 microcode updated early to revision 0x7, date = 2013-08-20
[ 1.888471] microcode: CPU0 sig=0x106e5, pf=0x10, revision=0x7
[ 1.888481] microcode: CPU1 sig=0x106e5, pf=0x10, revision=0x7
[ 1.888491] microcode: CPU2 sig=0x106e5, pf=0x10, revision=0x7
[ 1.888498] microcode: CPU3 sig=0x106e5, pf=0x10, revision=0x7
[ 1.888506] microcode: CPU4 sig=0x106e5, pf=0x10, revision=0x7
[ 1.888515] microcode: CPU5 sig=0x106e5, pf=0x10, revision=0x7
[ 1.888523] microcode: CPU6 sig=0x106e5, pf=0x10, revision=0x7
[ 1.888534] microcode: CPU7 sig=0x106e5, pf=0x10, revision=0x7
[ 1.888597] microcode: Microcode Update Driver: v2.00 , Peter Oruba

Compare the update time in the dmesg output above with the update time in the dmesg output for an update done using the initscript (Method 1, further up). With the Early Update driver, the update was complete in 0.278696 seconds. With the initscript and kernel module, the update was complete in 15.840911 seconds. Quite a difference.

I do not know why the dmesg output does not have a message for Core 0 in the group of messages before 1.000000 second elapsed. The message at 1.888471 shows it was updated, so I assume the kernel ring buffer was not large enough and the message was overwritten. Cores 1, 2 and 3 were updated in the period between 0.252234 and 0.278696 seconds, and then all eight logical cores are listed in the period between 1.888471 and 1.888597 seconds. I’m not sure of the precise messages expected, but they look similar to the results obtained by users in other distributions, such as the following CrunchBang Linux output:

$ uname -a
Linux crunchbang 3.10-12.dmz.1-liquorix-amd64 #1 ZEN SMP PREEMPT Sun Sep 15 17:29:51 UTC 2013 x86_64 GNU/Linux
$ dmesg | grep microcode
CPU0 microcode updated early to revision 0x19, date = 2013-06-13
CPU1 microcode updated early to revision 0x19, date = 2013-06-13
CPU2 microcode updated early to revision 0x19, date = 2013-06-13
CPU3 microcode updated early to revision 0x19, date = 2013-06-13
microcode: CPU0 sig=0x306a9, pf=0x10, revision=0x19
microcode: CPU1 sig=0x306a9, pf=0x10, revision=0x19
microcode: CPU2 sig=0x306a9, pf=0x10, revision=0x19
microcode: CPU3 sig=0x306a9, pf=0x10, revision=0x19
microcode: CPU4 sig=0x306a9, pf=0x10, revision=0x19
microcode: CPU5 sig=0x306a9, pf=0x10, revision=0x19
microcode: CPU6 sig=0x306a9, pf=0x10, revision=0x19
microcode: CPU7 sig=0x306a9, pf=0x10, revision=0x19
microcode: Microcode Update Driver: v2.00 , Peter Oruba
$ cat /proc/cpuinfo | grep microcode | uniq
microcode : 0x19

Finally, I deleted the temporary work directory and files:

# mount /dev/sda3 /boot
# rm -rf /boot/initrd/
# rm /boot/ucode.cpio
# rm /home/fitzcarraldo/kernel-genkernel-x86_64-3.17.1-gentoo-r1.bak
# rm /home/fitzcarraldo/initramfs-genkernel-x86_64-3.17.1-gentoo-r1.bak
# rm /home/fitzcarraldo/System.map-genkernel-x86_64-3.17.1-gentoo-r1.bak

# Optional. Could keep the following file in case Intel issues a new microcode.dat file and I want to create a new concatenated initramfs file:
# rm /home/fitzcarraldo/initramfs-genkernel-x86_64-3.17.1-gentoo-r1.bak.early

Of course, you will need to repeat the whole process and create a new concatenated initramfs file in any of the following cases:

a) you build a new version of the kernel;

b) you rebuild the current version of the kernel with different configuration settings;

c) Intel releases a new version of the microcode (which does not happen often).

It seems the Early Update driver still has some bugs, so I expect the message output to change in future kernel releases. See e.g. [PATCH 0/8] x86, microcode, intel: fixes and enhancements, [PATCH 3/8] x86, microcode, intel: clarify log messages, Re: [PATCH 3/8] x86, microcode, intel: clarify log messages and a bunch of other very recent posts in the kernel mailing list regarding the Early Update driver and CPU microcode updates.

Laptop Mode Tools revisited due to a change in its functionality

The site statistics for this blog can be quite revealing. For example, over the last two or three months I noticed that my post How to prevent a USB mouse auto-suspending in Linux when a laptop’s power supply is disconnected has consistently been one of the most viewed. Given the problems I experienced with Laptop Mode Tools 1.65 (see my Gentoo Linux Forums post Bug in laptop-mode-tools-1.65? and Gentoo Linux Bugzilla Bug Report No. 520124), I was not entirely surprised. Thanks to fellow Gentoo Linux and Laptop Mode Tools user Ted Tanberry I learned that Version 1.65 had stopped using Laptop Mode Tools module usb-autosuspend, and started using Laptop Mode Tools module runtime-pm instead. At least that was the developer’s intention, but he had not implemented it correctly. The aforementioned Gentoo Linux bug report explains in detail the problem with Version 1.65.

The situation in my Gentoo Linux installation with laptop-mode-tools-1.64 installed, providing the functionality I desired, was as follows:

a. The precise package installed:

# eix -I laptop-mode-tools
[U] app-laptop/laptop-mode-tools
Available versions: 1.64 (~)1.65 (~)1.65-r1 (~)1.66 {+acpi apm bluetooth scsi}
Installed versions: 1.64(10:04:43 21/10/14)(acpi bluetooth -apm -scsi)
Homepage: http://www.samwel.tk/laptop_mode/
Description: Linux kernel laptop_mode user-space utilities

b. The auto-suspend state when the laptop PSU was connected:

# for d in /sys/bus/usb/devices/[0-9]* ; do if [[ -e $d/product ]] ; then echo -e "`basename $d`\t`cat $d/power/control`\t`cat $d/speed`\t`cat $d/product`" ; fi ; done
1-1.2 on 1.5 USB Laser Mouse
2-1.2 on 12 Fingerprint Sensor
2-1.3 on 480 USB 2.0 Camera

c. The contents of the file /lib64/udev/rules.d/99-laptop-mode.rules:

ACTION=="change", SUBSYSTEM=="power_supply", RUN+="lmt-udev auto"
ACTION=="add|remove", SUBSYSTEM=="machinecheck", RUN+="lmt-udev auto"
ACTION=="add|remove", SUBSYSTEM=="usb", RUN+="lmt-udev force modules=usb-autosuspend devices=%k"

d. The contents of file /etc/laptop-mode/conf.d/usb-autosuspend.conf:

#
# Configuration file for Laptop Mode Tools module usb-autosuspend.
#
# For more information, consult the laptop-mode.conf(8) manual page.
#
 
 
###############################################################################
# USB autosuspend settings
# ------------------------
#
# If you enable this setting, laptop mode tools will automatically enable the
# USB autosuspend feature for all devices.
#
# NOTE: Some USB devices claim they support autosuspend, but implement it in a
# broken way. This can mean keyboards losing keypresses, or optical mice turning
# their LED completely off. If you have a device that misbehaves, add its USB ID
# to the blacklist below and complain to your hardware vendor.
################################################################################
 
# Enable debug mode for this module
# Set to 1 if you want to debug this module
DEBUG=0
 
# Enable USB autosuspend feature?
# Set to 0 to disable
CONTROL_USB_AUTOSUSPEND="auto"
 
# Set this to use opt-in/whitelist instead of opt-out/blacklist for deciding
# which USB devices should be autosuspended.
# AUTOSUSPEND_USE_WHITELIST=0 means AUTOSUSPEND_*_BLACKLIST will be used.
# AUTOSUSPEND_USE_WHITELIST=1 means AUTOSUSPEND_*_WHITELIST will be used.
AUTOSUSPEND_USE_WHITELIST=0
 
# The list of USB IDs that should not use autosuspend. Use lsusb to find out the
# IDs of your USB devices.
# Example: AUTOSUSPEND_USBID_BLACKLIST="046d:c025 0123:abcd"
AUTOSUSPEND_USBID_BLACKLIST="046d:c052"
 
# The list of USB driver types that should not use autosuspend.  The driver
# type is given by "DRIVER=..." in a USB device's uevent file.
# Example: AUTOSUSPEND_USBID_BLACKLIST="usbhid usb-storage"
AUTOSUSPEND_USBTYPE_BLACKLIST=""
 
# The list of USB IDs that should use autosuspend. Use lsusb to find out the
# IDs of your USB devices.
# Example: AUTOSUSPEND_USBID_WHITELIST="046d:c025 0123:abcd"
AUTOSUSPEND_USBID_WHITELIST=""
 
# The list of USB driver types that should use autosuspend.  The driver
# type is given by "DRIVER=..." in a USB device's uevent file.
# Example: AUTOSUSPEND_USBTYPE_WHITELIST="usbhid usb-storage"
AUTOSUSPEND_USBTYPE_WHITELIST=""
 
# Trigger auto-suspension of the USB deivce under conditional circumstances
BATT_SUSPEND_USB=1
LM_AC_SUSPEND_USB=0
NOLM_AC_SUSPEND_USB=0
 
# USB Auto-Suspend timeout in seconds
# Number of seconds after which the USB devices should suspend
AUTOSUSPEND_TIMEOUT=2

Having experienced the problems with the buggy Laptop Mode Tools 1.65, I re-installed 1.64 and had been using that successfully until a week ago. Then I noticed that 1.66 had been released, so I installed it:

# emerge laptop-mode-tools
.
.
.
>>> Installing (1 of 1) app-laptop/laptop-mode-tools-1.66::gentoo
* To enable automatic power state event handling,
* e.g. enabling laptop_mode after unplugging the battery,
* both laptop_mode and the acpid daemon must be
* added to default runlevel:
* # rc-update add laptop_mode default
>>> Auto-cleaning packages...

>>> No outdated packages were found on your system.

* GNU info directory index is up-to-date.

I would not have expected that ewarn message about adding laptop_mode to the default runlevel, as the ebuild is only supposed to display the warning if laptop_mode is not assigned to the default runlevel. But, sure enough, something had removed it:

# rc-update show -v | grep laptop
laptop_mode |
# rc-update show -v | grep acpi
acpid |      default

I don’t know what removed laptop_mode from the default runlevel. It was certainly assigned previously, as proved by Laptop Mode Tools 1.64 working as expected when I connected and disconnected the laptop’s PSU from the mains (see my earlier post). Anyway, I re-added it:

# rc-update add laptop_mode default
* service laptop_mode added to runlevel default

If you use systemd instead of OpenRC, instead of adding laptop_mode to the default runlevel you would need to use the following command:

# systemctl enable laptop_mode.service

Notice that the incorrect contents of 99-laptop-mode.rules and /etc/laptop-mode/laptop-mode.conf that were present in Laptop Mode Tools 1.65 have been fixed in 1.66:

# cat /lib64/udev/rules.d/99-laptop-mode.rules
ACTION=="change", SUBSYSTEM=="power_supply", RUN+="lmt-udev auto"
ACTION=="add|remove", SUBSYSTEM=="machinecheck", RUN+="lmt-udev auto force"
ACTION=="add|remove", SUBSYSTEM=="usb", RUN+="lmt-udev force modules=runtime-pm devices=%k"

# cat /etc/laptop-mode/laptop-mode.conf | grep usb-autosuspend
#

The ebuild for Laptop Mode Tools 1.66 did not delete the now-redundant file /etc/laptop-mode/conf.d/usb-autosuspend.conf but it is presumably ignored by 1.66 anyway.

From now on I must configure the contents of /etc/laptop-mode/conf.d/runtime-pm.conf instead. After installing Laptop Mode Tools 1.66 it contained the following:

#
# Configuration file for Laptop Mode Tools module runtime-pm
#
# For more information, consult the laptop-mode.conf(8) manual page.
#


###############################################################################
# Runtime Power Management Settings
# ---------------------------------
#
#__COMMENT If you enable this setting, laptop mode tools will automatically enable
#__COMMENT the Runtime Power Management feature for all devices.
#__COMMENT
#__COMMENT NOTE: Some devices claim they support autosuspend, but implement it in a
#__COMMENT broken way. This can mean keyboards losing keypresses, or optical mice
#__COMMENT turning their LED completely off. If you have a device that misbehaves,
#__COMMENT add its DEVICE ID to the blacklist section below and complain to your
#__COMMENT hardware / device driver contact
#
################################################################################

# Enable debug mode for this module
# Set to 1 if you want to debug this module
DEBUG=0

# Enable Runtime autosuspend feature?
# Set to 0 to disable
CONTROL_RUNTIME_AUTOSUSPEND=1

# Set this to use opt-in/whitelist instead of opt-out/blacklist for deciding
# which devices should be autosuspended.
# AUTOSUSPEND_USE_WHITELIST=0 means AUTOSUSPEND_*_BLACKLIST will be used.
# AUTOSUSPEND_USE_WHITELIST=1 means AUTOSUSPEND_*_WHITELIST will be used.
AUTOSUSPEND_USE_WHITELIST=0

# The list of Device IDs that should not use autosuspend. Use system commands or
# look into sysfs to find out the IDs of your devices.
# Example: AUTOSUSPEND_DEVID_BLACKLIST="046d:c025 0123:abcd"
AUTOSUSPEND_RUNTIME_DEVID_BLACKLIST=""

# The list of device driver types that should not use autosuspend.  The driver
# type is given by "DRIVER=..." in a device's uevent file.
# Example: AUTOSUSPEND_DEVID_BLACKLIST="usbhid usb-storage"
AUTOSUSPEND_RUNTIME_DEVTYPE_BLACKLIST=""

# The list of Device IDs that should use autosuspend. Use system commands or
# look into sysfs to find out the IDs of your devices.
# Example: AUTOSUSPEND_DEVID_WHITELIST="046d:c025 0123:abcd"
AUTOSUSPEND_RUNTIME_DEVID_WHITELIST=""

# The list of device driver types that should use autosuspend.  The driver
# type is given by "DRIVER=..." in a device's uevent file.
# Example: AUTOSUSPEND_DEVTYPE_WHITELIST="usbhid usb-storage"
AUTOSUSPEND_RUNTIME_DEVTYPE_WHITELIST=""

# Trigger auto-suspension of the deivce under conditional circumstances
# Warning: DO NOT CHANGE THESE DEFAUTLS UNLESS YOU KNOW
BATT_SUSPEND_RUNTIME=1
LM_AC_SUSPEND_RUNTIME=1
NOLM_AC_SUSPEND_RUNTIME=1

# Auto-Suspend timeout in seconds
# Number of seconds after which the USB devices should suspend
AUTOSUSPEND_TIMEOUT=2

So, in order to stop my laptop’s USB mouse, USB external keyboard and some internal USB devices from going to sleep when my laptop is only on battery power, I made the following change to a line in /etc/laptop-mode/conf.d/runtime-pm.conf:

# External keyboard at one office, internal Webcam, internal fingerprint sensor, Logitek NX50 notebook mouse
AUTOSUSPEND_RUNTIME_DEVID_BLACKLIST="03f0:0024 064e:a115 147e:1001 046d:c052"

My earlier post about Laptop Mode Tools explained one method for finding the device ID for each USB device, but the lsusb command can also be used:

# lsusb
Bus 002 Device 005: ID 03f0:0024 Hewlett-Packard KU-0316 Keyboard <---- External keyboard at one office
Bus 002 Device 004: ID 064e:a115 Suyin Corp. <---- Built-in Webcam
Bus 002 Device 003: ID 147e:1001 Upek TCS5B Fingerprint sensor <---- Built-in fingerprint sensor
Bus 002 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 046d:c052 Logitech, Inc. <----Logitech NX50 notebook mouse
Bus 001 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Although the Laptop Mode Tools usb-autosuspend module is supposed to be unused in 1.66, I edited /etc/laptop-mode/conf.d/usb-autosuspend.conf (which was not deleted by the 1.66 ebuild) and changed CONTROL_USB_AUTOSUSPEND="auto" to CONTROL_USB_AUTOSUSPEND="0" just to be on the safe side.

Fixing a problem with received video in Skype when using the AMD Catalyst (FGLRX) driver in Linux

Some users of Skype for Linux have reported that the bottom half of the received video image is corrupted in installations that use the closed-source video driver for ATI GPUs (the AMD Catalyst proprietary Linux driver, also known as the ‘FGLRX’ driver). One user described the lower half of the video image as “covered in small coloured squares like a chequer board”.

From what I have read in a few forums, it seems the problem does not occur when the open-source Radeon driver is used. My own experience corroborates that: I use the Radeon driver on one of my laptops, and received video in Skype is fine.

My main laptop has an AMD ATI Mobility Radeon HD 5650 GPU and I am using the Catalyst driver under Gentoo Linux. In this case there was a problem with received video in most Skype sessions. Either of the following effects usually occurred:

Snapshot 1 - Extract of received video image in Skype, showing an example of the corrupted image

Snapshot 1 - Extract of received video image in Skype, showing an example of the corrupted image

Snapshot 2 - Extract of received video image in Skype, showing another example of the corrupted image

Snapshot 2 - Extract of received video image in Skype, showing another example of the corrupted image

As shown in Snapshot 1, the lower half of the received video image was covered in a grid of thin green lines with areas tinged with purple, blue or green, whereas there was no grid of lines in the upper half of the image but some areas were tinged with red or blue.

As shown in Snapshot 2, the lower half of the received video image was covered in a grid of thin red lines, with a purple tinge in some areas, whereas there was no grid of lines in the upper half of the image, which looked reasonable but had some red-, green- or blue-tinged areas.

In all cases Skype’s thumbnail of my Webcam’s video image looked fine, and the person on the other end of the call said the video image received from me looked fine too.

Because of a bug in a previous version of the Catalyst driver a few years ago — see my blog posts Playing QuickTime videos in Firefox and Chromium + XVideo bug in AMD Catalyst 11.11 and 11.12 driver and AMD Catalyst for Linux driver 12.2 fixes the XVideo bug that crashed X.Org Server 1.11.x — I happen to know that Sykpe uses X11 overlays with the XVideo extension (xv), rather than using the OpenGL renderer (gl) or X11 with the SHM extension (x11). This made me wonder whether the use of XVideo with the Catalyst driver was causing the current problem. Unlike media players such as MPlayer and VLC, it is not possible to configure Skype to use gl or x11 instead of xv, so I thought it would not be possible to test whether the use of gl or x11 instead of xv would make a difference. Until, that is, I came upon a ‘trick’ posted by openSUSE user queequeg in 2009 during the period when an earlier version of the Catalyst driver had the aforementioned bug:

Skype Video Workaround for ATI

Anybody trying to make a video call with Skype and ATI fglrx drivers has had problems due to Skype using the “xv” video mode with the driver can’t handle. For anyone interested that is affected by this, there is a workaround:

1. Run the xvinfo command and look at the number of xv sessions available. Some cards have only 1, some have as many as 4. This is the number of xv occurances that the card can do at one time.
2. “Use up” all these xv sessions by opening videos in your favorite video player making sure to use xv for the video output. The videos can then be paused.
3. Once this (or they) are open, skype can be started and will default to X11 video and work properly with video calls.

I know this is a goofy way to get around this issue, but until fglrx can handle xv or skype allows an option to choose X11 for video render, I don’t know of any other way to do it.

(From what I hear, the 11.1 fglrx drivers can handle xv, but I haven’t confirmed this.)

So I tried his work-around. I had to launch four media players in order to use all available XVideo sessions. Lo and behold, when I launched Skype and made a video call the received video image was perfect. So it appeared that the Catalyst driver is not able to handle well the XVideo output from Skype. However, playing and pausing four videos every time I want to make a video call in Skype would hardly be practical, would it? And that is not the only downside: when I maximised a Firefox window during the Skype video call, my laptop spontaneously rebooted (I assume the X.Org server crashed).

I did also wonder whether just disabling compositing would solve the problem, so I disabled KWin Desktop Effects, but that didn’t make any difference.

I had also read in several forums that enabling or disabling the TexturedVideo and/or VideoOverlay options in the xorg.conf file have an effect on the video image produced by the Catalyst driver, but I could not find a post mentioning the use of either of those options to fix the specific problem I was seeing. So I decided not to pursue the xorg.conf route.

In my searches of the Web I came across a post somewhere that mentioned using GTK+ UVC Viewer (guvcview) to adjust video properties and improve video in Skype. I thought guvcview was only for adjusting the video image from a Webcam connected to my machine, i.e. adjusting the outgoing video image, and would not have any effect on received video. Nevertheless, I decided to install and launch guvcview to see if I could adjust both incoming and outgoing video properties. To my surprise, guvcview appeared to have fixed the problem with the received video. These are the steps I followed:

  1. I launched Skype and started a video call. The received video image had a grid of thin red lines and purple/green/blue tinting (similar to Snapshot 2).
  2. I Installed guvcview using the package manager.
  3. I launched guvcview in a Konsole (terminal) window. After guvcview created the file /home/fitzcarraldo/.config/guvcview/video0 and checked various video and audio settings it exited because my Webcam was being used by Skype (‘libv4l2: error setting pixformat: Device or resource busy‘).
  4. I clicked on the Webcam icon in the Skype call window, to turn my Webcam off.
  5. I launched guvcview again. The lower half of the received video image in Skype changed from a grid of thin red lines to a continuous green-coloured band, and the upper half of the image now looked reasonable but still had some red- or blue-tinged areas (see Snapshot 3 below).
  6. Snapshot 3 - Extract of received video image in Skype after I launched guvcview again

    Snapshot 3 - Extract of received video image in Skype after I launched guvcview again

  7. On the ‘Image Controls’ tab in the ‘GUVCViewer Controls’ window I changed the video frequency from 60 Hz to 50 Hz then back to 60 Hz again. I was just tinkering, and I believe this had no bearing on the outcome.
  8. I clicked on the ‘Quit’ button in the guvcview window to terminate the application.
  9. I clicked on the Webcam icon in the Skype call window to turn on again the Webcam, and the received Skype video image changed to a perfect image (see Snapshot 4 below).
  10. Snapshot 4 - Extract of received video image in Skype after I turned on again my Webcam in Skype

    Snapshot 4 - Extract of received video image in Skype after I turned on again my Webcam in Skype

It appears that guvcview had an effect on the received video image in Skype, although, if it did, I do not understand how. To check if the fix was permanent I ended the Skype video call, signed out of Skype and quit the application, rebooted and made a new Skype video call. The received video image in Skype was again perfect. I even deleted the guvcview configuration file and repeated this check, just in case the configuration file was somehow being used even though I had not launched guvcview, but the received video in yet another Skype video call was still perfect. I also clicked on the Webcam icon in the Skype call window several times during each call in order to turn my Webcam off and on several times; the received video image of the other person remained perfect.

So there you have it: when using an AMD ATI GPU and the Catalyst driver, it seems that guvcview can be used — at least in my case — to eliminate the type of image corruption in received Skype video shown in Snapshots 1 and 2. So, if you are also using the AMD Catalyst for Linux driver and are experiencing a similar problem, try guvcview. It might just do the trick.

Not all laptops are designed equal

Over time it is common for fans in laptops to become clogged with dust, fluff and even hair. The symptoms are usually a hotter laptop and a noisier fan that runs more frequently. The solution is to open up the laptop’s body in order to get at the fan and remove the crud with tweezers and by blowing. However, dismantling many laptops to access the fan makes the Mission Impossible break-in look simple, and this seems to be getting worse as laptop prices continue to decrease. If you are not confident you can unblock the fan yourself, you’ll have to find a local computer repair shop and you may find it’s not cheap. For some models the dismantling procedure can be so complicated that people post videos on YouTube. Often it is necessary to remove numerous screws, ribbon cables, jumper leads, plastic strips and the keyboard. In some cases you have to disassemble the laptop almost entirely. Fortunately, in the case of RAM modules there is often a hatch in the laptop’s base to facilitate access, but even adding or replacing RAM modules can sometimes be a major task (I used to own an Acer laptop that required the laptop base and keyboard to be removed in order to access the RAM modules).

Not long ago I had the misfortune to have to dismantle an Acer Aspire 5536-643G25Mn and a Toshiba Satellite C660-1J2 to remove accumulated fluff from the fans. I had to study YouTube videos carefully and could not believe how difficult it was to get access to the fan in the Acer Aspire. Dismantling the Toshiba Satellite to access the fan was not quite as bad as the Acer Aspire but was still a major task and, despite being as careful as possible, I still managed to break a fragile plastic lug on one of the base panels.

Last week my main laptop, a Compal NBLB2, seemed to be running a little hotter than usual, so I decided it was time to check if its fan also needed cleaning. What a pleasure that was in comparison to the other manufacturers’ laptops. The NBLB2 has a large plate in the base that, by removing only three screws (see the first photograph below), allows easy access to the fan and RAM modules. In less than five minutes I was able to remove a wad of fluff from the fan, replace the plate and power up the laptop again. Hats off to Compal for thinking about maintenance when designing this laptop. I only wish other laptop manufacturers did the same.

So, next time you need to buy a new laptop, do some research on how easy it will be to access the fan in case it needs to be cleaned. Look at the laptop’s base and check on the Web for a service manual, a YouTube video of it being disassembled, and comments in laptop/notebook forums. At least then you’ll know whether you stand a chance of avoiding paying a repair shop just to remove crud that inevitably builds up over time in the fan.

Base of Compal NBLB2 showing screws removed from main base plate

Base of Compal NBLB2 showing the 3 screws removed from the main base plate.

Base of Compal NBLB2 with main plate removed

Base of Compal NBLB2 with main plate removed. Notice how easy it is to access the fan and RAM modules.

How to prevent a USB mouse auto-suspending in Linux when a laptop’s power supply is disconnected

I found that my USB mouse (and external USB keyboard) went to sleep when the mains power supply was disconnected from my laptop. This was annoying because I had to click a mouse button and wait a couple of seconds in order to wake up the mouse. You can see from the console output below that several USB devices were being auto-suspended when I unplugged the laptop PSU:

# # PSU is currently connected.
# for d in /sys/bus/usb/devices/[0-9]* ; do if [[ -e $d/product ]] ; then echo -e "`basename $d`\t`cat $d/power/control`\t`cat $d/speed`\t`cat $d/product`" ; fi ; done
1-1.2 on 1.5 USB Laser Mouse
1-1.3 on 12 BCM2046 Bluetooth Device
2-1.2 on 12 Fingerprint Sensor
2-1.3 on 480 USB 2.0 Camera
2-1.6 on 1.5 USB Keyboard
# # Now I will disconnect the PSU...
# # PSU is currently disconnected.
# for d in /sys/bus/usb/devices/[0-9]* ; do if [[ -e $d/product ]] ; then echo -e "`basename $d`\t`cat $d/power/control`\t`cat $d/speed`\t`cat $d/product`" ; fi ; done
1-1.2 auto 1.5 USB Laser Mouse
1-1.3 auto 12 BCM2046 Bluetooth Device
2-1.2 auto 12 Fingerprint Sensor
2-1.3 auto 480 USB 2.0 Camera
2-1.6 auto 1.5 USB Keyboard
#

I found out the Vendor ID (046d) and Product ID (c052) of my Logitech NX50 USB portable/travel mouse by unplugging then reconnecting the USB mouse and using the dmesg command:

[13628.909728] usb 1-1.2: USB disconnect, device number 5
[13634.454132] usb 1-1.2: new low-speed USB device number 6 using ehci_hcd
[13634.535107] usb 1-1.2: New USB device found, idVendor=046d, idProduct=c052
[13634.535111] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[13634.535113] usb 1-1.2: Product: USB Laser Mouse
[13634.535115] usb 1-1.2: Manufacturer: Logitech
[13634.540168] input: Logitech USB Laser Mouse as /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/1-1.2:1.0/input/input17
[13634.540582] hid-generic 0003:046D:C052.0005: input,hidraw0: USB HID v1.10 Mouse [Logitech USB Laser Mouse] on usb-0000:00:1a.0-1.2/input0

First I tried creating a local Udev rule:

# cat /etc/udev/rules.d/91-local.rules
ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="USB Laser Mouse", ATTR{power/control}="on"

That didn’t stop the mouse from auto-suspending (and neither did “Logitech USB Laser Mouse” instead of “USB Laser Mouse”), so I tried creating a Udev rule specifying the Vendor ID and Product ID of the mouse:

# cat /etc/udev/rules.d/91-local.rules
ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="046d", ATTR{idProduct}=="c052", TEST=="power/control", ATTR{power/control}="on"

That didn’t stop the mouse from auto-suspending either.

Then I remembered that laptop-mode-tools is installed on my laptop:

# eix laptop-mode-tools
[I] app-laptop/laptop-mode-tools
Available versions: 1.60-r1 (~)1.62-r1 {(+)acpi apm bluetooth scsi}
Installed versions: 1.62-r1(18:10:15 11/01/13)(acpi bluetooth -apm -scsi)
Homepage: http://www.samwel.tk/laptop_mode/
Description: Linux kernel laptop_mode user-space utilities

So then I tried adding the mouse model to the blacklist in /etc/laptop-mode/conf.d/usb-autosuspend.conf by making AUTOSUSPEND_USBID_BLACKLIST="046d:c052" as shown below:

#
# Configuration file for Laptop Mode Tools module usb-autosuspend.
#
# For more information, consult the laptop-mode.conf(8) manual page.
#


###############################################################################
# USB autosuspend settings
# ------------------------
#
# If you enable this setting, laptop mode tools will automatically enable the
# USB autosuspend feature for all devices.
#
# NOTE: Some USB devices claim they support autosuspend, but implement it in a
# broken way. This can mean keyboards losing keypresses, or optical mice turning
# their LED completely off. If you have a device that misbehaves, add its USB ID
# to the blacklist below and complain to your hardware vendor.
################################################################################

# Enable debug mode for this module
# Set to 1 if you want to debug this module
DEBUG=0

# Enable USB autosuspend feature?
# Set to 0 to disable
CONTROL_USB_AUTOSUSPEND="auto"

# Set this to use opt-in/whitelist instead of opt-out/blacklist for deciding
# which USB devices should be autosuspended.
# AUTOSUSPEND_USE_WHITELIST=0 means AUTOSUSPEND_*_BLACKLIST will be used.
# AUTOSUSPEND_USE_WHITELIST=1 means AUTOSUSPEND_*_WHITELIST will be used.
AUTOSUSPEND_USE_WHITELIST=0

# The list of USB IDs that should not use autosuspend. Use lsusb to find out the
# IDs of your USB devices.
# Example: AUTOSUSPEND_USBID_BLACKLIST="046d:c025 0123:abcd"
AUTOSUSPEND_USBID_BLACKLIST="046d:c052"

# The list of USB driver types that should not use autosuspend.  The driver
# type is given by "DRIVER=..." in a USB device's uevent file.
# Example: AUTOSUSPEND_USBID_BLACKLIST="usbhid usb-storage"
AUTOSUSPEND_USBTYPE_BLACKLIST=""

# The list of USB IDs that should use autosuspend. Use lsusb to find out the
# IDs of your USB devices.
# Example: AUTOSUSPEND_USBID_WHITELIST="046d:c025 0123:abcd"
AUTOSUSPEND_USBID_WHITELIST=""

# The list of USB driver types that should use autosuspend.  The driver
# type is given by "DRIVER=..." in a USB device's uevent file.
# Example: AUTOSUSPEND_USBTYPE_WHITELIST="usbhid usb-storage"
AUTOSUSPEND_USBTYPE_WHITELIST=""

# Trigger auto-suspension of the USB deivce under conditional circumstances
BATT_SUSPEND_USB=1
LM_AC_SUSPEND_USB=0
NOLM_AC_SUSPEND_USB=0

# USB Auto-Suspend timeout in seconds
# Number of seconds after which the USB devices should suspend
AUTOSUSPEND_TIMEOUT=2

And now the mouse no longer suspends when I unplug the PSU:

# # PSU is currently connected.
# for d in /sys/bus/usb/devices/[0-9]* ; do if [[ -e $d/product ]] ; then echo -e "`basename $d`\t`cat $d/power/control`\t`cat $d/speed`\t`cat $d/product`" ; fi ; done
1-1.2 on 1.5 USB Laser Mouse
1-1.3 on 12 BCM2046 Bluetooth Device
2-1.2 on 12 Fingerprint Sensor
2-1.3 on 480 USB 2.0 Camera
2-1.6 on 1.5 USB Keyboard
# # Now I will disconnect the PSU...
# # PSU is currently disconnected.
# for d in /sys/bus/usb/devices/[0-9]* ; do if [[ -e $d/product ]] ; then echo -e "`basename $d`\t`cat $d/power/control`\t`cat $d/speed`\t`cat $d/product`" ; fi ; done
1-1.2 on 1.5 USB Laser Mouse
1-1.3 auto 12 BCM2046 Bluetooth Device
2-1.2 auto 12 Fingerprint Sensor
2-1.3 auto 480 USB 2.0 Camera
2-1.6 auto 1.5 USB Keyboard
# # Now I will reconnect the PSU...
# # PSU is currently connected.
# for d in /sys/bus/usb/devices/[0-9]* ; do if [[ -e $d/product ]] ; then echo -e "`basename $d`\t`cat $d/power/control`\t`cat $d/speed`\t`cat $d/product`" ; fi ; done
1-1.2 on 1.5 USB Laser Mouse
1-1.3 on 12 BCM2046 Bluetooth Device
2-1.2 on 12 Fingerprint Sensor
2-1.3 on 480 USB 2.0 Camera
2-1.6 on 1.5 USB Keyboard
#

So configuring laptop-mode-tools solved the problem with the mouse. Mind you, I will probably simply make CONTROL_USB_AUTOSUSPEND="no" in /etc/laptop-mode/conf.d/usb-autosuspend.conf, as I don’t want the internal USB devices in my laptop (Bluetooth adapter, fingerprint sensor and Webcam) to auto-suspend either.

UPDATE October 22, 2014: Version 1.65 and upwards of Laptop Mode Tools functions in a different way to earlier versions, so please see my post Laptop Mode Tools revisited due to a change in its functionality regarding the new way of configuring Laptop Mode Tools to stop USB devices auto-suspending.

AMD Catalyst for Linux driver 12.2 fixes the XVideo bug that crashed X.Org Server 1.11.x

Just a brief ‘heads up’ for users of the closed-source FGLRX driver in Linux: In a previous blog post I mentioned a bug in the AMD Catalyst driver for Linux that caused X.Org Server 1.11.x to crash if you tried to play a video and your media player was configured to use XVideo (Xv) output. The bug also meant that people talking to you via Skype could not enable their Web cams or X.Org Server 1.11.x would crash on your machine, as Skype uses XVideo.

The problem occurred with versions 11.11, 11.12 and 12.1 of the FGLRX driver (the package x11-drivers/ati-drivers). Well, today I installed version 12.2 of the driver and am pleased to report that I can again set media players to use Xv output without causing the X.Org Server to crash (I’m currently using xorg-server-1.11.4). Likewise, other people who I am talking to via Skype can again enable their Web cams without causing the X.Org Server on my machine to crash.

Follow

Get every new post delivered to your Inbox.

Join 52 other followers