Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf amd ibs: Incorporate Zen5 DTLB and PageSize information

IBS Op PMU on Zen5 reports DTLB and page size information differently
compared to prior generation.

IBS_OP_DATA3 Zen3/4 Zen5
----------------------------------------------------------------
19 IbsDcL2TlbHit1G Reserved
----------------------------------------------------------------
6 IbsDcL2tlbHit2M Reserved
----------------------------------------------------------------
5 IbsDcL1TlbHit1G PageSize:
4 IbsDcL1TlbHit2M 0 - 4K
1 - 2M
2 - 1G
3 - Reserved
Valid only if
IbsDcPhyAddrValid = 1
----------------------------------------------------------------
3 IbsDcL2TlbMiss IbsDcL2TlbMiss
Valid only if
IbsDcPhyAddrValid = 1
----------------------------------------------------------------
2 IbsDcL1tlbMiss IbsDcL1tlbMiss
Valid only if
IbsDcPhyAddrValid = 1
----------------------------------------------------------------

Kernel expose this change as "dtlb_pgsize" capability in PMU sysfs.

Change IBS register raw-dump logic according to new bit definitions.

Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Ananth Narayan <ananth.narayan@amd.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Joe Mario <jmario@redhat.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sandipan Das <sandipan.das@amd.com>
Cc: Santosh Shukla <santosh.shukla@amd.com>
Cc: Stephane Eranian <eranian@google.com>
Link: https://lore.kernel.org/r/20250429035938.1301-3-ravi.bangoria@amd.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Ravi Bangoria and committed by
Arnaldo Carvalho de Melo
fc481adc eeefc13c

