суббота, 27 апреля 2013 г.

HP Pavilion dv6-3155sr и Kubuntu


Привет всем!

Сегодня я покажу как увеличить время автономной работы на примере ноутбука HP Pavilion dv6-3155sr. Ноутбук имеет 2 видеокарты: встроенную (Intel GMA HD 3000) и дискретную (ATI Mobility Radeon HD 5650M). Под виндой эти видеокарты переключаются между собой при подключении к сети и отключении от нее. Но сначала небольшая прелюдия :)

С момента покупки ноута - работал в винде. В связи с тем что я занимаюсь веб-разработкой да и вся работа заточена под Linux - необходимо постоянно иметь настроенную для этого дела среду. До этого момента все время пользовался виртуалкой от VMWare, но последнее время все большие тормоза в ней начали надоедать (да, знаю про всякие тюнинги, улучшайзинги, но все они мало помогали). С этого момента решил поставить рядом с виндой Ubuntu 11.10. Обычно я юзаю только LTS-релизы, но в текущем 10.04 - очень плохая поддержка Wi-Fi и переключаемой графики для этого ноута, да и общая работа системы не радовала. Хотелось иметь максимально возможную поддержку оборудования. В общем терпеть до 12.04 больше сил не хватило - поставил 11.10. Вот так :)

Короче хватит трепа, перейдем к основной задаче. Итак, чего мы хотим добиться:

  1. Иметь возможность отключить дискретную графику (в связи с тем что линух мне нужен только для работы, поэтому дискретная графика не нужна).
  2. Максимально возможное время автономной работы.
  3. Автоматизировать переключение между режимами.

Отключаем дискретную графику

Сначала необходимо узнать распознала ли система наши видяхи:

# lspci | grep VGA
00:02.0 VGA compatible controller: Intel Corporation Core Processor

Integrated Graphics Controller (rev 02) 01:00.0 VGA compatible controller: ATI Technologies Inc Madison
[AMD Radeon HD 5000M Series] (rev ff)


Как видно, мои карточки успешно подхватились. Никаких дополнительных манипуляций после установки системы я не производил. Хочу отметить, что переключение между картами (а также их отключение) работает, только если в ядре включен флаг vga_switcheroo. Это можно проверить командой:

# grep -i switcheroo /boot/config-3.*
/boot/config-3.0.0-12-generic:CONFIG_VGA_SWITCHEROO=y
/boot/config-3.0.0-16-generic:CONFIG_VGA_SWITCHEROO=y


Также данный флаг работает только с опенсорсными дровами (radeon - для ATI'шных видеокарт и nouveau - для NVIDIA'вских). С проприетарными дровами nvidia и fglrx работать эта фича не будет.

И последний тест того что vga_switcheroo работает:

# ls -l /sys/kernel/debug/vgaswitcheroo/switch
-rw-r--r-- 1 root root 0 2012-02-26 13:02 /sys/kernel/debug/vgaswitcheroo/switch

Итак, все что нужно для переключения видеокарт - работает.

Теперь проверим какая видеокарта сейчас работает:

# cat /sys/kernel/debug/vgaswitcheroo/switch
0:IGD: :Pwr:0000:00:02.0
1:DIS:+:Pwr:0000:01:00.0


Как видим на данный момент подключены обе видеокарты, но вывод производится через дискретную.

"Pwr" означает, что видеокарта подключена, "+" - видеокарта используется в данный момент.

Нам необходимо полностью отключить дискретную видеокарту и использовать интегрированную. Делаем следующее:

# echo DIGD > /sys/kernel/debug/vgaswitcheroo/switch

Переключение видеокарты происходит только после рестарта сессии X-Window. Это можно сделать просто выходом и текущего сеанса, и войти снова. Но у меня даже после этого переключение не происходило, помогал только рестарт системы. В итоге мы получаем такую картину:

# cat /sys/kernel/debug/vgaswitcheroo/switch
0:IGD:+:Pwr:0000:00:02.0
1:DIS: :Off:0000:01:00.0


Дабы закрепить результат, чтобы настройки применялись при каждом запуске системы добавим пару команд в /etc/rc.local перед командой exit 0:

# nano /etc/rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
echo IGD > /sys/kernel/debug/vgaswitcheroo/switch
echo OFF > /sys/kernel/debug/vgaswitcheroo/switch
exit 0


Теперь при загрузке системы интегрированная карта будет активирована, а дискретная - выключится.

Увеличиваем время автономной работы

Есть такой очень полезный ресурс: LessWatts.org

Большинство советов бралось оттуда, которые в итоге очень помогли и действительно увеличили время автономной работы, ну и некоторые - из просторов интернета. В конце данной главы я представлю конечный скрипт со всеми настройками.

Тюнинг планировщика ядра

В линуксовых ядрах выше 2.6.18 планировщик имеет одну полезную для энергосбережения опцию, а именно: sched_mc_power_savings

# cat /sys/devices/system/cpu/sched_mc_power_savings 0

Значение в файле sched_mc_power_savings может быть равно 0 или 1. Значение по умолчанию — 0. При установленном параметре "1" планировщик попытается загрузить работой наименьшее возможное количество ядер, чтобы остальные оставались свободны. Другими словами, если каждый процессор немного загружен, sched_mc_power_savings старается сконцентрировать эту работу на минимально возможном количестве процессоров. Это в свою очередь даёт возможность чуть дольше "передохнуть" некоторым процессорам, что экономит энергию, особенно если процессор поддерживает какие-либо режимы глубокого сна, например, режимы C (режим "почти полного бездействия". Подробнее читайте здесь), которые потребляют в простое крайне малое количество энергии. Итоговая экономия может зависеть от многих факторов, включая то, какое количество процессоров доступно в системе и какой из регуляторов работает. При установленном значении "0" планировщик не действует.

Настройка регуляторов частоты ЦП

Чтобы по максимуму использовать энергосбережение процессора и иметь возможность регулировать частоту его работы в реальном времени, в ядрах 2.6.18 и выше реализована подсистема CPUfreq, которая и позволяет динамически изменять данный параметр. Чтобы узнать поддержку, воспользуемся командой:

# cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors conservative ondemand userspace powersave performance

Как видим предусмотрено 5 разных регуляторов:

performance
Данный регулятор настраивает процессор на максимально высокую частоту независимо от нагрузки.

ondemand
Регулятор ondemand проверяет уровень использования процессора, и если определённый порог превышен, регулятор выставляет наиболее высокую частоту из доступных. В случае, если процент использования ниже порога, регулятор понижает частоту до следующей возможной отметки.

conservative
Регулятор conservative впервые появился в ядре версии 2.6.12, он базируется на регуляторе ondemand. Он тоже динамически настраивает частоты в зависимости от загрузки процессора, однако ведёт себя немного по-другому и даёт возможность увеличивать мощность постепенно. Регулятор conservative проверяет процент использования процессора и в случае, если значение выходит за нижний или верхний порог, постепенно повышает или понижает частоту до следующей возможной, вместо того чтобы сразу установить наивысшую частоту, как это делает регулятор ondemand.

userspace
Ручная настройка частоты.
powersave
Регулятор powersave, в противоположность performance'у, статически настраивает процессор на самую низкую из доступных частот. В нем также можно настроить диапазон доступных частот. Назначение его – постоянная работа на самой низкой из возможных частот. Очевидно, что в этом случае на производительность влияет тот факт, что система никогда не будет использовать более высокую частоту, независимо от степени занятости процессора(ов).
На практике этот регулятор часто не дает экономии энергии, поскольку самая большая экономия достигается за счет использования режимов C-state (режим "почти полного бездействия". Подробнее читайте здесь). Использование регулятора powersave увеличивает время работы процесса, поскольку он будет использовать наименьшую частоту; в результате система дольше не перейдет в состояние простоя и потому не получит экономию от вхождения в режим C-state.

В данном ноуте установлен Intel Core i5-460M, который имеет 2 реальных и 4 логических ядра, поэтому у меня конфигурация такая:

# ls -l /sys/devices/system/cpu/ | grep cpu.$
drwxr-xr-x 7 root root 0 2012-02-26 15:34 cpu0
drwxr-xr-x 7 root root 0 2012-02-26 15:34 cpu1
drwxr-xr-x 7 root root 0 2012-02-26 15:34 cpu2
drwxr-xr-x 7 root root 0 2012-02-26 15:34 cpu3


Мы будем использовать регулятор ondemand:

# echo ondemand > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
# echo ondemand > /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor
# echo ondemand > /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor
# echo ondemand > /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor

Энергосбережение для SATA-устройств

В ядрах выше 2.6.25 появилась возможность включать энергосберегающий режим для SATA-интерфейсов (ALPM - Aggressive Link Power Management), когда на них долгое время не производятся операции ввода\вывода.

Чтобы проверить возможность управления питанием SATA-интерфейсов, выполним команду:

# cat /sys/class/scsi_host/host0/link_power_management_policy
max_performance


link_power_management_policy может принимать 2 значения: max_performance и min_power.

В данном ноуте аж 6 штук SATA'шных интерфейсов:

# ls -l /sys/class/scsi_host/ | grep host.$
lrwxrwxrwx 1 root root 0 2012-02-26 15:34 host0 -> ../../devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0
lrwxrwxrwx 1 root root 0 2012-02-26 15:34 host1 -> ../../devices/pci0000:00/0000:00:1f.2/host1/scsi_host/host1
lrwxrwxrwx 1 root root 0 2012-02-26 15:34 host2 -> ../../devices/pci0000:00/0000:00:1f.2/host2/scsi_host/host2
lrwxrwxrwx 1 root root 0 2012-02-26 15:34 host3 -> ../../devices/pci0000:00/0000:00:1f.2/host3/scsi_host/host3
lrwxrwxrwx 1 root root 0 2012-02-26 15:34 host4 -> ../../devices/pci0000:00/0000:00:1f.2/host4/scsi_host/host4
lrwxrwxrwx 1 root root 0 2012-02-26 15:34 host5 -> ../../devices/pci0000:00/0000:00:1f.2/host5/scsi_host/host5


И для всех можно установить режим энергосбережения.

Энергосбережение для звуковых карт Intel HDA (High Definition Audio)

Проверить наличие такой возможности можно командой:

# ls -l /sys/module/snd_hda_intel/parameters/power_save
-rw-r--r-- 1 root root 4096 2012-02-26 15:34 /sys/module/snd_hda_intel/parameters/power_save


power_save может иметь значение "0" (энергосбережение выключено) или больше. Обычно используют значения "0" или "10".

Оптимизация дисковой подсистемы

dirty_ratio
Максимальный размер памяти для хранения данных которые будут в итоге записаны (сброшены) на диск. Чем выше значение, тем реже производится запись.# cat /proc/sys/vm/dirty_ratio 10
Значение "10" можно ставить при работе от сети и "90" - при работе от батареи.

dirty_background_ratio
Минимальный размер памяти где будут храниться данные перед записью на диск. Желательно выставлять намного меньше чем dirty_ratio.# cat /proc/sys/vm/dirty_background_ratio 5
При работе от сети - "5", при работе от батареи - "1".

dirty_writeback_centisecs
Как часто ядро должно проверять есть ли данные для записи на диск. Чем выше значение, тем реже используется диск для записи данных.

# cat /proc/sys/vm/dirty_writeback_centisecs 500

Я ставлю "500" - при работе от сети и "60000" при работе от батареи.
Энергосбережение для PCI Express

# cat /sys/module/pcie_aspm/parameters/policy
[default] performance powersave


Начиная с версий ядер 2.6.39 данную нельзя менять, но это можно обойти, включив опцию ядра pcie_aspm:

# nano /etc/default/grub
# If you change this file, run 'update-grub' afterwards to update
# /boot/grub/grub.cfg.
# For full documentation of the options in this file, see:
# info -f grub -n 'Simple configuration'
GRUB_DEFAULT=0 #GRUB_HIDDEN_TIMEOUT=0 GRUB_HIDDEN_TIMEOUT_QUIET=true GRUB_TIMEOUT=10 GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian` GRUB_CMDLINE_LINUX_DEFAULT="quiet splash pcie_aspm=force"
.....


