[PATCH umr 01/17] Use the correct register prefix on Navi3 for top
Nicolai Hähnle
nicolai.haehnle at amd.com
Tue Jun 6 09:17:09 UTC 2023
Signed-off-by: Nicolai Hähnle <nicolai.haehnle at amd.com>
---
src/app/top.c | 89 +++++++++++++++++++++++++++------------------------
1 file changed, 48 insertions(+), 41 deletions(-)
diff --git a/src/app/top.c b/src/app/top.c
index f99b7b5..40ed0ac 100644
--- a/src/app/top.c
+++ b/src/app/top.c
@@ -903,30 +903,31 @@ void load_options(void)
}
} else {
// add some defaults to not be so boring
top_options.vi.grbm = 1;
top_options.vi.vgt = 1;
top_options.vi.ta = 1;
}
}
static struct {
- char *name, *tag;
+ char name[32];
+ char *tag;
uint64_t counts[32];
int *opt, is_sensor;
uint32_t addr, mask[32], cmp[32];
uint64_t addr_mask;
struct umr_bitfield *bits;
} stat_counters[64];
-#define ENTRY(_j, _name, _bits, _opt, _tag) do { int _i = (_j); stat_counters[_i].name = _name; stat_counters[_i].bits = _bits; stat_counters[_i].opt = _opt; stat_counters[_i].tag = _tag; } while (0)
-#define ENTRY_SENSOR(_j, _name, _bits, _opt, _tag) do { int _i = (_j); stat_counters[_i].name = _name; stat_counters[_i].bits = _bits; stat_counters[_i].opt = _opt; stat_counters[_i].tag = _tag; stat_counters[_i].is_sensor = 1; } while (0)
+#define ENTRY(_j, _prefix, _name, _bits, _opt, _tag) do { int _i = (_j); snprintf(stat_counters[_i].name, sizeof(stat_counters[_i].name), "%s%s", _prefix, _name); stat_counters[_i].bits = _bits; stat_counters[_i].opt = _opt; stat_counters[_i].tag = _tag; } while (0)
+#define ENTRY_SENSOR(_j, _name, _bits, _opt, _tag) do { int _i = (_j); strcpy(stat_counters[_i].name, _name); stat_counters[_i].bits = _bits; stat_counters[_i].opt = _opt; stat_counters[_i].tag = _tag; stat_counters[_i].is_sensor = 1; } while (0)
static void vi_handle_keys(int i)
{
switch(i) {
case 't': top_options.vi.ta ^= 1; break;
case 'g': top_options.vi.vgt ^= 1; break;
case 'G': top_options.vi.gfxpwr ^= 1; break;
case 'u': top_options.vi.uvd ^= 1; break;
case 'c': top_options.vi.vce ^= 1; break;
case 's': top_options.vi.grbm ^= 1; break;
@@ -963,44 +964,59 @@ static int sriov_supported_vf(struct umr_asic *asic)
return (sriov_ctrl & PCI_SRIOV_CTRL_VFE) ? sriov_num_vf : 0;
}
pci_offset = PCI_EXT_CAP_NEXT(pci_cfg_data);
}
return retval;
}
static void top_build_vi_program(struct umr_asic *asic)
{
+ const char *gfx_prefix;
+ const char *vcn_prefix;
int i, j, k;
char *regname;
+ gfx_prefix = "mm";
+ struct umr_ip_block* gfx = umr_find_ip_block(asic, "gfx", asic->options.vm_partition);
+ if (gfx && gfx->discoverable.maj >= 11)
+ gfx_prefix = "reg";
+
+ vcn_prefix = "mm";
+ struct umr_ip_block* vcn = umr_find_ip_block(asic, "vcn", asic->options.vm_partition);
+ if (vcn && ((vcn->discoverable.maj == 2 && vcn->discoverable.min >= 6) || vcn->discoverable.maj >= 4))
+ vcn_prefix = "reg";
+
stat_counters[0].bits = &stat_grbm_bits[0];
stat_counters[0].opt = &top_options.vi.grbm;
stat_counters[0].tag = "GRBM";
- stat_counters[1].opt = &top_options.vi.grbm;
- stat_counters[1].tag = stat_counters[0].tag;
- stat_counters[1].name = "mmGRBM_STATUS2";
- stat_counters[1].bits = &stat_grbm2_bits[0];
+ // which SE to read ...
+ if (options.use_bank == 1)
+ snprintf(stat_counters[0].name, sizeof(stat_counters[0].name), gfx_prefix, "GRBM_STATUS_SE%d", options.bank.grbm.se);
+ else
+ snprintf(stat_counters[0].name, sizeof(stat_counters[0].name), gfx_prefix, "GRBM_STATUS");
+
+ i = 1;
- i = 2;
+ ENTRY(i++, gfx_prefix, "GRBM_STATUS2", &stat_grbm2_bits[0], &top_options.vi.grbm, "GRBM");
top_options.sriov.active_vf = -1;
top_options.sriov.num_vf = sriov_supported_vf(asic);
if (top_options.sriov.num_vf != 0) {
stat_counters[i].is_sensor = 3;
- ENTRY(i++, "mmRLC_GPU_IOV_ACTIVE_FCN_ID", &stat_rlc_iov_bits[0],
+ ENTRY(i++, gfx_prefix, "RLC_GPU_IOV_ACTIVE_FCN_ID", &stat_rlc_iov_bits[0],
&top_options.vi.grbm, "GPU_IOV");
}
if (asic->config.gfx.family > 110)
- ENTRY(i++, "mmRLC_GPM_STAT", &stat_rlc_gpm_bits[0], &top_options.vi.gfxpwr, "GFX PWR");
+ ENTRY(i++, gfx_prefix, "RLC_GPM_STAT", &stat_rlc_gpm_bits[0], &top_options.vi.gfxpwr, "GFX PWR");
// sensors
if (asic->family >= FAMILY_NV) {
ENTRY_SENSOR(i++, "GFX_SCLK", &stat_nv_sensor_bits[0], &top_options.vi.sensors, "Sensors");
} else if (asic->config.gfx.family == 141 || asic->config.gfx.family == 142) {
// Arctic Island Family/Raven
ENTRY_SENSOR(i++, "GFX_SCLK", &stat_ai_sensor_bits[0], &top_options.vi.sensors, "Sensors");
} else if (asic->config.gfx.family == 135) {
// Carrizo/Stoney family
ENTRY_SENSOR(i++, "GFX_SCLK", &stat_carrizo_sensor_bits[0], &top_options.vi.sensors, "Sensors");
@@ -1013,80 +1029,71 @@ static void top_build_vi_program(struct umr_asic *asic)
} else if (asic->config.gfx.family == 120) {
// CIK
ENTRY_SENSOR(i++, "GFX_SCLK", &stat_cik_sensor_bits[0], &top_options.vi.sensors, "Sensors");
} else if (asic->config.gfx.family == 110) {
// SI
ENTRY_SENSOR(i++, "GFX_SCLK", &stat_si_sensor_bits[0], &top_options.vi.sensors, "Sensors");
}
sensor_bits = stat_counters[i-1].bits;
// More GFX bits
- ENTRY(i++, "mmTA_STATUS", &stat_ta_bits[0], &top_options.vi.ta, "TA");
+ ENTRY(i++, gfx_prefix, "TA_STATUS", &stat_ta_bits[0], &top_options.vi.ta, "TA");
// VGT bits only valid for gfx7..9
if (asic->family < FAMILY_NV)
- ENTRY(i++, "mmVGT_CNTL_STATUS", &stat_vgt_bits[0], &top_options.vi.vgt, "VGT");
+ ENTRY(i++, gfx_prefix, "VGT_CNTL_STATUS", &stat_vgt_bits[0], &top_options.vi.vgt, "VGT");
// UVD registers
if (asic->family < FAMILY_AI)
- ENTRY(i++, "mmSRBM_STATUS", &stat_srbm_status_uvd_bits[0], &top_options.vi.uvd, "UVD");
+ ENTRY(i++, gfx_prefix, "SRBM_STATUS", &stat_srbm_status_uvd_bits[0], &top_options.vi.uvd, "UVD");
k = i;
- ENTRY(i++, "mmUVD_CGC_STATUS", &stat_uvdclk_bits[0], &top_options.vi.uvd, "UVD");
+ ENTRY(i++, vcn_prefix, "UVD_CGC_STATUS", &stat_uvdclk_bits[0], &top_options.vi.uvd, "UVD");
// set PG flag for all UVD registers
for (; k < i; k++) {
stat_counters[k].addr_mask = REG_USE_PG_LOCK; // UVD requires PG lock
}
k = j = i;
- ENTRY(i++, "mmUVD_PGFSM_READ_TILE1", &stat_uvd_pgfsm1_bits[0], &top_options.vi.uvd, "UVD");
- ENTRY(i++, "mmUVD_PGFSM_READ_TILE2", &stat_uvd_pgfsm2_bits[0], &top_options.vi.uvd, "UVD");
- ENTRY(i++, "mmUVD_PGFSM_READ_TILE3", &stat_uvd_pgfsm3_bits[0], &top_options.vi.uvd, "UVD");
- ENTRY(i++, "mmUVD_PGFSM_READ_TILE4", &stat_uvd_pgfsm4_bits[0], &top_options.vi.uvd, "UVD");
- ENTRY(i++, "mmUVD_PGFSM_READ_TILE5", &stat_uvd_pgfsm5_bits[0], &top_options.vi.uvd, "UVD");
- ENTRY(i++, "mmUVD_PGFSM_READ_TILE6", &stat_uvd_pgfsm6_bits[0], &top_options.vi.uvd, "UVD");
- ENTRY(i++, "mmUVD_PGFSM_READ_TILE7", &stat_uvd_pgfsm7_bits[0], &top_options.vi.uvd, "UVD");
+ ENTRY(i++, vcn_prefix, "UVD_PGFSM_READ_TILE1", &stat_uvd_pgfsm1_bits[0], &top_options.vi.uvd, "UVD");
+ ENTRY(i++, vcn_prefix, "UVD_PGFSM_READ_TILE2", &stat_uvd_pgfsm2_bits[0], &top_options.vi.uvd, "UVD");
+ ENTRY(i++, vcn_prefix, "UVD_PGFSM_READ_TILE3", &stat_uvd_pgfsm3_bits[0], &top_options.vi.uvd, "UVD");
+ ENTRY(i++, vcn_prefix, "UVD_PGFSM_READ_TILE4", &stat_uvd_pgfsm4_bits[0], &top_options.vi.uvd, "UVD");
+ ENTRY(i++, vcn_prefix, "UVD_PGFSM_READ_TILE5", &stat_uvd_pgfsm5_bits[0], &top_options.vi.uvd, "UVD");
+ ENTRY(i++, vcn_prefix, "UVD_PGFSM_READ_TILE6", &stat_uvd_pgfsm6_bits[0], &top_options.vi.uvd, "UVD");
+ ENTRY(i++, vcn_prefix, "UVD_PGFSM_READ_TILE7", &stat_uvd_pgfsm7_bits[0], &top_options.vi.uvd, "UVD");
// set compare/mask for UVD TILE registers
for (; j < i; j++) {
stat_counters[j].cmp[0] = 0;
stat_counters[j].mask[0] = 3;
stat_counters[j].addr_mask = REG_USE_PG_LOCK; // require PG lock
}
// VCE registers
if (asic->family < FAMILY_AI)
- ENTRY(i++, "mmSRBM_STATUS2", &stat_srbm_status2_vce_bits[0], &top_options.vi.vce, "VCE");
+ ENTRY(i++, gfx_prefix, "SRBM_STATUS2", &stat_srbm_status2_vce_bits[0], &top_options.vi.vce, "VCE");
k = i;
// set PG flag for all VCE registers
for (; k < i; k++) {
stat_counters[k].addr_mask = REG_USE_PG_LOCK; // VCE requires PG lock
}
// memory hub
k = i;
if (asic->family < FAMILY_AI)
- ENTRY(i++, "mmMC_HUB_MISC_STATUS", &stat_mc_hub_bits[0], &top_options.vi.memory_hub, "MC HUB");
+ ENTRY(i++, gfx_prefix, "MC_HUB_MISC_STATUS", &stat_mc_hub_bits[0], &top_options.vi.memory_hub, "MC HUB");
// SDMA
k = i;
if (asic->family < FAMILY_AI)
- ENTRY(i++, "mmSRBM_STATUS2", &stat_sdma_bits[0], &top_options.vi.sdma, "SDMA");
-
- // which SE to read ...
- regname = calloc(1, 64);
- if (options.use_bank == 1)
- snprintf(regname, 63, "mmGRBM_STATUS_SE%d", options.bank.grbm.se);
- else
- snprintf(regname, 63, "mmGRBM_STATUS");
-
- stat_counters[0].name = regname;
+ ENTRY(i++, gfx_prefix, "SRBM_STATUS2", &stat_sdma_bits[0], &top_options.vi.sdma, "SDMA");
top_options.handle_key = vi_handle_keys;
top_options.helptext =
"(u)vd v(c)e (G)FX_PWR (s)GRBM (t)a v(g)t (m)emory_hub \n"
"s(d)ma se(n)sors\n";
}
static void toggle_logger(void)
{
@@ -1094,21 +1101,21 @@ static void toggle_logger(void)
top_options.logger ^= 1;
if (top_options.logger) {
char *p, name[512];
if (!(p = getenv("UMR_LOGGER")))
p = getenv("HOME");
sprintf(name, "%s/umr.log", p);
logfile = fopen(name, "a");
fprintf(logfile, "Time (seconds),");
- for (i = 0; stat_counters[i].name; i++)
+ for (i = 0; stat_counters[i].name[0]; i++)
if (top_options.all || *stat_counters[i].opt)
for (j = 0; stat_counters[i].bits[j].regname != 0; j++)
fprintf(logfile, "%s.%s,", stat_counters[i].tag, stat_counters[i].bits[j].regname);
fprintf(logfile, "\n");
} else {
if (logfile)
fclose(logfile);
logfile = NULL;
}
}
@@ -1163,25 +1170,25 @@ void umr_top(struct umr_asic *asic)
if (getenv("HOSTNAME")) strcpy(hostname, getenv("HOSTNAME"));
// init stats
memset(&stat_counters, 0, sizeof stat_counters);
load_options();
// select an architecture ...
top_build_vi_program(asic);
// add DRM info
- for (i = 0; stat_counters[i].name; i++);
- ENTRY(i, "DRM", &stat_drm_bits[0], &top_options.drm, "DRM");
+ for (i = 0; stat_counters[i].name[0]; i++);
+ ENTRY(i, "", "DRM", &stat_drm_bits[0], &top_options.drm, "DRM");
stat_counters[i].is_sensor = 2;
- for (i = 0; stat_counters[i].name; i++) {
+ for (i = 0; stat_counters[i].name[0]; i++) {
if (stat_counters[i].is_sensor == 0)
grab_bits(stat_counters[i].name, asic, stat_counters[i].bits, &stat_counters[i].addr);
else if (stat_counters[i].is_sensor == 3)
grab_addr(stat_counters[i].name, asic, stat_counters[i].bits, &stat_counters[i].addr);
}
sensor_thread_quit = 0;
// start thread to grab sensor data
if (pthread_create(&sensor_thread, NULL, gpu_sensor_thread, asic)) {
@@ -1205,27 +1212,27 @@ void umr_top(struct umr_asic *asic)
// setup loop
if (top_options.high_precision)
rep = 1000;
else
rep = 100;
req.tv_sec = 0;
req.tv_nsec = 1000000000/rep; // 10ms
ts = 0;
while (!top_options.quit) {
- for (i = 0; stat_counters[i].name; i++)
+ for (i = 0; stat_counters[i].name[0]; i++)
memset(stat_counters[i].counts, 0, sizeof(stat_counters[i].counts[0])*32);
for (i = 0; i < (int)rep / (top_options.high_frequency ? 10 : 1); i++) {
if (!top_options.sriov.num_vf || top_options.sriov.active_vf < 0 ||
top_options.sriov.active_vf == get_active_vf(asic, stat_counters[2].addr)) {
- for (j = 0; stat_counters[j].name; j++) {
+ for (j = 0; stat_counters[j].name[0]; j++) {
if (top_options.all || *stat_counters[j].opt) {
if (stat_counters[j].is_sensor == 0)
parse_bits(asic, stat_counters[j].addr, stat_counters[j].bits, stat_counters[j].counts, stat_counters[j].mask, stat_counters[j].cmp, stat_counters[j].addr_mask);
else if (i == 0 && stat_counters[j].is_sensor == 1) // only parse sensors on first go-around per display
parse_sensors(asic, stat_counters[j].addr, stat_counters[j].bits, stat_counters[j].counts, stat_counters[j].mask, stat_counters[j].cmp, stat_counters[j].addr_mask);
else if (i == 0 && stat_counters[j].is_sensor == 2) // only parse drm on first go-around per display
parse_drm(asic, stat_counters[j].addr, stat_counters[j].bits, stat_counters[j].counts, stat_counters[j].mask, stat_counters[j].cmp, stat_counters[j].addr_mask);
else if (stat_counters[j].is_sensor == 3)
parse_iov(asic, stat_counters[j].addr, stat_counters[j].bits, stat_counters[j].counts, stat_counters[j].mask, stat_counters[j].cmp, stat_counters[j].addr_mask);
}
@@ -1286,34 +1293,34 @@ void umr_top(struct umr_asic *asic)
tt = time(NULL);
printw("(%s[%s]) %s%s -- %s",
hostname, asic->asicname,
top_options.logger ? "(logger enabled) " : "",
top_options.high_frequency ?
(top_options.high_precision ? "(sample @ 1ms, report @ 100ms)" : "(sample @ 10ms, report @ 100ms)") :
(top_options.high_precision ? "(sample @ 1ms, report @ 1000ms)" : "(sample @ 10ms, report @ 1000ms)"),
ctime(&tt));
// figure out padding
- for (i = maxstrlen = 0; stat_counters[i].name; i++)
+ for (i = maxstrlen = 0; stat_counters[i].name[0]; i++)
if (top_options.all || *stat_counters[i].opt)
for (j = 0; stat_counters[i].bits[j].regname; j++)
if (stat_counters[i].bits[j].start != 255 && (k = strlen(stat_counters[i].bits[j].regname)) > maxstrlen)
maxstrlen = k;
snprintf(namefmt, sizeof(namefmt)-1, "%%%ds => ", maxstrlen + 1);
print_j = 0;
if (logfile != NULL) {
struct timespec tp;
clock_gettime(CLOCK_MONOTONIC, &tp);
fprintf(logfile, "%f,", ((double)tp.tv_sec * 1000000000.0 + tp.tv_nsec) / 1000000000.0);
}
- for (i = 0; stat_counters[i].name; i++) {
+ for (i = 0; stat_counters[i].name[0]; i++) {
if (top_options.all || *stat_counters[i].opt) {
if (logfile != NULL) {
for (j = 0; stat_counters[i].bits[j].regname != 0; j++) {
if (stat_counters[i].bits[j].start != 255)
fprintf(logfile, "%llu,", (unsigned long long)stat_counters[i].counts[j]);
}
}
if (!i || strcmp(stat_counters[i-1].tag, stat_counters[i].tag)) {
if (print_j & (top_options.wide ? 3 : 1))
printw("\n");
--
2.40.0
More information about the amd-gfx
mailing list