+51 -12
+51 -12
tools/perf/util/amd-sample-raw.c
··· 20 20 static u32 cpu_family, cpu_model, ibs_fetch_type, ibs_op_type; 21 21 static bool zen4_ibs_extensions; 22 22 static bool ldlat_cap; 23 + static bool dtlb_pgsize_cap; 23 24 24 25 static void pr_ibs_fetch_ctl(union ibs_fetch_ctl reg) 25 26 { ··· 162 161 163 162 static void pr_ibs_op_data3(union ibs_op_data3 reg) 164 163 { 165 - char l2_miss_str[sizeof(" L2Miss _")] = ""; 166 - char op_mem_width_str[sizeof(" OpMemWidth _____ bytes")] = ""; 164 + static const char * const dc_page_sizes[] = { 165 + " 4K", 166 + " 2M", 167 + " 1G", 168 + " ??", 169 + }; 167 170 char op_dc_miss_open_mem_reqs_str[sizeof(" OpDcMissOpenMemReqs __")] = ""; 171 + char dc_l1_l2tlb_miss_str[sizeof(" DcL1TlbMiss _ DcL2TlbMiss _")] = ""; 172 + char dc_l1tlb_hit_str[sizeof(" DcL1TlbHit2M _ DcL1TlbHit1G _")] = ""; 173 + char op_mem_width_str[sizeof(" OpMemWidth _____ bytes")] = ""; 174 + char dc_l2tlb_hit_2m_str[sizeof(" DcL2TlbHit2M _")] = ""; 175 + char dc_l2tlb_hit_1g_str[sizeof(" DcL2TlbHit1G _")] = ""; 176 + char dc_page_size_str[sizeof(" DcPageSize ____")] = ""; 177 + char l2_miss_str[sizeof(" L2Miss _")] = ""; 168 178 169 179 /* 170 180 * Erratum #1293 ··· 191 179 snprintf(op_mem_width_str, sizeof(op_mem_width_str), 192 180 " OpMemWidth %2d bytes", 1 << (reg.op_mem_width - 1)); 193 181 194 - printf("ibs_op_data3:\t%016llx LdOp %d StOp %d DcL1TlbMiss %d DcL2TlbMiss %d " 195 - "DcL1TlbHit2M %d DcL1TlbHit1G %d DcL2TlbHit2M %d DcMiss %d DcMisAcc %d " 196 - "DcWcMemAcc %d DcUcMemAcc %d DcLockedOp %d DcMissNoMabAlloc %d DcLinAddrValid %d " 197 - "DcPhyAddrValid %d DcL2TlbHit1G %d%s SwPf %d%s%s DcMissLat %5d TlbRefillLat %5d\n", 198 - reg.val, reg.ld_op, reg.st_op, reg.dc_l1tlb_miss, reg.dc_l2tlb_miss, 199 - reg.dc_l1tlb_hit_2m, reg.dc_l1tlb_hit_1g, reg.dc_l2tlb_hit_2m, reg.dc_miss, 200 - reg.dc_mis_acc, reg.dc_wc_mem_acc, reg.dc_uc_mem_acc, reg.dc_locked_op, 201 - reg.dc_miss_no_mab_alloc, reg.dc_lin_addr_valid, reg.dc_phy_addr_valid, 202 - reg.dc_l2_tlb_hit_1g, l2_miss_str, reg.sw_pf, op_mem_width_str, 203 - op_dc_miss_open_mem_reqs_str, reg.dc_miss_lat, reg.tlb_refill_lat); 182 + if (dtlb_pgsize_cap) { 183 + if (reg.dc_phy_addr_valid) { 184 + int idx = (reg.dc_l1tlb_hit_1g << 1) | reg.dc_l1tlb_hit_2m; 185 + 186 + snprintf(dc_l1_l2tlb_miss_str, sizeof(dc_l1_l2tlb_miss_str), 187 + " DcL1TlbMiss %d DcL2TlbMiss %d", 188 + reg.dc_l1tlb_miss, reg.dc_l2tlb_miss); 189 + snprintf(dc_page_size_str, sizeof(dc_page_size_str), 190 + " DcPageSize %4s", dc_page_sizes[idx]); 191 + } 192 + } else { 193 + snprintf(dc_l1_l2tlb_miss_str, sizeof(dc_l1_l2tlb_miss_str), 194 + " DcL1TlbMiss %d DcL2TlbMiss %d", 195 + reg.dc_l1tlb_miss, reg.dc_l2tlb_miss); 196 + snprintf(dc_l1tlb_hit_str, sizeof(dc_l1tlb_hit_str), 197 + " DcL1TlbHit2M %d DcL1TlbHit1G %d", 198 + reg.dc_l1tlb_hit_2m, reg.dc_l1tlb_hit_1g); 199 + snprintf(dc_l2tlb_hit_2m_str, sizeof(dc_l2tlb_hit_2m_str), 200 + " DcL2TlbHit2M %d", reg.dc_l2tlb_hit_2m); 201 + snprintf(dc_l2tlb_hit_1g_str, sizeof(dc_l2tlb_hit_1g_str), 202 + " DcL2TlbHit1G %d", reg.dc_l2_tlb_hit_1g); 203 + } 204 + 205 + printf("ibs_op_data3:\t%016llx LdOp %d StOp %d%s%s%s DcMiss %d DcMisAcc %d " 206 + "DcWcMemAcc %d DcUcMemAcc %d DcLockedOp %d DcMissNoMabAlloc %d " 207 + "DcLinAddrValid %d DcPhyAddrValid %d%s%s SwPf %d%s%s " 208 + "DcMissLat %5d TlbRefillLat %5d\n", 209 + reg.val, reg.ld_op, reg.st_op, dc_l1_l2tlb_miss_str, 210 + dtlb_pgsize_cap ? dc_page_size_str : dc_l1tlb_hit_str, 211 + dc_l2tlb_hit_2m_str, reg.dc_miss, reg.dc_mis_acc, reg.dc_wc_mem_acc, 212 + reg.dc_uc_mem_acc, reg.dc_locked_op, reg.dc_miss_no_mab_alloc, 213 + reg.dc_lin_addr_valid, reg.dc_phy_addr_valid, dc_l2tlb_hit_1g_str, 214 + l2_miss_str, reg.sw_pf, op_mem_width_str, op_dc_miss_open_mem_reqs_str, 215 + reg.dc_miss_lat, reg.tlb_refill_lat); 204 216 } 205 217 206 218 /* ··· 376 340 377 341 if (perf_env__find_pmu_cap(env, "ibs_op", "ldlat")) 378 342 ldlat_cap = 1; 343 + 344 + if (perf_env__find_pmu_cap(env, "ibs_op", "dtlb_pgsize")) 345 + dtlb_pgsize_cap = 1; 379 346 380 347 if (ibs_fetch_type || ibs_op_type) { 381 348 if (!cpu_family)