ВНИМАНИЕ!!! Обязательно убедитесь, что ваш PCI Express может менять режимы и имеет такую функциональность. Если не уверены - лучше не менять.

В данном ноутбуке такая функциональность предусмотрена, поэтому после перезагрузки можем менять режимы:

# echo default > /sys/module/pcie_aspm/parameters/policy
# echo powersave > /sys/module/pcie_aspm/parameters/policy
# echo performance > /sys/module/pcie_aspm/parameters/policy

Автоматизируем...

В Убунте есть один прекрасный скрипт который выполняется при переключении режимов. Он лежит здесь:

# cat /etc/acpi/power.sh
#!/bin/sh
test -f /usr/share/acpi-support/key-constants || exit 0
. /usr/share/acpi-support/policy-funcs
if [ -z "$*" ] && ( [ `CheckPolicy` = 0 ] || CheckUPowerPolicy ); then
  exit;
fi
pm-powersave $*


Итак, изучив кучу опций по энергосбережению в Линуксе собираем это все вместе. Представляю итоговый скрипт:

#!/bin/sh
if on_ac_power; then
 echo 0 > /proc/sys/vm/laptop_mode
 echo 10 > /proc/sys/vm/dirty_ratio
 echo 5 > /proc/sys/vm/dirty_background_ratio
 echo 500 > /proc/sys/vm/dirty_writeback_centisecs
 echo 0 > /sys/module/snd_hda_intel/parameters/power_save
 echo max_performance > /sys/class/scsi_host/host0/link_power_management_policy
 echo max_performance > /sys/class/scsi_host/host1/link_power_management_policy
 echo max_performance > /sys/class/scsi_host/host2/link_power_management_policy
 echo max_performance > /sys/class/scsi_host/host3/link_power_management_policy
 echo max_performance > /sys/class/scsi_host/host4/link_power_management_policy
 echo max_performance > /sys/class/scsi_host/host5/link_power_management_policy
 echo ondemand > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
 echo ondemand > /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor
 echo ondemand > /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor
 echo ondemand > /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor
 echo default > /sys/module/pcie_aspm/parameters/policy
 echo 0 > /sys/devices/system/cpu/sched_mc_power_savings
else
 echo 5 > /proc/sys/vm/laptop_mode
 echo 90 > /proc/sys/vm/dirty_ratio
 echo 1 > /proc/sys/vm/dirty_background_ratio
 echo 60000 > /proc/sys/vm/dirty_writeback_centisecs
 echo 10 > /sys/module/snd_hda_intel/parameters/power_save
 echo min_power > /sys/class/scsi_host/host0/link_power_management_policy
 echo min_power > /sys/class/scsi_host/host1/link_power_management_policy
 echo min_power > /sys/class/scsi_host/host2/link_power_management_policy
 echo min_power > /sys/class/scsi_host/host3/link_power_management_policy
 echo min_power > /sys/class/scsi_host/host4/link_power_management_policy
 echo min_power > /sys/class/scsi_host/host5/link_power_management_policy
 echo ondemand > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
 echo ondemand > /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor
 echo ondemand > /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor
 echo ondemand > /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor
 echo powersave > /sys/module/pcie_aspm/parameters/policy
 echo 1 > /sys/devices/system/cpu/sched_mc_power_savings
fi

test -f /usr/share/acpi-support/key-constants || exit 0

. /usr/share/acpi-support/policy-funcs

if [ -z "$*" ] && ( [ `CheckPolicy` = 0 ] || CheckUPowerPolicy ); then
 exit;
fi

pm-powersave $*


На всякий случай делаем:

# chmod +x /etc/acpi/power.sh

Напоследок могу посоветовать очень полезную тулзу powertop с помощью которой вы можете еще более тоньше оптимизировать работу своей системы.

И вот некоторые доказательства полезности данных манипуляций. Вот что было до оптимизации:

А это после:
Результат налицо! :)