Tag Archives: sysctl

Naughty timer ACPI-safe, hangs on FreeBSD on Koolu

After updating the CVS tree from STABLE, rebuilding and reinstalling world and the kernel, I have found that:

  • boot hangs at DHCP discovery (dhclient), devd start-up, and one more place;
  • key repeating doesn’t work, you have to press a key every time;
  • the date doesn’t update;
  • you can’t restart or shut down.

All these have one thing in common: they happen when the counter doesn’t tick.

After noodling around for quite some time with the kernel config and make.conf, I finally understood this wasn’t the reason. See, the GENERIC kernel that kame with the FreeBSD 7.0 CD (and I backed that up after installing, right away) worked, and the GENERIC kernel re-compiled didn’t.

I thought it was related to the build tools. No, not.

Turned out it was the counter (timer). See, your system has several:

% sysctl kern.timecounter.choice
kern.timecounter.choice: TSC(800) ACPI-fast(1000) i8254(0) dummy(-1000000)
% sysctl kern.timecounter.hardware
kern.timecounter.hardware: ACPI-fast

Now, this stuff happened on a Koolu, and it had an ACPI-safe, quality 850, so that got chosen by default. Turned out it didn’t work.

You can do several things:

  • you can boot the same kernel without ACPI, just select the appropriate option;
  • or you can load it by hand:
    sudo sysctl kern.timecounter.hardware=TSC

  • or automatically – add this to /etc/sysctl.conf:
    kern.timecounter.hardware=TSC
    (Make sure there are no quotes in the latter!)

FreeBSD: script to manage processor speed

I have posted about this before <broken link>.

This time, it’s not one script, but many.

  • cpuctl is the script to be used when you want to switch the processor frequency. It goes anywhere you feel comfortable, I put it in ~/bin/.
  • cpucontrol is a wrapper script to sysctl. It’s required, since a common user is not allowed to change sysctl values. So, this script is run at startup with root permissions and works in the background. It reads from a file and issues the sysctl command. You control who can change the frequency by setting the aforementioned file’s permissions.
  • rc.d-cpucontrol is the rc.d file. It’s required to run cpucontrol on startup.
  • awesome-cpu is a widget for the awesome window manager. I use that. If you don’t, just delete it.

You can get all the files packed. SERVER DIED

Check the files, they have modifiable values. To install, issue something like:

cp cpuctl ~/bin/cpuctl
sudo cp cpucontrol /usr/local/bin/cpucontrol
sudo cp rc.d-cpucontrol /usr/local/etc/rc.d/cpucontrol
sudo echo 'cpucontrol_enable="YES"' >> /etc/rc.conf

FreeBSD: script to manage processor speed

Edit: this has been updated <broken link>.

You might ask: why not use powerd? Well, I tried. It sure does save energy, but there are also annoying pauses between when I start manically switching windows and it changes the frequency.

So, I wrote a C Shell script to do the thing. Yes, C Shell is a nuisance, but Bourne Shell doesn’t have arrays, and I’ve wasted quite some time trying to work around that. Then I just dumped the idea.

It ain’t that long anyway, so you are able to catch the bugs before they run away.

To use it, set the freq_levels array to what you’ve got.

The drawback is that it uses sudo when setting the frequency. I’m currently trying to find out how not to.

#!/bin/tcsh
# Script to manage cpu freqency (scaling). Tested on FreeBSD.

## NOTE: allowed frequencies must be set manually.
## On FreeBSD, see: sysctl -a | grep dev.cpu
# -----
# dev.cpu.0.freq_levels: 1660/27000 1452/23625 1328/18900 1162/16537
# 996/10800 871/9450 747/8100 622/6750 498/5400 373/4050 249/2700 124/1350

# Smaller values go earlier.
set freq_levels = ( 373 871 996 1162 1660 )

# Get current frequency and check which level it is.
set freq_current = `sysctl dev.cpu.0.freq | cut -d' ' -f 2`
set level_current = 0	# level is unknown
set i = 1		# iterator

while ( $i <= $#freq_levels )
	if ( $freq_current == $freq_levels[$i] ) then
		@ level_current = $i
		break
	endif
	@ i = $i + 1
end

if ( $level_current == 0 ) then
	echo "Current CPU frequency not in supported frequency list."
	exit 1
endif


# Check which action is to be performed. If no argument specified,
# output help.
if ( $1 == "" ) then
	goto help
endif
switch ($1)
	case "up":
		if ( $level_current  1 ) then
			@ level_current = $level_current - 1
			eval 'sudo sysctl dev.cpu.0.freq=$freq_levels[$level_current]'
		endif
		breaksw
	case "show":
		echo "Current frequency: $freq_current"
		echo "Current level:     ${level_current}/${#freq_levels}"
		breaksw

	case "-h":
	help:
		echo "cpuctl [ up | down | show ]"
		breaksw
	case "--help":
		goto help
		breaksw

	case "*":
		echo "Unknown parameter: $1"
		goto help
		breaksw
endsw

exit 0