Skip to content

Commit 28b18fb

Browse files
authored
Merge pull request #825 from whitesscott/thor-memory
Add Jetson Thor EMC support via devfreq bwmgr and BPMP actmon
2 parents ca24495 + d6eb572 commit 28b18fb

1 file changed

Lines changed: 41 additions & 14 deletions

File tree

jtop/core/memory.py

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
# Create logger
3030
logger = logging.getLogger(__name__)
3131
# Memory regular exception
32-
MEMINFO_REG = re.compile(r'(?P<key>.+):\s+(?P<value>.+) (?P<unit>.)B')
32+
MEMINFO_REG = re.compile(r'(?P<key>[^:]+):\s+(?P<value>.+)\s+(?P<unit>.)B')
3333
FSTAB_RE = re.compile(r'^(?P<path>[^ ]+) +(?P<mount>[^ ]+) +(?P<type>[^ ]+) +(?P<options>[^ ]+) +(?P<dump>\d+) +(?P<pass>\d+)$')
3434
BUDDYINFO_REG = re.compile(r'Node\s+(?P<numa_node>\d+).*zone\s+(?P<zone>\w+)\s+(?P<nr_free>.*)')
3535
SWAP_REG = re.compile(r'(?P<name>[^ ]+)\s+(?P<type>[^ ]+)\s+(?P<size>\d+)\s+(?P<used>\d+)\s+(?P<prio>-?\d+)')
@@ -127,76 +127,103 @@ def read_emc(root_path):
127127
emc = {}
128128
# Initialize emc['cur'] to avoid a crash when starting this service
129129
emc['cur'] = 1
130+
130131
if os.path.isdir(root_path + "/debug/bpmp/debug/clk/emc"):
131132
path = root_path + "/debug/bpmp/debug/clk/emc"
132133
# Check if access to this file
133134
if os.access(path + "/rate", os.R_OK):
134135
with open(path + "/rate", 'r') as f:
135-
# Write min
136136
emc['cur'] = int(f.read()) // 1000
137137
# Check if access to this file
138138
if os.access(path + "/max_rate", os.R_OK):
139139
with open(path + "/max_rate", 'r') as f:
140-
# Write min
141140
emc['max'] = int(f.read()) // 1000
142141
# Check if access to this file
143142
if os.access(path + "/min_rate", os.R_OK):
144143
with open(path + "/min_rate", 'r') as f:
145-
# Write min
146144
emc['min'] = int(f.read()) // 1000
147145
# Check if access to this file
148146
if os.access(path + "/mrq_rate_locked", os.R_OK):
149147
with open(path + "/mrq_rate_locked", 'r') as f:
150-
# Write min
151148
emc['override'] = int(f.read()) // 1000
149+
150+
elif os.path.isdir(root_path + "/../class/devfreq/bwmgr"):
151+
# Jetson Thor exposes EMC/BWMGR through devfreq instead of the
152+
# older tegra_bwmgr debugfs interface used on earlier platforms.
153+
path = root_path + "/../class/devfreq/bwmgr"
154+
# Check if access to this file
155+
if os.access(path + "/cur_freq", os.R_OK):
156+
with open(path + "/cur_freq", 'r') as f:
157+
emc['cur'] = int(f.read()) // 1000
158+
# Check if access to this file
159+
if os.access(path + "/max_freq", os.R_OK):
160+
with open(path + "/max_freq", 'r') as f:
161+
emc['max'] = int(f.read()) // 1000
162+
# Check if access to this file
163+
if os.access(path + "/min_freq", os.R_OK):
164+
with open(path + "/min_freq", 'r') as f:
165+
emc['min'] = int(f.read()) // 1000
166+
# Optional metadata
167+
if os.access(path + "/governor", os.R_OK):
168+
with open(path + "/governor", 'r') as f:
169+
emc['governor'] = f.read().strip()
170+
152171
elif os.path.isdir(root_path + "/debug/tegra_bwmgr"):
153172
path = root_path + "/debug/clk/override.emc"
154173
# Check if access to this file
155174
if os.access(path + "/clk_rate", os.R_OK):
156175
with open(path + "/clk_rate", 'r') as f:
157-
# Write min
158176
emc['cur'] = int(f.read()) // 1000
159177
# Check if access to this file
160178
if os.access(path + "/clk_state", os.R_OK):
161179
with open(path + "/clk_state", 'r') as f:
162-
# Write min
163180
emc['override'] = int(f.read()) // 1000
164181
# Decode from tegra_bwmgr
165182
path = root_path + "/tegra_bwmgr"
166183
# Check if access to this file
167184
if os.access(path + "/emc_max_rate", os.R_OK):
168185
with open(path + "/emc_max_rate", 'r') as f:
169-
# Write min
170186
emc['max'] = int(f.read()) // 1000
171187
# Check if access to this file
172188
if os.access(path + "/emc_min_rate", os.R_OK):
173189
with open(path + "/emc_min_rate", 'r') as f:
174-
# Write min
175190
emc['min'] = int(f.read()) // 1000
191+
176192
elif os.path.isdir(root_path + "/clk/emc"):
177193
emc = read_engine(root_path + "/clk/emc")
178-
# Fix max frequency
194+
195+
# Apply nvpmodel EMC cap regardless of which EMC source populated emc['max']
179196
emc_cap = 0
180-
# Check if access to this file
181197
if os.access(root_path + "/nvpmodel_emc_cap/emc_iso_cap", os.R_OK):
182198
with open(root_path + "/nvpmodel_emc_cap/emc_iso_cap", 'r') as f:
183-
# Write min
184199
emc_cap = int(f.read()) // 1000
185-
# Fix max EMC
186200
if 'max' in emc:
187201
if emc_cap > 0 and emc_cap < emc['max']:
188202
emc['max'] = emc_cap
203+
189204
# Percentage utilization
190205
# https://forums.developer.nvidia.com/t/real-time-emc-bandwidth-with-sysfs/107479/3
191206
if os.access(root_path + "/debug/cactmon/mc_all", os.R_OK):
192207
with open(root_path + "/debug/cactmon/mc_all", 'r') as f:
193208
utilization = int(f.read())
209+
elif os.access(root_path + "/debug/bpmp/debug/actmon/mc_all_avg_activity", os.R_OK):
210+
with open(root_path + "/debug/bpmp/debug/actmon/mc_all_avg_activity", 'r') as f:
211+
utilization = int(f.read())
194212
elif os.access(root_path + "/actmon_avg_activity/mc_all", os.R_OK):
195213
with open(root_path + "/actmon_avg_activity/mc_all", 'r') as f:
196214
utilization = int(f.read())
197215
else:
198-
# if utilization not accesibile return empty EMC data
216+
# if utilization not accessible return empty EMC data
217+
return {}
218+
219+
if emc['cur'] <= 0:
220+
logger.warning(
221+
"EMC current frequency value is non-positive (emc['cur']=%s). "
222+
"Dropping EMC data to avoid division by zero.",
223+
emc['cur'],
224+
)
199225
return {}
226+
200227
emc['val'] = utilization // emc['cur']
201228
# Set always online this engine
202229
emc['online'] = True

0 commit comments

Comments
 (0)