This is the motto of the FreeBSD operating system – The Power to Serve – which also greatly fits for the topic of this article. Decade ago (yes time flies) I even made a wallpaper with this motto – still available on the DeviatArt page.
Time for FreeBSD article covering its power management features. It also applies to FreeBSD Desktop series but its not limited to it. Popular opinion seems to be that FreeBSD is so server oriented that it lacks any power management mechanisms. Nothing more far from the truth. While less important on the desktop (but will still lower your electricity bill) or servers it is desirable to properly configure power management on laptops to so they will have longer battery life and will run more quiet.
I write this as the FreeBSD Handbook does not cover all that information in the 11.13. Power and Resource Management chapter. The FreeBSD on Laptops article part 4. Power Management is from the ancient times of FreeBSD 10.1-RELEASE. There is some information on the FreeBSD Wiki page but parts of it are outdated.
FreeBSD offers many mechanisms in the power management department:
- power off devices without attached driver
- scale CPU frequency and power
- supports CPU sleep states (C1/C1E/C2/C3/…)
- enabling/disabling Turbo Mode available in most CPUs
- per USB device power management options
- SATA/AHCI channels/controllers power management
- suspend/resume support (along with using laptop lid for it)
- support for vendor specific tools that help to measure power management
- tools and ACPI support for fan speed control
- tools and ACPI support for setting screen brightness
- battery capacity status and running time estimation
- network interfaces power saving options
- support for AMD PowerNow!
- support for Intel (Enhanced) SpeedStep
- support for Intel Speed Shift
- support for AMD Turbo Core
- support for Intel Turbo Boost
One word about different files for the settings in the FreeBSD system:
- /etc/rc.conf – does not require reboot just daemons reloading
- /etc/sysctl.conf – does not require reboot – you can set them at runtime
- /boot/loader.conf – these settings REQUIRE reboot
Here is the Table of Contents (non-clickable) for the article.
- Information
- Battery
- Battery Wear
- CPU
- lscpu(1)
- dmesg(8)
- CPU Frequency Scaling
- powerd(8)
- powerdxx(8)
- C-States
- CPU Turbo Mode
- USB Devices
- SATA/AHCI Power Management
- Devices without Driver
- Nvidia Optimus
- Suspend and Resume
- Network Interfaces
- Vendor Tools
- DTrace
- Other
- ZFS
- Applications
- Hardware
- UPDATE 1 – Graphics Card Power Saving
- UPDATE 2 – AMD CPU Temperatures
- UPDATE 3 – Suspend/Resume Tips
- UPDATE 4 – Intel Speed Shift
Information
Let’s start by describing where to get needed information about current CPU speed, used C-states, current power management modes for USB devices, battery capacity and remaining time, etc.
Battery
To get battery information you can use the acpiconf(8) tool. This is the acpiconf(8) output for my main battery (in the ThinkPad T420s laptop) with AC power attached.
% acpiconf -i 0 Design capacity: 44000 mWh Last full capacity: 37930 mWh Technology: secondary (rechargeable) Design voltage: 11100 mV Capacity (warn): 1896 mWh Capacity (low): 200 mWh Low/warn granularity: 1 mWh Warn/full granularity: 1 mWh Model number: 45N1037 Serial number: 28608 Type: LION OEM info: SANYO State: high Remaining capacity: 100% Remaining time: unknown Present rate: 0 mW Present voltage: 12495 mV
… and with AC power detached.
% acpiconf -i 0 Design capacity: 44000 mWh Last full capacity: 37930 mWh Technology: secondary (rechargeable) Design voltage: 11100 mV Capacity (warn): 1896 mWh Capacity (low): 200 mWh Low/warn granularity: 1 mWh Warn/full granularity: 1 mWh Model number: 45N1037 Serial number: 28608 Type: LION OEM info: SANYO State: high Remaining capacity: 100% Remaining time: 2:31 Present rate: 0 mW Present voltage: 12492 mV
Now as AC power is detached from the laptop the Remaining time: field will show you remaining time estimation for this single battery shows as 2:31 here (two hours and thirty one minutes).
Below is acpiconf(8) output for my secondary battery (in ThinkPad T420s ultrabay instead of DVD drive).
% acpiconf -i 1 Design capacity: 31320 mWh Last full capacity: 24510 mWh Technology: secondary (rechargeable) Design voltage: 10800 mV Capacity (warn): 1225 mWh Capacity (low): 200 mWh Low/warn granularity: 1 mWh Warn/full granularity: 1 mWh Model number: 45N1041 Serial number: 260 Type: LiP OEM info: SONY State: high Remaining capacity: 100% Remaining time: unknown Present rate: 0 mW Present voltage: 12082 mV
… and with AC power detached.
% acpiconf -i 1 Design capacity: 31320 mWh Last full capacity: 24510 mWh Technology: secondary (rechargeable) Design voltage: 10800 mV Capacity (warn): 1225 mWh Capacity (low): 200 mWh Low/warn granularity: 1 mWh Warn/full granularity: 1 mWh Model number: 45N1041 Serial number: 260 Type: LiP OEM info: SONY State: discharging Remaining capacity: 98% Remaining time: 1:36 Present rate: 14986 mW Present voltage: 11810 mV
With AC power detached it shows the Remaining time: as 1:36 for the secondary battery.
So its total 4:07 time on battery estimated. The same time in minutes (247) will be shown in the sysctl(8) value named hw.acpi.battery.time as shown below.
% sysctl hw.acpi.battery.time hw.acpi.battery.time: 247
You can also get more ‘complete’ battery information with below sysctl(8) values under hw.acpi.battery MIB.
% sysctl hw.acpi.battery hw.acpi.battery.info_expire: 5 hw.acpi.battery.units: 2 hw.acpi.battery.state: 1 hw.acpi.battery.time: 247 hw.acpi.battery.life: 99
The hw.acpi.battery.time will show you ‘-1‘ value if you have AC power attached.
% sysctl hw.acpi.battery hw.acpi.battery.info_expire: 5 hw.acpi.battery.units: 2 hw.acpi.battery.state: 0 hw.acpi.battery.time: -1 hw.acpi.battery.life: 100
Battery Wear
As time passes by batteries lose their ‘design’ capacity. After 1-2 years such battery can have only 70% or less of its original efficiency.
All the information needed to check that is provided by the acpiconf(8) command with Design capacity: and Last full capacity: values. I have made a battery-capacity.sh script that will tell you what the current battery efficiency is. Here is how it looks in action.
% battery-capacity.sh 0 Battery '0' model '45N1037' has efficiency: 86% % battery-capacity.sh 1 Battery '1' model '45N1041' has efficiency: 78%
Here is the battery-capacity.sh script itself.
#! /bin/sh if [ ${#} -ne 1 ] then echo "usage: ${0##*/} BATTERY" exit fi if acpiconf -i ${1} 1> /dev/null 2> /dev/null then DATA=$( acpiconf -i ${1} ) MAX=$( echo "${DATA}" | grep '^Design\ capacity:' | awk -F ':' '{print $2}' | tr -c -d '0-9' ) NOW=$( echo "${DATA}" | grep '^Last\ full\ capacity:' | awk -F ':' '{print $2}' | tr -c -d '0-9' ) MOD=$( echo "${DATA}" | grep '^Model\ number:' | awk -F ':' '{print $2}' | awk '{print $1}' ) echo -n "Battery '${1}' model '${MOD}' has efficiency: " printf '%1.0f%%\n' $( bc -l -e "scale = 2; ${NOW} / ${MAX} * 100" -e quit ) else echo "NOPE: Battery '${1}' does not exists on this system." echo "INFO: Most systems has only '0' or '1' batteries." exit 1 fi
CPU
To get information about current CPU’s you will have to use dev.cpu MIB or dev.cpu.0 for the first physical CPU core.
% sysctl dev.cpu.0 dev.cpu.0.cx_method: C1/hlt C2/io dev.cpu.0.cx_usage_counters: 412905 0 dev.cpu.0.cx_usage: 100.00% 0.00% last 290us dev.cpu.0.cx_lowest: C1 dev.cpu.0.cx_supported: C1/1/1 C2/3/104 dev.cpu.0.freq_levels: 2501/35000 2500/35000 2200/29755 2000/26426 1800/23233 1600/20164 1400/17226 1200/14408 1000/11713 800/9140 dev.cpu.0.freq: 800 dev.cpu.0.%parent: acpi0 dev.cpu.0.%pnpinfo: _HID=none _UID=0 dev.cpu.0.%location: handle=\_PR_.CPU0 dev.cpu.0.%driver: cpu dev.cpu.0.%desc: ACPI CPU
If you load the coretemp(4) kernel module with kldload(8) command you will get additional temperature information.
Below is same sysctl(8) dev.cpu.0 MIB with coretemp(4) kernel module loaded.
% sysctl dev.cpu.0 dev.cpu.0.temperature: 49.0C dev.cpu.0.coretemp.throttle_log: 0 dev.cpu.0.coretemp.tjmax: 100.0C dev.cpu.0.coretemp.resolution: 1 dev.cpu.0.coretemp.delta: 51 dev.cpu.0.cx_method: C1/hlt C2/io dev.cpu.0.cx_usage_counters: 16549 0 dev.cpu.0.cx_usage: 100.00% 0.00% last 1489us dev.cpu.0.cx_lowest: C1 dev.cpu.0.cx_supported: C1/1/1 C2/3/104 dev.cpu.0.freq_levels: 2501/35000 2500/35000 2200/29755 2000/26426 1800/23233 1600/20164 1400/17226 1200/14408 1000/11713 800/9140 dev.cpu.0.freq: 800 dev.cpu.0.%parent: acpi0 dev.cpu.0.%pnpinfo: _HID=none _UID=0 dev.cpu.0.%location: handle=\_PR_.CPU0 dev.cpu.0.%driver: cpu dev.cpu.0.%desc: ACPI CPU
Let me describe some most useful ones.
CPU core temperature.
dev.cpu.0.temperature: 49.0C
CPU supported C-states (C1 and C2 for this CPU).
dev.cpu.0.cx_supported: C1/1/1 C2/3/104
CPU statistics for C-states usage (only C1 state been used).
dev.cpu.0.cx_usage_counters: 16549 0
dev.cpu.0.cx_usage: 100.00% 0.00% last 1489us
CPU maximum (most deep) C state enabled.
dev.cpu.0.cx_lowest: C1
CPU supported frequency levels with power usage after the ‘/‘ character. The 2500/35000 can be read as 2.5 GHz frequency with 35 W power usage and 2501 is the Turbo Mode. The lowest is 800 MHz with about 9 W usage.
dev.cpu.0.freq_levels: 2501/35000 2500/35000 2200/29755 2000/26426 1800/23233 1600/20164 1400/17226 1200/14408 1000/11713 800/9140
CPU current frequency (will vary when You use powerd(8) or powerdxx(8) daemon).
dev.cpu.0.freq: 800
The hw.acpi.thermal.tz0.temperature MIB will also show you current thermal zone temperature.
% sysctl hw.acpi.thermal.tz0.temperature hw.acpi.thermal.tz0.temperature: 49.1C
To check how many cores you have use these commands.
% grep FreeBSD/SMP /var/run/dmesg.boot FreeBSD/SMP: Multiprocessor System Detected: 2 CPUs FreeBSD/SMP: 1 package(s) x 2 core(s) % sysctl kern.smp.cpus kern.smp.cpus: 2
If my description does not feel useful then you should also check the -d flag for sysctl(8) command as shown below.
% sysctl -d dev.cpu.0.freq dev.cpu.0.freq: Current CPU frequency
lscpu(1)
There is also third party tool called lscpu(8) that will describe your CPU features and model. You will have to add it from packages.
# pkg install lscpu
To make lscpu(8) work the cpuctl(4) kernel module is needed.
Here is how it looks for my dual core CPU.
# kldload cpuctl # lscpu Architecture: amd64 Byte Order: Little Endian Total CPU(s): 2 Thread(s) per core: 2 Core(s) per socket: 2 Socket(s): 0 Vendor: GenuineIntel CPU family: 6 Model: 42 Model name: Intel(R) Core(TM) i5-2520M CPU @ 2.50GHz Stepping: 7 L1d cache: 32K L1i cache: 32K L2 cache: 256K L3 cache: 3M Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 cflsh ds acpi mmx fxsr sse sse2 ss htt tm pbe sse3 pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline aes xsave osxsave avx syscall nx rdtscp lm lahf_lm
dmesg(8)
Also dmesg(8) command (or /var/run/dmesg.boot file after longer uptime) covers your CPU model and features information.
% grep CPU /var/run/dmesg.boot CPU: Intel(R) Core(TM) i5-2520M CPU @ 2.50GHz (2491.97-MHz K8-class CPU) FreeBSD/SMP: Multiprocessor System Detected: 2 CPUs cpu0: on acpi0 coretemp0: on cpu0
CPU Frequency Scaling
For CPU scaling feature you may use the powerd(8) daemon available in the FreeBSD base system or powerdxx(8) from the FreeBSD Ports or packages. The powerdxx(8) daemon aims to better scale multicore systems and not turning all cores to high state when there is moderate load on the system but some people may prefer that approach to have full power available when they do anything and to save power when they do nothing. Thus powerd(8) is not better then powerdxx(8) or vice versa. They are just different so that gives you more options for your needs.
No matter which one you will choose it has to be configured in the /etc/rc.conf file.
powerd(8)
Here are the options for powerd(8) daemon.
powerd_enable=YES powerd_flags="-n adaptive -a hiadaptive -b adaptive -m 800 -M 1600"
The -n option of for the unknown state – if for some reason the powerd(8) will not be able to determine if you are running on the AC power or battery. The -a is for AC power and -b for running on the battery. The adaptive setting is less ‘aggressive’ so its more battery time friendly. The hiadaptive is more aggressive this its preferred when you are running on AC power. The -m option sets minimum CPU frequency to be used and -M the maximum. Both in MHz units. Check powerd(8) man page for more details.
powerdxx(8)
First you will need to install it.
# pkg install powerdxx
Then its options are identical as those of powerd(8) daemon.
powerdxx_enable=YES powerdxx_flags="-n adaptive -a hiadaptive -b adaptive -m 800 -M 1600"
Check the powerdxx(8) section above for the flags/parameters description.
Decade ago CPU frequency scaling on FreeBSD was not that ‘easy’ as it is now, you may check my old HOWTO: FreeBSD CPU Scaling and Power Saving in that topic from 2008.
C-States
The C-states can be configured in the /etc/rc.conf file with these options.
- performance_cx_lowest
- economy_cx_lowest
The economy_cx_lowest parameter is for running on battery and performance_cx_lowest parameter is for running on AC power. Both are set using the /etc/rc.d/power_profile script used by rc(8) subsystem. It sets the hw.acpi.cpu.cx_lowest parameter which sets/controls all dev.cpu.*.cx_lowest values. You can also track the changes in the /var/log/messages file when you attach/detach the AC power.
% tail -f /var/log/messages Nov 28 13:14:42 t420s power_profile[48231]: changed to 'economy' Nov 28 13:14:46 t420s power_profile[56835]: changed to 'performance'
Usually I jest use these values.
performance_cx_lowest=C1 economy_cx_lowest=Cmax
These settings above are generally sufficient for most systems. To check which C-states your CPU supports get the value of dev.cpu.0.cx_supported MIB.
% sysctl dev.cpu.0.cx_supported dev.cpu.0.cx_supported: C1/1/1 C2/3/104
My CPU supports only C1 and C2 but yours may support more. I remember once when using some old Core 2 Duo laptop that the C2 state had quite ‘noticeable’ delay when getting back from C1 (running) state to C2 (sleep) state so following setting is needed. You do not use the performance_cx_lowest and economy_cx_lowest parameters. You set the first core to C1 and all other cores to C2. This way even on battery you have fully responsive system and all other cores may sleep and save energy.
For example if You would have 4 cores and your maximum (deepest) supported C-state would be C3, then you would put these into the /etc/sysctl.conf file.
% grep cx_lowest /etc/sysctl.conf dev.cpu.0.cx_lowest=C1 dev.cpu.1.cx_lowest=C3 dev.cpu.2.cx_lowest=C3 dev.cpu.3.cx_lowest=C3
CPU Turbo Mode
There are two ways to enable Turbo mode. One way is to set powerd(8) or powerdxx(8) daemon with maximum frequency set above nominal CPU speed. For example if you have CPU described as dual-core 2.3 GHz then set the maximum speed with -M flag to 4000 for example (which would mean 4GHz). If you do not use CPU frequency scaling daemon then you will use dev.cpu.0.freq parameter with highest (first) value from the dev.cpu.0.freq_levels MIB.
Supported CPU frequency levels on my system.
% sysctl dev.cpu.0.freq_levels dev.cpu.0.freq_levels: 2501/35000 2500/35000 2200/29755 2000/26426 1800/23233 1600/20164 1400/17226 1200/14408 1000/11713 800/9140
The highest value (left) is 2501/35000 so I need to set dev.cpu.0.freq parameter with this value to use Turbo Mode. You need to only use the ‘frequency’ value part because if you paste it with power requirements description it will fail.
# sysctl dev.cpu.0.freq=2501/35000 sysctl: invalid integer '2501/35000'
This is how it should be used.
# sysctl dev.cpu.0.freq=2501 dev.cpu.0.freq: 800 -> 2501
USB Devices
To list attached USB devices use the usbconfig(8) tool.
% usbconfig ugen1.1: at usbus1, cfg=0 md=HOST spd=SUPER (5.0Gbps) pwr=SAVE (0mA) ugen2.1: at usbus2, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA) ugen0.1: at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA) ugen2.2: at usbus2, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA) ugen0.2: at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA) ugen0.3: at usbus0, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (100mA) ugen2.3: at usbus2, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA)
You will see that pwr parameter (short for power) will show you current power setting which can be:
- ON
- OFF
- SAVE
To set new USB power option for the ugen1.1 device also use the usbconfig(8) tool with the power_save parameter in the following way.
# usbconfig -u 1 -a 1 power_save
The USB power management does not have dedicated config file on FreeBSD so we will put them into universal /etc/rc.local file which is being run at the end of the start-up process managed by the rc(8) subsystem. Here is the added content with exception for the ‘Lenovo USB Receiver‘ which is my wireless mouse.
% grep -A 10 POWER /etc/rc.local # POWER SAVE USB DEVICES usbconfig \ | grep -v 'Lenovo USB Receiver' \ | awk '{print $1}' \ | sed 's|ugen||'g \ | tr -d : \ | awk -F '.' '{print $1 " " $2 }' \ | while read U A do usbconfig -u ${U} -a ${A} power_save 2> /dev/null done
It’s good idea to NOT save power for mouse or tracked devices because you will probably find it annoying to have to wait about a second each time you would like to use it. I use a for loop to set power saving for all USB devices except wireless USB mouse (identified as ‘Lenovo USB Receiver‘ device).
SATA/AHCI Power Management
FreeBSD offers AHCI channels power management via acpich(4) driver. These power management settings can be set at boot using the hint.ahcich.*.pm_level parameter in the /boot/loader.conf file. I use configuration up to 8 channels while I only have three.
% grep ahcich /var/run/dmesg.boot ahcich0: at channel 0 on ahci0 ahcich1: at channel 1 on ahci0 ahcich4: at channel 4 on ahci0 ada0 at ahcich0 bus 0 scbus0 target 0 lun 0
That is because settings for non-existent devices are harmless and will not display any error messages but you will not have to use different settings for various systems which saves time. This is the hint.ahcich.*.pm_level description from the ahci(4) man page.
hint.ahcich.X.pm_level controls SATA interface Power Management for the specified channel, allowing some power to be saved at the cost of additional command latency. Some controllers, such as ICH8, do not implement modes 2 and 3 with NCQ used. Because of artificial entering latency, performance degradation in modes 4 and 5 is much smaller then in modes 2 and 3.
Possible power management options are:
- 0 – interface Power Management is disabled (default)
- 1 – device is allowed to initiate PM state change, host is passive
- 2 – host initiates PARTIAL PM state transition every time port becomes idle
- 3 – host initiates SLUMBER PM state transition every time port becomes idle
- 4 – driver initiates PARTIAL PM state transition 1ms after port becomes idle
- 5 – driver initiates SLUMBER PM state transition 125ms after port becomes idle
Here are my setting from the /boot/loader.conf file.
# AHCI POWER MANAGEMENT FOR EVERY USED CHANNEL (ahcich 0-7) hint.ahcich.0.pm_level=5 hint.ahcich.1.pm_level=5 hint.ahcich.2.pm_level=5 hint.ahcich.3.pm_level=5 hint.ahcich.4.pm_level=5 hint.ahcich.5.pm_level=5 hint.ahcich.6.pm_level=5 hint.ahcich.7.pm_level=5
Devices without Driver
FreeBSD has power saving option to not power devices that does not have attached driver. Its called hw.pci.do_power_nodriver and you can set it in the /boot/loader.conf file. Here is its description from then pci(4) man page.
hw.pci.do_power_nodriver (Defaults to 0) Place devices into a low power state (D3) when a suitable device driver is not found.
It can be set to one of the following values:
- 0 – All devices are left fully powered (defaults).
- 1 – Like ‘2‘ except that storage controllers are also not powered down.
- 2 – Powers down most devices (display/memory/peripherals not powered down).
- 3 – Powers down all PCI devices without a device driver.
Here is my setting from the /boot/loader.conf file.
# POWER OFF DEVICES WITHOUT ATTACHED DRIVER hw.pci.do_power_nodriver=3
The pciconf(8) utility will show you what devices are in your system and which driver is attached to it. If no driver is attached you will see none*@ for such devices, as none0@ below. You can also check man page for most drivers like em(4) man page for em0 device or xhci(4) page for xhci0 device.
% pciconf -l hostb0@pci0:0:0:0: class=0x060000 card=0x21d217aa chip=0x01048086 rev=0x09 hdr=0x00 vgapci0@pci0:0:2:0: class=0x030000 card=0x21d217aa chip=0x01268086 rev=0x09 hdr=0x00 none0@pci0:0:22:0: class=0x078000 card=0x21d217aa chip=0x1c3a8086 rev=0x04 hdr=0x00 em0@pci0:0:25:0: class=0x020000 card=0x21ce17aa chip=0x15028086 rev=0x04 hdr=0x00 ehci0@pci0:0:26:0: class=0x0c0320 card=0x21d217aa chip=0x1c2d8086 rev=0x04 hdr=0x00 hdac0@pci0:0:27:0: class=0x040300 card=0x21d217aa chip=0x1c208086 rev=0x04 hdr=0x00 pcib1@pci0:0:28:0: class=0x060400 card=0x21d217aa chip=0x1c108086 rev=0xb4 hdr=0x01 pcib2@pci0:0:28:1: class=0x060400 card=0x21d217aa chip=0x1c128086 rev=0xb4 hdr=0x01 pcib3@pci0:0:28:3: class=0x060400 card=0x21d217aa chip=0x1c168086 rev=0xb4 hdr=0x01 pcib4@pci0:0:28:4: class=0x060400 card=0x21d217aa chip=0x1c188086 rev=0xb4 hdr=0x01 ehci1@pci0:0:29:0: class=0x0c0320 card=0x21d217aa chip=0x1c268086 rev=0x04 hdr=0x00 isab0@pci0:0:31:0: class=0x060100 card=0x21d217aa chip=0x1c4f8086 rev=0x04 hdr=0x00 ahci0@pci0:0:31:2: class=0x010601 card=0x21d217aa chip=0x1c038086 rev=0x04 hdr=0x00 ichsmb0@pci0:0:31:3: class=0x0c0500 card=0x21d217aa chip=0x1c228086 rev=0x04 hdr=0x00 iwn0@pci0:3:0:0: class=0x028000 card=0x11118086 chip=0x42388086 rev=0x3e hdr=0x00 sdhci_pci0@pci0:5:0:0: class=0x088000 card=0x21d217aa chip=0xe8221180 rev=0x07 hdr=0x00 xhci0@pci0:13:0:0: class=0x0c0330 card=0x01941033 chip=0x01941033 rev=0x04 hdr=0x00
You can also use -v flag to get more detailed information.
% pciconf -l -v (...) xhci0@pci0:13:0:0: class=0x0c0330 card=0x01941033 chip=0x01941033 rev=0x04 hdr=0x00 vendor = 'NEC Corporation' device = 'uPD720200 USB 3.0 Host Controller' class = serial bus subclass = USB
Nvidia Optimus
If for some reason your BIOS/UEFI firmware does not allow you to disable Nvidia discrete graphics card you may use this script to disable it so it will not drain power from your system. It requires the acpi_call(4) kernel module which is provided by the acpi_call package.
# mkdir /root/bin # cd /root/bin # fetch https://people.freebsd.org/~xmj/turn_off_gpu.sh # pkg install acpi_call # kldload acpi_call # chmod +x /root/bin/turn_off_gpu.sh # /root/bin/turn_off_gpu.sh
You may add it to the /etc/rc.local file after the USB power saving options with this entry.
# DISABLE NVIDIA CARD /root/bin/turn_off_gpu.sh
It will store the working ACPI call in the /root/.gpu_method file and execute it each next time.
Suspend and Resume
The biggest enemies of suspend/resume mechanism are bugs in your BIOS/UEFI firmware for your hardware. Sometimes disabling Bluetooth helps – that is the option for ThinkPad T420s for example. To check which suspend modes are supported on your system check the hw.acpi.supported_sleep_state MIB from sysctl(8) subsystem.
% sysctl hw.acpi.supported_sleep_state hw.acpi.supported_sleep_state: S3 S4 S5
To enter ACPI S3 sleep state (suspend) you can use acpiconf(8) tool or zzz(8) tool.
# zzz
… or with acpiconf(8) tool.
# acpiconf -s 3
Its exactly the same as stated in the zzz(8) man page.
You can also set sysctl(8) value that everytime you close your laptop lid your system will go to sleep. To achieve that put hw.acpi.lid_switch_state=S3 into the /etc/sysctl.conf file. No matter if you put you hardware to sleep by command or by closing the lid your laptop will resume after opening the lid. Of course if you haven’t closed the lid after the zzz(8) command you will either have to close and open the lid or push the power button to resume. Of course you may also suspend/resume desktops or even your backup server if it has its purpose. It’s not limited to laptops only.
There are also dedicated kernel modules for various vendor ACPI subsystems. Here they are:
- /boot/kernel/acpi_asus_wmi.ko
- /boot/kernel/acpi_asus.ko
- /boot/kernel/acpi_dock.ko
- /boot/kernel/acpi_fujitsu.ko
- /boot/kernel/acpi_hp.ko
- /boot/kernel/acpi_ibm.ko
- /boot/kernel/acpi_panasonic.ko
- /boot/kernel/acpi_sony.ko
- /boot/kernel/acpi_toshiba.ko
- /boot/kernel/acpi_video.ko
- /boot/kernel/acpi_wmi.ko
For example if you have IBM/Lenovo ThinkPad the you will use the acpi_ibm.ko kernel module.
# kldload acpi_ibm
After loading each module you will get new sysctl(8) values for your use. For example related to fan speed, keyboard backlit or screen brightness. Below is new dev.acpi_ibm section in sysctl(8) after loading the acpi_ibm(4) kernel module.
% sysctl dev.acpi_ibm dev.acpi_ibm.0.handlerevents: NONE dev.acpi_ibm.0.mic_led: 0 dev.acpi_ibm.0.fan: 0 dev.acpi_ibm.0.fan_level: 0 dev.acpi_ibm.0.fan_speed: 0 dev.acpi_ibm.0.wlan: 1 dev.acpi_ibm.0.bluetooth: 0 dev.acpi_ibm.0.thinklight: 0 dev.acpi_ibm.0.mute: 0 dev.acpi_ibm.0.volume: 0 dev.acpi_ibm.0.lcd_brightness: 0 dev.acpi_ibm.0.hotkey: 1425 dev.acpi_ibm.0.eventmask: 134217727 dev.acpi_ibm.0.events: 1 dev.acpi_ibm.0.availmask: 134217727 dev.acpi_ibm.0.initialmask: 2060 dev.acpi_ibm.0.%parent: acpi0 dev.acpi_ibm.0.%pnpinfo: _HID=LEN0068 _UID=0 dev.acpi_ibm.0.%location: handle=\_SB_.PCI0.LPC_.EC__.HKEY dev.acpi_ibm.0.%driver: acpi_ibm dev.acpi_ibm.0.%desc: IBM ThinkPad ACPI Extras dev.acpi_ibm.%parent:
Here are descriptions of more interesting ones.
This one will turn the LED light on the Microphone mute button.
dev.acpi_ibm.0.mic_led
Select if you want to manage CPU fan (0) or leave it to the manufacturer defaults (1).
dev.acpi_ibm.0.fan
If CPU fan is enabled, set its speed.
dev.acpi_ibm.0.fan_level
This one will tell you how fast the CPU fan is spinning (in RPMs).
dev.acpi_ibm.0.fan_speed
Enable/disable WiFi (if its enabled in BIOS).
dev.acpi_ibm.0.wlan
Enable/disable Bluetooth (if its enabled in BIOS).
dev.acpi_ibm.0.bluetooth
Enable/disable ThinkLight.
dev.acpi_ibm.0.thinklight
Mute/unmute speakers.
dev.acpi_ibm.0.mute
Speakers volume.
dev.acpi_ibm.0.volume
Screen brightness.
dev.acpi_ibm.0.lcd_brightness
For most of the cases its not needed to use them as you will probably just use the vendor defined keyboard shortcuts (probably with Fn key) or vendor specific dedicated buttons. Sometimes you want to create/use your own setup or need custom keyboard shortcuts, or you want to control the fan speed depending on the CPU temperature other way then your vendor predefined it. This is when these dedicated ACPI kernel modules are most useful.
For example I recently thought that my CPU fan seems to be little louder then it should be so I created custom cron(8) based acpi-thinkpad-fan.sh script to use lower fan speeds or even lower quieter speeds when CPU temperature is low enough.
I will post it here. Maybe you will find it useful for your purposes. To describe it shortly it disables the fan when CPU temperature is below 50 (C) degrees, it sets it to level ‘1’ if its between 50 (C) and 60 (C) degrees and sets it to level ‘3’ when temperature reaches more then 60 (C) degrees.
#! /bin/sh if ! kldstat | grep -q acpi_ibm.ko then doas kldload acpi_ibm fi doas sysctl dev.acpi_ibm.0.fan=0 1> /dev/null TEMP=$( sysctl -n hw.acpi.thermal.tz0.temperature | awk -F'.' '{print $1}' ) if [ ${TEMP} -lt 50 ] then doas sysctl dev.acpi_ibm.0.fan_level=0 1> /dev/null exit 0 fi if [ ${TEMP} -lt 60 ] then doas sysctl dev.acpi_ibm.0.fan_level=1 1> /dev/null exit 0 fi if [ ${TEMP} -ge 60 ] then doas sysctl dev.acpi_ibm.0.fan_level=3 1> /dev/null exit 0 fi
… and here is its crontab(5) entry:
% crontab -l # ACPI/IBM/FAN * * * * * ~/scripts/acpi-thinkpad-fan.sh
Network Interfaces
There is also ifconfig(8) option to save power if a driver supports such feature, its called powersave and its used like that.
# ifconfig wlan0 powersave
I use it in my network.sh network management script described broadly in the FreeBSD Network Management with network.sh article.
Vendor Tools
There are also vendor tools available on FreeBSD like powermon(8) for example. Remember that it requires cpuctl(4) kernel module to work.
# pkg install powermon # kldload cpuctl # powermon Intel(R) Core(TM) i5-2520M CPU @ 2.50GHz (Arch: Sandy Bridge, Limit: 44W) 5.11W [=======> ] Package: Uncore: x86 Cores: GPU: Current: 5.11W Current: 3.17W Current: 1.73W Current: 0.21W Total: 98.33J Total: 60.86J Total: 33.49J Total: 3.98J
DTrace
The dynamic tracing framework that like ZFS found its way from Solaris/Illumos to FreeBSD may be also useful weapon in the battle for more time on your battery.
First add the dtrace-toolkit package.
# pkg install dtrace-toolkit
Your system stops saving energy or wakes CPU up because something needs to be run/done. To check what is run on your system you mostly run ps(1) or top(1) utilities but that will not show you what exactly is being started or how often something is being run. This is where DTrace comes with help.
We will use the /usr/share/dtrace/toolkit/execsnoop script from the dtrace-toolkit package. It will print EVERY COMMAND that is being run with all its arguments.It will remain silent when no commands are run, be advised.
Here is example output for my dzen2 toolbar update.
# /usr/local/share/dtrace-toolkit/execsnoop UID PID PPID ARGS 1000 97748 97509 /usr/local/bin/zsh -c ~/scripts/dzen2-update.sh > ~/.dzen2-fifo 1000 97748 1 /bin/sh /home/vermaden/scripts/dzen2-update.sh 1000 99157 97748 sysctl -n kern.smp.cpus 1000 311 97748 ps ax -o %cpu,rss,command -c 1000 3118 1521 awk -v SMP=200 /\ idle$/ {printf("%.1f%%",SMP-$1)} 1000 4462 97748 date +%Y/%m/%d/%a/%H:%M 1000 4801 97748 sysctl -n dev.cpu.0.freq 1000 6009 97748 sysctl -n hw.acpi.thermal.tz0.temperature 1000 6728 97748 sysctl -n vm.stats.vm.v_inactive_count 1000 7043 97748 sysctl -n vm.stats.vm.v_free_count 1000 7482 97748 sysctl -n vm.stats.vm.v_cache_count 1000 10363 8568 bc -l 1000 10863 10363 dc -x 1000 13143 7773 grep --color -q ^\. 1000 13798 97748 /bin/sh /home/vermaden/scripts/__conky_if_ip.sh 1000 15089 14235 ifconfig -u 1000 16439 14235 grep -v 127.0.0.1 1000 17738 14235 grep -c inet 1000 19069 18612 ifconfig -l -u 1000 19927 18612 sed s/lo0//g 1000 20772 13798 ifconfig wlan0 1000 23388 21410 grep ssid 1000 24588 13798 grep -q " 1000 25965 25282 awk /ssid/ {print $2} 1000 27917 27217 awk /inet / {print $2} 1000 29941 97748 /bin/sh /home/vermaden/scripts/__conky_if_gw.sh 1000 32808 31412 route -n -4 -v get default 1000 34012 31412 awk END{print $2} 1000 34895 97748 /bin/sh /home/vermaden/scripts/__conky_if_dns.sh 1000 36118 34895 awk /^nameserver/ {print $2; exit} /etc/resolv.conf 1000 37628 97748 /bin/sh /home/vermaden/scripts/__conky_if_ping.sh dzen2 1000 38829 37628 ping -c 1 -s 0 -t 1 -q 9.9.9.9 1000 42079 41566 mixer -s vol 1000 42177 41566 awk -F : {printf("%s",$2)} 1000 44434 43254 zfs list -H -d 0 -o name,avail 1000 45866 43254 awk {printf("%s/%s ",$1,$2)} 1000 47004 97748 /bin/sh /home/vermaden/scripts/__conky_battery_separate.sh dzen2 1000 48282 47004 sysctl -n hw.acpi.battery.units 1000 49494 47004 sysctl -n hw.acpi.battery.life 1000 49948 47004 sysctl -n hw.acpi.acline 1000 52073 51441 acpiconf -i 0 1000 53055 51441 awk /^State:/ {print $2} 1000 53981 53186 acpiconf -i 0 1000 55354 53186 awk /^Remaining capacity:/ {print $3} 1000 55968 55631 acpiconf -i 1 1000 57187 55631 awk /^State:/ {print $2} 1000 58405 57471 acpiconf -i 1 1000 59201 57471 awk /^Remaining capacity:/ {print $3} 1000 60961 59252 bsdgrep -v -E (COMMAND|idle)$ 1000 63534 59252 head -3 1000 62194 59252 sort -r -n 1000 64629 59252 awk {printf("%s/%d%%/%.1fGB ",$3,$1,$2/1024/1024)} 1000 64634 93198 tail -1 /home/vermaden/.dzen2-fifo
Lots of processes just to update the information on the top of the screen. That is why I refresh dzen2 information only every 5 minutes and if I want exact information and system status for current moment I just ‘click’ on then dzen2 bar to run all these commands and refresh itself.
This way using DTrace you will know if something unwanted does not steal you precious battery time. You may find such dzen2 config in my FreeBSD Desktop – Part 13 – Configuration – Dzen2 article.
Other
ZFS
By default ZFS will commit transaction group every 5 seconds and that is good default setting for the vfs.zfs.txg.timeout parameter. You may want to increase it a little if needed. To 10 for example. I say about that parameter mostly because lots of guides advice to set it to 1 for various performance reasons but keep in mind that setting it to 1 will prevent your disk (and CPU) from going to sleep thus draining more battery life.
If you want to mess with vfs.zfs.txg.timeout value set it in the /boot/loader.conf file.
Applications
To get more time on battery used applications are also crucial. For example Thunar uses less CPU time then Caja or Nautilus. The Geany text editor uses less CPU resources and memory then Scite or Gedit editors, even GVim takes more resources. Not to mention that custom Openbox/Fluxbox/${YOUR_FAVORITE_WM} window manager based setup will consume a lot less CPU time then entire Gnome or Mate environment.
Hardware
It’s sometimes possible to literally buy more battery time. For example when you want to buy new SSD for you laptop then pick not the fastest one but the most power efficient one. You will probably not feel the performance difference anyway but you will appreciate more battery time.
Most RAM modules come with 1.5V current voltage but there is chance that your laptop may support low power DDR modules with 1.35V current thus increasing your battery time. Also keep in mind that each RAM stick uses about 0.5-1.0W of power so using single 8 GB RAM stick will provide you more battery time the the same 8 GB of memory using two 4 GB RAM modules. This also have performance drawback because with single RAM module you will not be able to use dual channel technology so you will limit you RAM speed. Some laptops have even 4 RAM slots (like ThinkPad W520 for example) so without losing anything you should use two 8 GB RAM sticks instead of four 4 GB RAM sticks for longer battery life.
It is sometimes possible to swap your DVD drive to internal secondary battery. Examples of such laptops are Dell Latitude D630, ThinkPad T420s or ThinkPad T500/W500. Sometimes vendors offer entire slice battery that will stick to the bottom of your laptop like slice battery for ThinkPad X220 or T420/T520/W520 laptops or for the 1st generation of ThinkPad X1 laptop.
Hope that this information will help you squeeze some battery time (or at least save some power) on FreeBSD π
UPDATE 1 – Graphics Card Power Saving
If You have the graphics/drm-kmod package installed you probably use the latest i915kms.ko kernel module.
To set maximum power management for integrated Intel graphics cards put these into the /boot/loader.conf file.
# INTEL DRM WITH graphics/drm-kmod PACKAGE (NEW) # SKIP UNNECESSARY MODE SETS AT BOOT TIME compat.linuxkpi.fastboot=1 # USE SEMAPHORES FOR INTER RING SYNC compat.linuxkpi.semaphores=1 # ENABLE POWER SAVING RENDER C-STATE 6 compat.linuxkpi.enable_rc6=7 # ENABLE POWER SAVING DISPLAY C-STATES compat.linuxkpi.enable_dc=2 # ENABLE FRAME BUFFER COMPRESSION FOR POWER SAVINGS compat.linuxkpi.enable_fbc=1
In the past these settings below were used but they are not present anymore.
# INTEL DRM WITH graphics/drm-kmod PACKAGE (OLD) drm.i915.enable_rc6=7 drm.i915.semaphores=1 drm.i915.intel_iommu_enabled=1
UPDATE 2 – AMD CPU Temperatures
While the coretemp(4) kernel module is used for Intel CPUs the amdtemp(4) kernel module will provide additional temperature information for AMD CPUs.
UPDATE 3 – Suspend/Resume Tips
The biggest enemies of suspend/resume subsystem are bugs in the BIOS/UEFI firmware. Sometimes disabling the Bluetooth helps – that is the option for the Lenovo ThinkPad T420s for example. On the Lenovo ThinkPad X240 it is disabling the TPM (Trusted Platform Module).
UPDATE 4 – Intel Speed Shift
As I run FreeBSD on very decent but also pretty old 2011 ThinkPad W520 this option is a mystery for me – but for those who run more fresh systems may benefit from it.
With the introduction of Intel Skylake (6th Generation) CPUs the FreeBSD operating system is able to utilize the Intel Speed Shift technology. You can read more about it in the hwpstate_intel(4) man page. To make use of it include the following line in the /boot/loader.conf file.
machdep.hwpstate_pkg_ctrl=0
Then in the /etc/sysctl.conf file you would add a line for each CPU thread (not core) with your desired settings.
dev.hwpstate_intel.N.epp=Y
The N here stands for the thread number. On a dual core CPU with 4 threads you would have 4 such lines. On a octa core CPU with 8 threads you would have 8 lines.
The Y value means:
- 0 – maximum performance
- 50 – balanced (default)
- 100 – maximum power savings
To get the most power savings you would use 100 value for all threads as shown below.
dev.hwpstate_intel.0.epp=100 dev.hwpstate_intel.1.epp=100 dev.hwpstate_intel.2.epp=100 dev.hwpstate_intel.3.epp=100 dev.hwpstate_intel.4.epp=100 dev.hwpstate_intel.5.epp=100 dev.hwpstate_intel.6.epp=100 dev.hwpstate_intel.7.epp=100
You could of course use full performance for a single thread, keep one balanced thread and save power on the rest of the threads as shown below.
dev.hwpstate_intel.0.epp=0 dev.hwpstate_intel.1.epp=50 dev.hwpstate_intel.2.epp=100 dev.hwpstate_intel.3.epp=100 dev.hwpstate_intel.4.epp=100 dev.hwpstate_intel.5.epp=100 dev.hwpstate_intel.6.epp=100 dev.hwpstate_intel.7.epp=100
… and when you will be running on AC instead on battery then you may prefer to use that unlimited power with all values of 0 for all threads.
Settings below.
dev.hwpstate_intel.0.epp=0 dev.hwpstate_intel.1.epp=0 dev.hwpstate_intel.2.epp=0 dev.hwpstate_intel.3.epp=0 dev.hwpstate_intel.4.epp=0 dev.hwpstate_intel.5.epp=0 dev.hwpstate_intel.6.epp=0 dev.hwpstate_intel.7.epp=0
Ideally you would use performance settings when on AC power and run in power save mode when running on battery. You can achieve that with this simple script below running in cron(8) daemon.
#! /bin/sh case $( sysctl -n hw.acpi.acline ) in (0) # BATTERY doas sysctl dev.hwpstate_intel.0.epp=100 1> /dev/null 2> /dev/null doas sysctl dev.hwpstate_intel.1.epp=100 1> /dev/null 2> /dev/null doas sysctl dev.hwpstate_intel.2.epp=100 1> /dev/null 2> /dev/null doas sysctl dev.hwpstate_intel.3.epp=100 1> /dev/null 2> /dev/null doas sysctl dev.hwpstate_intel.4.epp=100 1> /dev/null 2> /dev/null doas sysctl dev.hwpstate_intel.5.epp=100 1> /dev/null 2> /dev/null doas sysctl dev.hwpstate_intel.6.epp=100 1> /dev/null 2> /dev/null doas sysctl dev.hwpstate_intel.7.epp=100 1> /dev/null 2> /dev/null ;; (1) # AC doas sysctl dev.hwpstate_intel.0.epp=0 1> /dev/null 2> /dev/null doas sysctl dev.hwpstate_intel.1.epp=50 1> /dev/null 2> /dev/null doas sysctl dev.hwpstate_intel.2.epp=100 1> /dev/null 2> /dev/null doas sysctl dev.hwpstate_intel.3.epp=100 1> /dev/null 2> /dev/null doas sysctl dev.hwpstate_intel.4.epp=100 1> /dev/null 2> /dev/null doas sysctl dev.hwpstate_intel.5.epp=100 1> /dev/null 2> /dev/null doas sysctl dev.hwpstate_intel.6.epp=100 1> /dev/null 2> /dev/null doas sysctl dev.hwpstate_intel.7.epp=100 1> /dev/null 2> /dev/null ;; esac
… and now the crontab(5) entry. I am also assuming here that you have needed doas(1) permissions. Modify the script if you useΒ sudo(8) instead.
% crontab -l # INTEL/SPEED/SHIFT * * * * * ~/scripts/acpi-intel-speed-shift.sh
Unfortunately as I do not own laptop with Intel Speed Shift CPU so I do not know if running the 0 and 50 for the first two threads works best. Maybe its better to switch all threads to 100 to save more power. I will let you know when I will get such laptop in the future π
Pingback: New top story on Hacker News: The Power to Serve β FreeBSD Power Management – News about world
Pingback: New top story on Hacker News: The Power to Serve β FreeBSD Power Management | World Best News
Pingback: New top story on Hacker News: The Power to Serve β FreeBSD Power Management – Latest news
Pingback: New top story on Hacker News: The Power to Serve β FreeBSD Power Management – Golden News
Pingback: New top story on Hacker News: The Power to Serve β FreeBSD Power Management – Hckr News
Please don’t tack on file exensions like .sh on executables. UNIX doesn’t need them and it purposely abstracts them from a user. Let’s not force CP/M inherited stupidities of MS-DOS and Windows on users. And besides, it’s unprofessional.
LikeLike
Thank you for comment.
By adding the ‘.sh’ extension is the way I distinguish commands from FreeBSD base system or installed by Ports/pkg(8) packages from my scripts and wrappers (with extension), but I agree that some prefer to not use extensions.
LikeLiked by 2 people
Pingback: The Power to Serve β #FreeBSD Power Management https://vermaden.wor… | Dr. Roy Schestowitz (η½δΌ)
Pingback: In Other BSDs for 2018/12/08 – DragonFly BSD Digest
The article gave me a lot of knowledge on the power management. Thank you!
I’d like to add on the USB devices. After the lid is opened the devices
are powered on again and the POWER script needs to be run to switch them
back to the power saving mode. This can be accomplished by placing a script
into /usr/local/etc/devd
cat /usr/local/etc/devd/acpi-resume.conf
notify 10 {
# Opening lid
match "system" "ACPI";
match "subsystem" "Lid";
match "notify" "0x01";
action "/etc/rc.local/POWER";
};
If POWER is not executable, use “sh /etc/rc.local/POWER” (you should have
gotten the idea).
LikeLike
Thanks for pointing that out, I will add UPDATE with that information π
LikeLike
Pingback: Silent Fanless FreeBSD Server – Redundant Backup | ππππππππ
Woaw, thank for all of this (I’m an old freebsd laptop user and I discover some other nice tricks here I didn’t know). It should be included in the doc tree, for sure !
FYI, some suspend/resume back from/to X11 won’t work (ie blank screen but system ok OR blank screen + system crashed) because of the boot console choice ; perhaps could you include this on your papers ; eg, for the Dell 6x series (6420, 6530 tested), you must choose the sc console driver at boot time, not the vt one. IIRC FreeBSD default to vt since R10 or R11…
Here’s what I have in my boot/loader.conf with some extras useful parameters I used over time:
# —————————–
# Console Mode 1 – sc + text
# —————————–
kern.vty=sc
#hw.vga.textmode=1
#splash_bmp_load=”YES”
#bitmap_load=”YES”
#bitmap_name=”/boot/splash.bmp”
# —————————–
# Console Mode 2 – vt
# —————————–
#kern.vty=vt
#kern.vt.fb.default_mode=800×600
#hw.vga.textmode=0
# ! no splash with vt mode
# —————————–
# Console – Common
# —————————–
beastie_disable=”YES” # Turn the beastie boot menu on and off
autoboot_delay=”2″ # with beastie Off “-1″=no wait, “NO”=infinite wait
loader_logo=”none” # Desired logo: fbsdbw, beastiebw, beastie, none
#verbose_loading=”YES” # Set to YES for verbose loader output
#boot_verbose=”NO”
#boot_mute=”YES” # -m: Mute the console
Hope it helps, thank to you,
BR
Val.
LikeLiked by 1 person
Hi,
thanks for these tips, I will try to update the articles with the suspend/resume information, and thank you for the /boot/loader.conf options in one place π
Regards.
LikeLike
Many thanks for all those wonderful articles about FreeBSD. Your website is real goldmine.
Sorry for asking such stupid question, but I could not find information about a command you use in your sh fan script. Could you tell me what is the “doas” command? Appreciated if you can guide me to good publication to learn sh scripting.
Thanks again, Pierre
LikeLike
Thanks π
The ‘doas’ is a OpenBSD clone of ‘sudo’. If you use ‘sudo’ instead then you may find/replace any instance of ‘doas’ into ‘sudo.
Here is the ‘portable’ doas page:
https://github.com/slicer69/doas
… but of course its also available on FreeBSD as port:
https://www.freshports.org/security/doas/
Here is a great guide on how to use ‘doas’ command – the DOAS MASTERY article:
https://flak.tedunangst.com/post/doas-mastery
Here is the ‘doas’ documentation:
https://man.openbsd.org/doas
https://man.openbsd.org/doas.conf.5
Now, about that sh scripting guide … I do not know any single place/page/guide that will cover it all.
There exist quite complete and advanced BASH guides, but I do not recall any POSIX /bin/sh guide.
Here are the guides that I could find now:
https://www.etalabs.net/sh_tricks.html
https://www.grymoire.com/Unix/Sh.html
https://www.panix.com/~elflord/unix/bash-tute.html
https://www.shellscript.sh/
https://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
… but for example none of them contain REAL WORLD USAGE patterns that are useful, for example the ‘while read’ loop as subshell versus version without subshell.
Lets assume that in a ‘while read’ loop that want to find some value you would next use. If you start by commands that you will then pipe into ‘while read’ loop then variables defined in that loop will not exist after the end of that loop because it was generated as subshell.
… but if you create ‘while read’ loop with EOF descriptor (you can name it as you wish) then its not a subshell and the ASD variable will be usable after the ‘while read’ loop ended.
Example run of these two different loops is below.
… and its just one basic thing in POSIX /bin/sh π
Another example, parsing the arguments for a script, there are several ways to do it, take a look at this script which shows them.
… and here is its results.
Hope that helps π
LikeLiked by 1 person
Thank you for the prompt reply and detailed explanations/orientation. That’s really helpful.
It now time for me to go deeper into fundamentals such as sh! Mastering those sh scripts is key to leverage the “power to serve” ;).
kind regards,
Pierre
LikeLike
Good luck with your scripts journeyy. Feel free to ask me for help when you hit any problems on the road to scripting mastery.
LikeLike
Pingback: ThinkPad T480 is my contemporary most well-known notebook computer which runs FreeBSD – Tech 'n' Gadget News
Pingback: ThinkPad T480 is my new main laptop which runs FreeBSD — Economicon
Pingback: ThinkPad T480 is my new main laptop which runs FreeBSD – Viral Tech News
Pingback: FreeBSD GNOME 3 Fast Track | ππππππππ
Great stuff! Even though this is geared towards laptop users, I found it really helpful for getting up to speed on powerd in a server environment as well. If you get billed for power usage and have a rack of stuff, this is important (or if you just don’t feel like burning power for no good reason). I’ve seen some mention that turbo states are not available without powerd running, not sure if that’s accurate.
LikeLike
Thanks.
IMHO the ‘Turbo’ state can be selected manually with sysctl(8) command.
Take a look at the available levels from here:
Currently the 800 (MHz) is selected.
If you would like to set ‘Turbo’ mode then you would execute that command:
Generally the modes that with ‘1’ larger then the official maximum frequency for given CPU is the ‘Turbo’ mode. In mine CPU its 2500 for maximum ‘not turbo’ mode and 2501 for ‘Turbo’ mode.
Hope that helps.
Regards.
LikeLike
Thanks – I did notice I could set it manually, but I’m lost on why the actual “turbo” speed isn’t reported – which makes verification hard.
I was basing the “no turbo w/o powerd” on this post: https://www.ateamsystems.com/tech-blog/increase-freebsd-performance-with-powerd/
But maybe that’s outdated now?
I do see “turbostat” was ported: https://www.freshports.org/sysutils/turbostat/
Going to see what that reports…
LikeLike
Thanks for letting me know about sysutils/turbostat util – I did not knew that π
I just tried it and it seems to track ‘states’ really reliably.
On an quite ‘not loaded/idle’ system I got 800 MHz.
Then I started to load CPU with Python calculations:
When my ‘maximum’ CPU state was set as 2501 by powerd(8) or by hand with sysctl(8) then the CPU increased speed to 3200 MHz which is max Turbo mode for my current X220 CPU.
Regards.
LikeLiked by 1 person
Here’s some more useful power-saving settings for recent Intel CPUs:
In:
add:
where:
(n1) = ncpu
(n2) = a number from 0 to 100
Where 0 represents minimal power-saving and 100 represents maximum power saving.
For an example 4-core 8-thread Intel CPU:
For more information: https://www.neelc.org/posts/freebsd-speed-shift-laptop/
The result is a drastic reduction of power consumption. I keep all CPUs at 100 unless I need to compile source code for some particular purpose (kernel / buildworld etc) or some other heavy compute apps. In this particular case, all 8 threads of an i7-8565U CPU stay at al lazy ~800Mhz nearly all of the time.
LikeLiked by 1 person
Thanks for sharing that π
I have edited your post a little with [B] and [PRE] tags for more readability.
LikeLike
Pingback: FreeBSD 13.1 on ThinkPad W520 | ππππππππ
Here is a useful hint for folks who explicitly set a certain audio device & rely on the suspend/zzz features. In certain circumstances the playback and/or audio hardware node interaction, will prevent proper suspend. Personal note: I had bewildering issues with Intel integrated graphics desktops, where the console would be spammed with pcm/snd errors — followed by audio devices no longer playing any sound. A reboot would fix the issue, which is not an ideal situation; this solution provided the fix.
This person provides a useful solution here:
https://www.davidschlachter.com/misc/freebsd-usb-audio
A person on reddit/r/freebsd provides another elegant approach:
sig=15
while [ “$( fuser -ks$sig /dev/dsp3* 2>/dev/null )” ]
do
echo sent $sig
sleep 1
sig=9
done
LikeLike
Pingback: FreeBSD 13.2 on ThinkPad T14 (GEN1) | ππππππππ