Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
LimaGroup
Lima-Launcher
Commits
a6f3f1cd
Commit
a6f3f1cd
authored
Jan 27, 2022
by
Alejandro Homs Puron
Browse files
[SET_CPU_AFFINITY] CPUFreq: support cpufreq-utils support & 'cpufreq_governor' in config
parent
30720585
Changes
1
Hide whitespace changes
Inline
Side-by-side
scripts/set_cpu_affinity
View file @
a6f3f1cd
...
...
@@ -98,9 +98,6 @@ class SMPSystem:
NbCPUs
=
0
MaxNbCPUs
=
0
PerformanceCPUFreqGovernor
=
'performance'
OnDemandCPUFreqGovernor
=
'ondemand'
@
classmethod
def
getNbCPUs
(
klass
):
if
klass
.
NbCPUs
==
0
:
...
...
@@ -121,43 +118,153 @@ class SMPSystem:
def
getCPUSysfsDir
(
klass
,
cpu
):
return
f
'/sys/devices/system/cpu/cpu
{
cpu
}
'
class
CPUFreqRawFileSetter
:
@
classmethod
def
getBaseDir
(
klass
,
cpu
):
return
os
.
path
.
join
(
SMPSystem
.
getCPUSysfsDir
(
cpu
),
'cpufreq'
)
@
classmethod
def
getScalingGovernorFile
(
klass
,
cpu
):
return
os
.
path
.
join
(
klass
.
getBaseDir
(
cpu
),
'scaling_governor'
)
@
classmethod
def
getAvailableGovernorsFile
(
klass
,
cpu
):
return
os
.
path
.
join
(
klass
.
getBaseDir
(
cpu
),
'scaling_available_governor'
)
@
classmethod
def
getCPUFreqDir
(
klass
,
cpu
):
return
os
.
path
.
join
(
klass
.
getCPUSysfsDir
(
cpu
),
'cpufreq'
)
def
getAvailableGovernors
(
klass
,
cpu
):
fname
=
klass
.
getAvailableGovernorsFile
()
cmd
=
SystemCmd
([
'cat'
,
fname
],
try_sudo
=
False
)
cat
=
cmd
.
doPopen
(
stdout
=
PIPE
,
text
=
True
)
return
cat
.
stdout
.
readline
().
strip
().
split
()
@
classmethod
def
getCPUFreqCurrGovernor
(
klass
,
cpu
):
fname
=
os
.
path
.
join
(
klass
.
getCPUFreqDir
(
cpu
),
'scaling_governor'
)
cmd
=
SystemCmd
([
'cat'
,
fname
])
cat
=
cmd
.
doPopen
(
stdout
=
PIPE
)
return
cat
.
stdout
.
readline
().
strip
()
def
getCurrGovernor
(
klass
,
cpu_list
):
governor_list
=
[]
for
cpu
in
cpu_list
:
fname
=
klass
.
getScalingGovernorFile
()
cmd
=
SystemCmd
([
'cat'
,
fname
],
try_sudo
=
False
)
cat
=
cmd
.
doPopen
(
stdout
=
PIPE
,
text
=
True
)
governor_list
.
append
(
cat
.
stdout
.
readline
().
strip
())
return
governor_list
@
classmethod
def
setC
PUFreqC
urrGovernor
(
klass
,
cpu_list
,
governor
):
def
setCurrGovernor
(
klass
,
cpu_list
,
governor
):
cpu_cmds
=
[]
for
cpu
in
cpu_list
:
fname
=
os
.
path
.
join
(
klass
.
getCPUFreqDir
(
cpu
),
's
caling
_g
overnor
'
)
fname
=
klass
.
getS
caling
G
overnor
File
(
)
cpu_cmds
.
append
(
f
'echo
{
governor
}
>
{
fname
}
'
)
bash_cmd
=
' && '
.
join
(
cpu_cmds
)
cmd
=
SystemCmd
([
'bash'
,
'-c'
,
bash_cmd
])
if
cmd
.
execute
()
!=
0
:
raise
RuntimeError
(
f
'Cannot set CPU
{
cpu
}
freq. governor '
raise
RuntimeError
(
f
'Cannot set CPU
s
{
cpu
_list
}
freq. governor '
f
'to
{
governor
}
'
)
class
CPUFreqUtilsSetter
:
Info
=
'cpufreq-info'
Set
=
'cpufreq-set'
@
classmethod
def
getAvailableGovernors
(
klass
,
cpu
):
cmd
=
SystemCmd
([
klass
.
Info
,
'-c'
,
str
(
cpu
),
'-g'
],
try_sudo
=
False
)
info
=
cmd
.
doPopen
(
stdout
=
PIPE
,
text
=
True
)
avail
=
info
.
stdout
.
readline
().
strip
().
split
()
return
avail
@
classmethod
def
setAllCPUFreqGovernor
(
klass
,
governor
):
def
getGovernorInfo
(
klass
,
cpu
):
cmd
=
SystemCmd
([
klass
.
Info
,
'-c'
,
str
(
cpu
),
'-p'
],
try_sudo
=
False
)
info
=
cmd
.
doPopen
(
stdout
=
PIPE
,
text
=
True
)
min_freq
,
max_freq
,
policy
=
info
.
stdout
.
readline
().
strip
().
split
()
return
min_freq
,
max_freq
,
policy
@
classmethod
def
getCurrGovernor
(
klass
,
cpu_list
):
governors
=
[]
for
cpu
in
cpu_list
:
min_freq
,
max_freq
,
policy
=
klass
.
getGovernorInfo
(
cpu
)
governors
.
append
(
policy
)
return
governors
@
classmethod
def
setCurrGovernor
(
klass
,
cpu_list
,
governor
):
for
cpu
in
cpu_list
:
min_freq
,
max_freq
,
policy
=
klass
.
getGovernorInfo
(
cpu
)
cmd
=
SystemCmd
([
klass
.
Set
,
'-c'
,
str
(
cpu
),
'-g'
,
governor
,
'-d'
,
min_freq
,
'-u'
,
max_freq
])
if
cmd
.
execute
()
!=
0
:
raise
RuntimeError
(
f
'Cannot set CPU
{
cpu
}
freq. governor '
f
'to
{
governor
}
'
)
class
CPUFreqMgr
:
PerformanceGovernors
=
[
'performance'
]
PowerSaveGovernors
=
[
'ondemand'
,
'powersave'
]
def
__init__
(
self
,
target_governors
=
None
,
default_governors
=
PowerSaveGovernors
,
setter
=
None
):
self
.
m_setter
=
setter
or
self
.
getSetter
()
if
target_governors
:
if
not
self
.
m_setter
:
raise
RuntimeError
(
'No available CPUFreq setter: '
'install cpufreq-utils or provide '
'sudo privileges'
)
available_targets
=
self
.
getAvailableGovernorsFrom
(
target_governors
)
if
not
available_targets
:
raise
ValueError
(
f
'None of the target governors '
f
'
{
target_governors
}
is available'
)
self
.
m_target_governor
=
available_targets
[
0
]
else
:
self
.
m_target_governor
=
None
available_defaults
=
self
.
getAvailableGovernorsFrom
(
default_governors
)
if
not
available_defaults
:
raise
ValueError
(
f
'None of the default governors '
f
'
{
default_governors
}
is available'
)
self
.
m_default_governor
=
available_defaults
[
0
]
print
(
f
'default_governor=
{
self
.
m_default_governor
}
'
)
def
getSetter
(
self
):
for
klass
in
[
CPUFreqUtilsSetter
,
CPUFreqRawFileSetter
]:
try
:
setter
=
klass
()
cpu_list
=
[
0
]
governors
=
setter
.
getCurrGovernor
(
cpu_list
)
setter
.
setCurrGovernor
(
cpu_list
,
governors
[
0
])
return
setter
except
:
pass
return
None
def
getAvailableGovernorsFrom
(
self
,
governors
):
available_governors
=
None
for
cpu
in
range
(
SMPSystem
.
getNbCPUs
()):
available_for_this
=
self
.
m_setter
.
getAvailableGovernors
(
cpu
)
if
available_governors
is
None
:
available_governors
=
available_for_this
else
:
available_governors
=
[
g
for
g
in
available_for_this
if
g
in
available_governors
]
return
[
g
for
g
in
governors
if
g
in
available_governors
]
def
setAllGovernors
(
self
,
governor
):
print
(
f
'Setting all CPUs freq. governor to
{
governor
}
...'
)
klass
.
setCPUFreq
CurrGovernor
(
range
(
klass
.
getNbCPUs
()),
governor
)
self
.
m_setter
.
set
CurrGovernor
(
range
(
SMPSystem
.
getNbCPUs
()),
governor
)
def
__enter__
(
self
):
if
self
.
m_target_governor
:
self
.
setAllGovernors
(
self
.
m_target_governor
)
@
contextmanager
def
all_cpu_freq_governor
(
governor
,
default_governor
=
SMPSystem
.
OnDemandCPUFreqGovernor
):
SMPSystem
.
setAllCPUFreqGovernor
(
governor
)
try
:
yield
finally
:
SMPSystem
.
setAllCPUFreqGovernor
(
default_governor
)
def
__exit__
(
self
,
*
args
):
if
self
.
m_target_governor
:
self
.
setAllGovernors
(
self
.
m_default_governor
)
def
CPU
(
*
args
):
...
...
@@ -568,6 +675,7 @@ class CPUAffinityDataJSONParser:
config
=
json
.
loads
(
json_str
)
self
.
m_json
=
None
listener
=
[]
cpufreq_governor
=
None
lima
=
ProcessMgr
.
DefaultAffinity
other
=
ProcessMgr
.
DefaultAffinity
net_dev
=
[]
...
...
@@ -578,6 +686,7 @@ class CPUAffinityDataJSONParser:
self
.
m_json
=
config
[
'cpu_affinity'
]
if
'recv'
in
self
.
m_json
:
listener
=
self
.
listenerAffinityFromJSON
(
self
.
m_json
[
'recv'
])
cpufreq_governor
=
self
.
m_json
.
get
(
'cpufreq_governor'
,
None
)
if
'lima'
in
self
.
m_json
:
lima
=
self
.
limaAffinityFromJSON
(
self
.
m_json
[
'lima'
])
if
'other'
in
self
.
m_json
:
...
...
@@ -585,8 +694,9 @@ class CPUAffinityDataJSONParser:
if
'net_dev'
in
self
.
m_json
:
net_dev
=
[
self
.
netDevGroupAffinityFromJSON
(
json
)
for
json
in
self
.
m_json
[
'net_dev'
]]
self
.
m_global_data
=
dict
(
listener
=
listener
,
lima
=
lima
,
other
=
other
,
net_dev
=
net_dev
)
self
.
m_global_data
=
dict
(
listener
=
listener
,
cpufreq_governor
=
cpufreq_governor
,
lima
=
lima
,
other
=
other
,
net_dev
=
net_dev
)
@
classmethod
def
listenerAffinityFromRecvsJSON
(
klass
,
recvs
):
...
...
@@ -682,7 +792,7 @@ def main(argv):
for
l
in
CPUGlobalDataToStringLines
(
cpu_affinity_data
):
print
(
l
)
with
all_cpu_freq_governor
(
SMPSystem
.
PerformanceCPUF
req
G
overnor
):
with
CPUFreqMgr
([
cpu_affinity_data
[
'cpuf
req
_g
overnor
'
]]
):
with
net_dev_groups_cpu_affinity
(
cpu_affinity_data
[
'net_dev'
]):
with
ProcessMgr
(
cpu_affinity_data
[
'other'
]):
def
child_func
(
affinity
,
*
argv
):
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment