Subject: freeze / connection delay after idling for a while ?

From: Jerome Marc <[email-masked]>
Date: Mon, 30 Sep 2024 13:52:43 +0200

Hi,

I just installed Alpine 3.20.3 on a RPI 2 in diskless mode.(headless,
minimal installation)

I noticed that if I let the device idling, I have a few seconds latency
when I try to connect the machine with SSH for example. Even when connected
I can have my SSH session frozen for a few seconds if I do nothing in the
terminal.
I notice the same when using a nodejs app (HTTP) therefore this is a
general thing (not just about SSH)

I don't see anything weird in logs. Any idea ? Is that a power saving
feature ?

Jerome

---

From: Steffen Nurpmeso <[email-masked]>
Date: Mon, 30 Sep 2024 22:27:28 +0200

Jerome Marc wrote in
 <[email-masked]>:
 |I just installed Alpine 3.20.3 on a RPI 2 in diskless mode.(headless,
 |minimal installation)
 |
 |I noticed that if I let the device idling, I have a few seconds latency
 |when I try to connect the machine with SSH for example. Even when connected
 |I can have my SSH session frozen for a few seconds if I do nothing in the
 |terminal.
 |I notice the same when using a nodejs app (HTTP) therefore this is a
 |general thing (not just about SSH)
 |
 |I don't see anything weird in logs. Any idea ? Is that a power saving
 |feature ?

It *could* be that cpupower-openrc is indeed the
tools/power/cpupower of the linux kernel sources, it seems to be
widely available (architecture-wise, on Alpine).
If that is so, then running it should output stuff like

  #?0|kent:~# bin/cpupower.sh
  analyzing CPU 0:
    driver: intel_pstate
    CPUs which run at the same hardware frequency: 0
    CPUs which need to have their frequency coordinated by software: 0
    maximum transition latency:  Cannot determine or is not supported.
    hardware limits: 400 MHz - 3.40 GHz
    available cpufreq governors: performance powersave
    current policy: frequency should be within 400 MHz and 3.40 GHz.
                    The governor "powersave" may decide which speed to use
                    within this range.
    current CPU frequency: Unable to call hardware
    current CPU frequency: 800 MHz (asserted by call to kernel)
    boost state support:
      Supported: yes
      Active: yes

On the reserve laptop however the EFI(BIOS) "always" sets back
cpupower, and we start with "powersave" governor and low
frequency, and so the initial decrypting of the hard disk takes
seeeeconds.  I btw drive it via

  #!/bin/sh -
  #@ /root/bin/cpupower.sh
  # cpupower is in Linux src, tools/power/cpupower

  : ${HOSTNAME:=$(uname -n)}

  if [ -f /root/hosts/${HOSTNAME}/cpupower ]; then
          . /root/hosts/${HOSTNAME}/cpupower
  else
          logger -s -t /root/bin/cpupower.sh "MISS /root/hosts/${HOSTNAME}/cpupower"
          exit 1
  fi

  if command -v cpupower >/dev/null 2>&1; then :; else
          logger -s -t /root/bin/cpupower.sh 'no cpupower tool'
          exit 1
  fi

  if [ $# -gt 0 ]; then
          x=
          case $1 in
          lo) x=$lo;;
          med) x=$med;;
          hi) x=$hi;;
          default) x=$default;;
          75) x=$x75;;
          *) echo >&2 'Synopsis: cpupower [lo|med|hi|default[|75]]';;
          esac
          [ -n "$x" ] && cpupower frequency-set -u $x
  fi

  cpupower frequency-info

and that /root/hosts/$HOSTNAME/cpupower is (here)

  #@ /root/hosts/self/cpupower
  lo='400M -g powersave'
  med='1600M -g powersave'
  hi='3400M -g performance'
  default='3400M -g powersave'
  x75='2500M -g performance'

(i use "hi" only for kernel and port builds).
It makes "a hell of a difference".

Other than that i have seen similar things because (a) the
kernel's crng came up slowly (up to 30 minutes at times), but this
*should* be a thing of the past (dunno Alpine 3.20, i always use
[edge]), or because of WiFi chip powersafe stuff, i usually do
that though, i use "iw dev $dev set power_save on":

  # iw dev wlp1s0 get power_save
  Power save: on

Other than that i am out of ideas.

--steffen
|
|Der Kragenbaer,                The moon bear,
|der holt sich munter           he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)

---

From: Jerome Marc <[email-masked]>
Date: Mon, 30 Sep 2024 23:20:21 +0200

Hi Steffen,

Thanks !
Unfortunately there is cpupower rc service running and I don't have wifi.
I installed cpupower and got this output :

alpine:~# cpupower frequency-info
analyzing CPU 0:
  driver: cpufreq-dt
  CPUs which run at the same hardware frequency: 0 1 2 3
  CPUs which need to have their frequency coordinated by software: 0 1 2 3
  maximum transition latency:  Cannot determine or is not supported.
  hardware limits: 600 MHz - 900 MHz
  available frequency steps:  600 MHz, 700 MHz, 800 MHz, 900 MHz
  available cpufreq governors: conservative ondemand userspace performance
schedutil
  current policy: frequency should be within 600 MHz and 900 MHz.
                  The governor "schedutil" may decide which speed to use
                  within this range.
  current CPU frequency: 600 MHz (asserted by call to hardware)

Looks good...

Le lun. 30 sept. 2024 à 22:27, Steffen Nurpmeso <[email-masked]> a

---

From: Jerome Marc <[email-masked]>
Date: Tue, 1 Oct 2024 14:51:17 +0200

Ok I found the culprit. It was a network issue. The problem was happening
when initiating the connection from a wlan which is bridged with the wired
lan.
For some reason, my Internet router forgets the presence of the RPI.
Therefore IP address resolution can be slow. I suppose it's because there
is no traffic coming from the RPI.
I installed the avahi daemon, I think it will make the RPI visible
continuously.

---

From: Steffen Nurpmeso <[email-masked]>
Date: Tue, 29 Oct 2024 00:40:57 +0100

Steffen Nurpmeso wrote in
 <20240930202728._Cgmke2m@steffen%sdaoden.eu>:
 |Jerome Marc wrote in
 | <[email-masked]>:
 ..
 |It *could* be that cpupower-openrc is indeed the
 |tools/power/cpupower of the linux kernel sources, it seems to be
 |widely available (architecture-wise, on Alpine).
 |If that is so, then running it should output stuff like

btw that

 |  #?0|kent:~# bin/cpupower.sh

script was total shit, as it was relying on that cpupower program
even though /sys/devices/system/cpu{,/cpufreq/} supports plenty of
possibilities.  Thank you.  I have extended/changed it, changed my

  plo='400M -g powersave'
  pmi='1600M -g powersave'
  phi='3400M -g powersave'
  smi='2500M -g performance'
  shi='3400M -g performance'
  defmode=phi
  defname=$phi

but these configs are only used if the mentioned will not work
out, otherwise it adapts automatically more or less better.
In fact the energy_performance_preference seems to play a much,
much greater role than anything else, at least with my
scheduler(s) and config etc etc.  (Terribly slow with p+!)
But with that i now have

  # DEBUG=Y bin/cpupower.sh - # or p-
  echo powersave > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
  echo power > /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference
  echo 400000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq
  echo 400000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
  echo powersave > /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor
  echo power > /sys/devices/system/cpu/cpu1/cpufreq/energy_performance_preference
  echo 400000 > /sys/devices/system/cpu/cpu1/cpufreq/scaling_min_freq
  echo 400000 > /sys/devices/system/cpu/cpu1/cpufreq/scaling_max_freq
  ...

over

  # DEBUG=Y bin/cpupower.sh p+
  echo powersave > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
  echo balance_power > /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference
  echo 400000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq
  echo 3400000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
  ...

to

  # DEBUG=Y bin/cpupower.sh + # or s+
  echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
  echo performance > /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference
  echo 400000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq
  echo 3400000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
  ...

and that all-automatic!  Just in case someone is interested...

#!/bin/sh -
#@ /root/bin/cpupower.sh

: ${DEBUG:=}

if [ -f /root/hosts/${HOSTNAME}/cpupower ]; then
	. /root/hosts/${HOSTNAME}/cpupower
