Jetson TK1 CPU scaling governor settings not sticking

I have tried setting the CPU scaling governor of the Jetson TK1 on startup with both the cpufrequtils service and including the instructions here (Jetson/Performance - eLinux.org) in an /etc/init.d script.

After startup/reboot, when I log in and check the governor (i.e., /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor) I initial see that it is set to ‘performance’ as desire. However, in a minute or so it reverts back to ‘interactive’. If I restart the cpufrequtils service (or my init.d script) then it seems like the change is more permanent, but that’s not a terribly great solution (and kind of defeats the purpose of those services running on startup).

I have set my TK1 to performance and let it run quite some time (set was via rc.local) with no change to setup. However, I wasn’t actually putting any load on the system, so whatever you run which would have an effect that scaling would be sensitive to is not taking place for this particular test.

I see that you’ve mentioned cpufrequtils service, while all of my settings were simply performance mode without cpu frequency adjustments. What kind of cpu frequency adjustments are you using?

FYI, I added these bash scripts to make testing easier (placed in /usr/local/bin/)…testing of current setting on CPU online or not is to avoid abort in any script that might abort for an echo error output:
performance_ls:

#!/bin/bash

echo -n "CPUquiet: ";
cat /sys/devices/system/cpu/cpuquiet/tegra_cpuquiet/enable
echo -n "Scaling Governor: ";
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
echo -n "CPU 0 online: ";
cat /sys/devices/system/cpu/cpu0/online
echo -n "CPU 1 online: ";
cat /sys/devices/system/cpu/cpu1/online
echo -n "CPU 2 online: ";
cat /sys/devices/system/cpu/cpu2/online
echo -n "CPU 3 online: ";
cat /sys/devices/system/cpu/cpu3/online

performance_set_default:

#!/bin/bash

echo '1' > /sys/devices/system/cpu/cpuquiet/tegra_cpuquiet/enable

g_ONLINE="$(cat /sys/devices/system/cpu/cpu0/online)";
if [[ "${g_ONLINE}" != '1' ]]; then
   echo '1' > /sys/devices/system/cpu/cpu0/online
fi

g_ONLINE="$(cat /sys/devices/system/cpu/cpu1/online)";
if [[ "${g_ONLINE}" != '0' ]]; then
   echo '0' > /sys/devices/system/cpu/cpu1/online
fi

g_ONLINE="$(cat /sys/devices/system/cpu/cpu2/online)";
if [[ "${g_ONLINE}" != '0' ]]; then
   echo '0' > /sys/devices/system/cpu/cpu2/online
fi

g_ONLINE="$(cat /sys/devices/system/cpu/cpu3/online)";
if [[ "${g_ONLINE}" != '0' ]]; then
   echo '0' > /sys/devices/system/cpu/cpu3/online
fi

echo 'interactive' > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

performance_set_max:

#!/bin/bash

echo '0' > /sys/devices/system/cpu/cpuquiet/tegra_cpuquiet/enable

g_ONLINE="$(cat /sys/devices/system/cpu/cpu0/online)";
if [[ "${g_ONLINE}" != '1' ]]; then
   echo '1' > /sys/devices/system/cpu/cpu0/online
fi

g_ONLINE="$(cat /sys/devices/system/cpu/cpu1/online)";
if [[ "${g_ONLINE}" != '1' ]]; then
   echo '1' > /sys/devices/system/cpu/cpu1/online
fi

g_ONLINE="$(cat /sys/devices/system/cpu/cpu2/online)";
if [[ "${g_ONLINE}" != '1' ]]; then
   echo '1' > /sys/devices/system/cpu/cpu2/online
fi

g_ONLINE="$(cat /sys/devices/system/cpu/cpu3/online)";
if [[ "${g_ONLINE}" != '1' ]]; then
   echo '1' > /sys/devices/system/cpu/cpu3/online
fi

echo 'performance' > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

I was using the ‘performance’ scaling_governor. Now I’m using ‘userspace’ and setting the frequency to the max. Doesn’t seem to mater; it still switches back to ‘iteractive’. I ditched the cpufrequtils.

I seemed to have fixed the problem by setting /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor, etc. to read-only. Apparerntly this keeps whatever process is changing the governor back to ‘iteractive’ from doing so, but I still don’t know what that process is.

I have not tried cpufrequtils, but it looks like it’s generally available on a number of distributions. One URL I found on the topic mentions that sysfsutils also needs to be installed and configured to keep the settings across boot…and I wonder if perhaps this would force an old setting if not set to whatever the desired setting is during the middle of ordinary runtime. See this:
https://wiki.debian.org/HowTo/CpuFrequencyScaling

I’ve noticed that on 21.4 there’s an rc script called ondemand, which sets the scaling governor to ondemand. It’s enabled by default. I’ve disabled said script with:

update-rc.d -f ondemand remove

That’s an interesting find. This “/etc/init.d/ondemand” file/service is installed as part of the initscripts package, and does not list actions for all of the /sys modes available to Jetson. This could easily get in the way of performance testing or setup without knowing it, as “performance” is summarily rejected by the script after a delay.

It looks like this part of initscripts has a means of detecting local login (perhaps GUI and/or console). I say this because the “ondemand” script has this line in it:

sleep 60 # probably enough time for desktop login

During my testing I had neither X11 login nor console login and was using ssh session only. My remote-only login could explain why performance mode never stopped for my tests, yet switched back to ondemand for you. There was never any “background” event for me since the local logins were non-existent and already “backgrounded” (why send a background event if already in background?).

I’m not completely sure of how init has this set up, but all of the modes known are taken from a /sys entry, so all possible modes are known to the script…yet the /etc/init.d/ondmand script switch case for “background” (presumably triggered by a service background or inactivity event) handles only these corner cases:

interactive
ondemand
powersave

It seems that the initscript package maintainers (I haven’t looked for who that is) could modify the ondemand script to look for an optional config file as to what action to take on “background” event, rather than hard-coding for only three cases when the /sys content far exceeds those three cases. This would allow customizing for different hardware with different power saving options without modifying the initscripts package itself.