elif [ $# -gt 0 ]; then
	logger -s -t /root/bin/cpupower.sh "MISS /root/hosts/${HOSTNAME}/cpupower (for setting)"
	exit 1
fi

cd /

[ -n "$DEBUG" ] && DEBUG=echo
strat=strata mode= bd=/sys/devices/system/cpu

mode_set() {
	$DEBUG logger -s -t /root/bin/cpupower.sh mode=$mode
	#flock /run/.sys-cpu -c "echo $mode > /run/.sys-cpu"
	[ -z "$DEBUG" ] && echo $mode > /run/.sys-cpu
}

strata() {
	query() { # {{{
		i=0
		while [ -d $bd/cpu$i ]; do
			if [ -f $bd/cpu$i/online ]; then
				eval read j < $bd/cpu$i/online
				if [ $j -ne 1 ]; then
					i=$((i + 1))
					continue
				fi
			fi
			eval cpu$i=y

			if [ -f $bd/cpu$i/cpufreq/base_frequency ]; then
				eval read j < $bd/cpu$i/cpufreq/base_frequency
				eval cpu${i}_bf=\$j
				if [ -f $bd/cpu$i/cpufreq/cpuinfo_min_freq ]; then
					eval read j < $bd/cpu$i/cpufreq/cpuinfo_min_freq
					eval cpu${i}_minf=\$j
				fi
				if [ -f $bd/cpu$i/cpufreq/cpuinfo_max_freq ]; then
					eval read j < $bd/cpu$i/cpufreq/cpuinfo_max_freq
					eval cpu${i}_maxf=\$j
				fi
			fi

			if [ -f $bd/cpu$i/cpufreq/scaling_governor ]; then
				eval read j < $bd/cpu$i/cpufreq/scaling_governor
				eval cpu${i}_gov=\$j
				if [ -f $bd/cpu$i/cpufreq/scaling_available_governors ]; then
					eval read j < $bd/cpu$i/cpufreq/scaling_available_governors
					eval cpu${i}_govs=\$j
				fi
			fi

			if [ -f $bd/cpu$i/cpufreq/energy_performance_preference ]; then
				eval read j < $bd/cpu$i/cpufreq/energy_performance_preference 
				eval cpu${i}_epref=\$j
				if [ -f $bd/cpu$i/cpufreq/energy_performance_available_preferences ]; then
					eval read j < $bd/cpu$i/cpufreq/energy_performance_available_preferences
					eval cpu${i}_eprefs=\$j
				fi
			fi

			if [ -f $bd/cpu$i/cpufreq/scaling_cur_freq ]; then
				eval read j < $bd/cpu$i/cpufreq/scaling_cur_freq
				eval cpu${i}_sf=\$j
				if [ -f $bd/cpu$i/cpufreq/scaling_min_freq ]; then
					eval read j < $bd/cpu$i/cpufreq/scaling_min_freq
					eval cpu${i}_sminf=\$j
				fi
				if [ -f $bd/cpu$i/cpufreq/scaling_max_freq ]; then
					eval read j < $bd/cpu$i/cpufreq/scaling_max_freq
					eval cpu${i}_smaxf=\$j
				fi
			fi

			i=$((i + 1))
		done
	} # }}}

	adjust() { # {{{
		[ -n "$DEBUG" ] && ev=echo || ev=eval
		i=0
		while [ -d $bd/cpu$i ]; do
			eval j=\$cpu$i
			if [ -z "$j" ]; then
				i=$((i + 1))
				continue
			fi

			eval bf=\$cpu${i}_bf minf=\$cpu${i}_minf maxf=\$cpu${i}_maxf \
					gov=\$cpu${i}_gov govs=\$cpu${i}_govs \
					epref=\$cpu${i}_epref eprefs=\$cpu${i}_eprefs \
					sf=\$cpu${i}_sf minf=\$cpu${i}_minf maxf=\$cpu${i}_maxf

			gov= epref= sminf= smaxf=
			if [ $mode != "${mode%p*}" ]; then
				if [ -n "$govs" ]; then
					if [ " $govs" != "${govs#* powersave}" ]; then
						gov=powersave
					fi
				fi

				if [ -n "$eprefs" ]; then
					if [ $mode != "${mode#*+}" ] && [ " $eprefs" != "${eprefs#* balance_power}" ]; then
						epref=balance_power
					fi
					if [ -z "$epref" ] && [ " $eprefs" != "${eprefs#* power}" ]; then
						epref=power
					fi
				fi

				if [ -n "$bf" ] && [ -n "$minf" ] && [ -n "$maxf" ]; then
					sminf=$minf
					if [ $mode != "${mode#*-}" ]; then
						smaxf=$minf
					elif [ $mode != "${mode#*=}" ]; then
						smaxf=$((bf + ((maxf - bf) / 2)))
						[ $smaxf -gt $maxf ] && smaxf=$((maxf - $(maxf / 4)))
					else
						smaxf=$maxf
					fi
				fi
			else
				if [ -n "$govs" ]; then
					if [ " $govs" != "${govs#* performance}" ]; then
						gov=performance
					fi
				fi

				if [ -n "$eprefs" ]; then
					if [ $mode = "${mode#*+}" ] && [ " $eprefs" != "${eprefs#* balance_performance}" ]; then
						epref=balance_performance
					fi
					if [ -z "$epref" ] && [ " $eprefs" != "${eprefs#* performance}" ]; then
						epref=performance
					fi
				fi

				if [ -n "$bf" ] && [ -n "$minf" ] && [ -n "$maxf" ]; then
					sminf=$minf
					if [ $mode != "${mode#*+}" ]; then
						smaxf=$maxf
					elif [ $mode != "${mode#*=}" ]; then
						smaxf=$((bf + ((maxf - bf) / 2)))
						[ $smaxf -gt $maxf ] && smaxf=$((maxf - $(maxf / 4)))
					#else
					#	smaxf=$bf
					fi
				fi
			fi

			[ -n "$gov" ] && $ev "echo $gov > $bd/cpu$i/cpufreq/scaling_governor"
			[ -n "$epref" ] && $ev "echo $epref > $bd/cpu$i/cpufreq/energy_performance_preference"
			[ -n "$sminf" ] && $ev "echo $sminf > $bd/cpu$i/cpufreq/scaling_min_freq"
			[ -n "$smaxf" ] && $ev "echo $smaxf > $bd/cpu$i/cpufreq/scaling_max_freq"

			i=$((i + 1))
		done
		$ev query

		mode_set
	} # }}}

	show() { # {{{
		i=0
		while [ -d $bd/cpu$i ]; do
			eval j=\$cpu$i
			if [ -z "$j" ]; then
				i=$((i + 1))
				continue
			fi
			printf "CPU $i: "

			eval j=\$cpu${i}_bf
			if [ -n "$j" ]; then 
				printf "$j/"
				eval j=\$cpu${i}_minf
				[ -n "$j" ] && printf "$j"
				eval j=\$cpu${i}_maxf
				[ -n "$j" ] && printf -- "-$j"
				printf '; '
			fi

			eval j=\$cpu${i}_gov
			if [ -n "$j" ]; then 
				printf "gov: $j"
				eval j=\$cpu${i}_govs
				[ -n "$j" ] && printf " ($j)"
				printf '; '
			fi

			eval j=\$cpu${i}_epref
			if [ -n "$j" ]; then 
				printf "energy: $j"
				eval j=\$cpu${i}_eprefs
				[ -n "$j" ] && printf " ($j)"
				printf '; '
			fi

			eval j=\$cpu${i}_sf
			if [ -n "$j" ]; then 
				printf "scaling: $j/"
				eval j=\$cpu${i}_sminf
				[ -n "$j" ] && printf "$j"
				eval j=\$cpu${i}_smaxf
				[ -n "$j" ] && printf -- "-$j"
				#printf '; '
			fi

			printf '\n'
			i=$((i + 1))
		done
	} # }}}

	query
	[ -n "$mode" ] && adjust
	show
}

stratb() {
	if [ -n "$mode" ]; then
		eval i=\$$moden
		if [ -z "$i" ]; then
			logger -s -t /root/bin/cpupower.sh "MISS /root/hosts/${HOSTNAME}/cpupower mode=$mode"
			exit 1
		fi
		$DEBUG cpupower frequency-set -u $i
		mode_set
	fi
	eval exec $DEBUG cpupower frequency-info
}

if [ ! -f $bd/cpu0/cpufreq/base_frequency ]; then
	if command -v cpupower >/dev/null 2>&1; then :; else
		logger -s -t /root/bin/cpupower.sh 'no cpupower tool'
		exit 1
	fi
	strat=stratb
fi

if [ $# -gt 0 ]; then
	case "$1" in
	\-|p-) mode=p- moden=plo;;
	p=) mode=$1 moden=pmi;;
	p\+) mode=$1 moden=phi;;
	s=) mode=$1 moden=smi;;
	\+|s\+) mode=s+ moden=shi;;
	=|def) mode=$defmode moden=$defname;;
	*) echo >&2 'Synopsis: cpupower [p-|p=|p+|s=|s+|=|def]';;
	esac
fi

eval $strat

# s-sht-mode

--steffen
|
|Der Kragenbaer,                The moon bear,
|der holt sich munter           he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)
|
|And in Fall, feel "The Dropbear Bard"s ball(s).
|
|The banded bear
|without a care,
|Banged on himself fore'er and e'er
|
|Farewell, dear collar bear