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

perf intel-pt: Add decoder support for ptwrite and power event packets

Add decoder support for PTWRITE, MWAIT, PWRE, PWRX and EXSTOP packets. This
patch only affects the decoder, so the tools still do not select or consume
the new information. That is added in subsequent patches.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Link: http://lkml.kernel.org/r/1495786658-18063-14-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Adrian Hunter and committed by
Arnaldo Carvalho de Melo
a472e65f 2bc60ffd

+293 -8
+168 -8
tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
··· 158 158 bool continuous_period; 159 159 bool overflow; 160 160 bool set_fup_tx_flags; 161 + bool set_fup_ptw; 162 + bool set_fup_mwait; 163 + bool set_fup_pwre; 164 + bool set_fup_exstop; 161 165 unsigned int fup_tx_flags; 162 166 unsigned int tx_flags; 167 + uint64_t fup_ptw_payload; 168 + uint64_t fup_mwait_payload; 169 + uint64_t fup_pwre_payload; 163 170 uint64_t timestamp_insn_cnt; 164 171 uint64_t sample_insn_cnt; 165 172 uint64_t stuck_ip; ··· 667 660 case INTEL_PT_PAD: 668 661 case INTEL_PT_VMCS: 669 662 case INTEL_PT_MNT: 663 + case INTEL_PT_PTWRITE: 664 + case INTEL_PT_PTWRITE_IP: 670 665 return 0; 671 666 672 667 case INTEL_PT_MTC: ··· 767 758 768 759 case INTEL_PT_TIP_PGD: 769 760 case INTEL_PT_TRACESTOP: 761 + case INTEL_PT_EXSTOP: 762 + case INTEL_PT_EXSTOP_IP: 763 + case INTEL_PT_MWAIT: 764 + case INTEL_PT_PWRE: 765 + case INTEL_PT_PWRX: 770 766 case INTEL_PT_OVF: 771 767 case INTEL_PT_BAD: /* Does not happen */ 772 768 default: ··· 1030 1016 return err; 1031 1017 } 1032 1018 1019 + static bool intel_pt_fup_event(struct intel_pt_decoder *decoder) 1020 + { 1021 + bool ret = false; 1022 + 1023 + if (decoder->set_fup_tx_flags) { 1024 + decoder->set_fup_tx_flags = false; 1025 + decoder->tx_flags = decoder->fup_tx_flags; 1026 + decoder->state.type = INTEL_PT_TRANSACTION; 1027 + decoder->state.from_ip = decoder->ip; 1028 + decoder->state.to_ip = 0; 1029 + decoder->state.flags = decoder->fup_tx_flags; 1030 + return true; 1031 + } 1032 + if (decoder->set_fup_ptw) { 1033 + decoder->set_fup_ptw = false; 1034 + decoder->state.type = INTEL_PT_PTW; 1035 + decoder->state.flags |= INTEL_PT_FUP_IP; 1036 + decoder->state.from_ip = decoder->ip; 1037 + decoder->state.to_ip = 0; 1038 + decoder->state.ptw_payload = decoder->fup_ptw_payload; 1039 + return true; 1040 + } 1041 + if (decoder->set_fup_mwait) { 1042 + decoder->set_fup_mwait = false; 1043 + decoder->state.type = INTEL_PT_MWAIT_OP; 1044 + decoder->state.from_ip = decoder->ip; 1045 + decoder->state.to_ip = 0; 1046 + decoder->state.mwait_payload = decoder->fup_mwait_payload; 1047 + ret = true; 1048 + } 1049 + if (decoder->set_fup_pwre) { 1050 + decoder->set_fup_pwre = false; 1051 + decoder->state.type |= INTEL_PT_PWR_ENTRY; 1052 + decoder->state.type &= ~INTEL_PT_BRANCH; 1053 + decoder->state.from_ip = decoder->ip; 1054 + decoder->state.to_ip = 0; 1055 + decoder->state.pwre_payload = decoder->fup_pwre_payload; 1056 + ret = true; 1057 + } 1058 + if (decoder->set_fup_exstop) { 1059 + decoder->set_fup_exstop = false; 1060 + decoder->state.type |= INTEL_PT_EX_STOP; 1061 + decoder->state.type &= ~INTEL_PT_BRANCH; 1062 + decoder->state.flags |= INTEL_PT_FUP_IP; 1063 + decoder->state.from_ip = decoder->ip; 1064 + decoder->state.to_ip = 0; 1065 + ret = true; 1066 + } 1067 + return ret; 1068 + } 1069 + 1033 1070 static int intel_pt_walk_fup(struct intel_pt_decoder *decoder) 1034 1071 { 1035 1072 struct intel_pt_insn intel_pt_insn; ··· 1094 1029 if (err == INTEL_PT_RETURN) 1095 1030 return 0; 1096 1031 if (err == -EAGAIN) { 1097 - if (decoder->set_fup_tx_flags) { 1098 - decoder->set_fup_tx_flags = false; 1099 - decoder->tx_flags = decoder->fup_tx_flags; 1100 - decoder->state.type = INTEL_PT_TRANSACTION; 1101 - decoder->state.from_ip = decoder->ip; 1102 - decoder->state.to_ip = 0; 1103 - decoder->state.flags = decoder->fup_tx_flags; 1032 + if (intel_pt_fup_event(decoder)) 1104 1033 return 0; 1105 - } 1106 1034 return err; 1107 1035 } 1108 1036 decoder->set_fup_tx_flags = false; ··· 1501 1443 case INTEL_PT_TRACESTOP: 1502 1444 case INTEL_PT_BAD: 1503 1445 case INTEL_PT_PSB: 1446 + case INTEL_PT_PTWRITE: 1447 + case INTEL_PT_PTWRITE_IP: 1448 + case INTEL_PT_EXSTOP: 1449 + case INTEL_PT_EXSTOP_IP: 1450 + case INTEL_PT_MWAIT: 1451 + case INTEL_PT_PWRE: 1452 + case INTEL_PT_PWRX: 1504 1453 decoder->have_tma = false; 1505 1454 intel_pt_log("ERROR: Unexpected packet\n"); 1506 1455 return -EAGAIN; ··· 1589 1524 case INTEL_PT_MODE_TSX: 1590 1525 case INTEL_PT_BAD: 1591 1526 case INTEL_PT_PSBEND: 1527 + case INTEL_PT_PTWRITE: 1528 + case INTEL_PT_PTWRITE_IP: 1529 + case INTEL_PT_EXSTOP: 1530 + case INTEL_PT_EXSTOP_IP: 1531 + case INTEL_PT_MWAIT: 1532 + case INTEL_PT_PWRE: 1533 + case INTEL_PT_PWRX: 1592 1534 intel_pt_log("ERROR: Missing TIP after FUP\n"); 1593 1535 decoder->pkt_state = INTEL_PT_STATE_ERR3; 1594 1536 return -ENOENT; ··· 1726 1654 intel_pt_set_last_ip(decoder); 1727 1655 if (!decoder->branch_enable) { 1728 1656 decoder->ip = decoder->last_ip; 1657 + if (intel_pt_fup_event(decoder)) 1658 + return 0; 1659 + no_tip = false; 1729 1660 break; 1730 1661 } 1662 + if (decoder->set_fup_mwait) 1663 + no_tip = true; 1731 1664 err = intel_pt_walk_fup(decoder); 1732 1665 if (err != -EAGAIN) { 1733 1666 if (err) ··· 1832 1755 case INTEL_PT_PAD: 1833 1756 break; 1834 1757 1758 + case INTEL_PT_PTWRITE_IP: 1759 + decoder->fup_ptw_payload = decoder->packet.payload; 1760 + err = intel_pt_get_next_packet(decoder); 1761 + if (err) 1762 + return err; 1763 + if (decoder->packet.type == INTEL_PT_FUP) { 1764 + decoder->set_fup_ptw = true; 1765 + no_tip = true; 1766 + } else { 1767 + intel_pt_log_at("ERROR: Missing FUP after PTWRITE", 1768 + decoder->pos); 1769 + } 1770 + goto next; 1771 + 1772 + case INTEL_PT_PTWRITE: 1773 + decoder->state.type = INTEL_PT_PTW; 1774 + decoder->state.from_ip = decoder->ip; 1775 + decoder->state.to_ip = 0; 1776 + decoder->state.ptw_payload = decoder->packet.payload; 1777 + return 0; 1778 + 1779 + case INTEL_PT_MWAIT: 1780 + decoder->fup_mwait_payload = decoder->packet.payload; 1781 + decoder->set_fup_mwait = true; 1782 + break; 1783 + 1784 + case INTEL_PT_PWRE: 1785 + if (decoder->set_fup_mwait) { 1786 + decoder->fup_pwre_payload = 1787 + decoder->packet.payload; 1788 + decoder->set_fup_pwre = true; 1789 + break; 1790 + } 1791 + decoder->state.type = INTEL_PT_PWR_ENTRY; 1792 + decoder->state.from_ip = decoder->ip; 1793 + decoder->state.to_ip = 0; 1794 + decoder->state.pwrx_payload = decoder->packet.payload; 1795 + return 0; 1796 + 1797 + case INTEL_PT_EXSTOP_IP: 1798 + err = intel_pt_get_next_packet(decoder); 1799 + if (err) 1800 + return err; 1801 + if (decoder->packet.type == INTEL_PT_FUP) { 1802 + decoder->set_fup_exstop = true; 1803 + no_tip = true; 1804 + } else { 1805 + intel_pt_log_at("ERROR: Missing FUP after EXSTOP", 1806 + decoder->pos); 1807 + } 1808 + goto next; 1809 + 1810 + case INTEL_PT_EXSTOP: 1811 + decoder->state.type = INTEL_PT_EX_STOP; 1812 + decoder->state.from_ip = decoder->ip; 1813 + decoder->state.to_ip = 0; 1814 + return 0; 1815 + 1816 + case INTEL_PT_PWRX: 1817 + decoder->state.type = INTEL_PT_PWR_EXIT; 1818 + decoder->state.from_ip = decoder->ip; 1819 + decoder->state.to_ip = 0; 1820 + decoder->state.pwrx_payload = decoder->packet.payload; 1821 + return 0; 1822 + 1835 1823 default: 1836 1824 return intel_pt_bug(decoder); 1837 1825 } ··· 1926 1784 __fallthrough; 1927 1785 case INTEL_PT_TIP_PGE: 1928 1786 case INTEL_PT_TIP: 1787 + case INTEL_PT_PTWRITE: 1788 + case INTEL_PT_PTWRITE_IP: 1789 + case INTEL_PT_EXSTOP: 1790 + case INTEL_PT_EXSTOP_IP: 1791 + case INTEL_PT_MWAIT: 1792 + case INTEL_PT_PWRE: 1793 + case INTEL_PT_PWRX: 1929 1794 intel_pt_log("ERROR: Unexpected packet\n"); 1930 1795 return -ENOENT; 1931 1796 ··· 2107 1958 case INTEL_PT_VMCS: 2108 1959 case INTEL_PT_MNT: 2109 1960 case INTEL_PT_PAD: 1961 + case INTEL_PT_PTWRITE: 1962 + case INTEL_PT_PTWRITE_IP: 1963 + case INTEL_PT_EXSTOP: 1964 + case INTEL_PT_EXSTOP_IP: 1965 + case INTEL_PT_MWAIT: 1966 + case INTEL_PT_PWRE: 1967 + case INTEL_PT_PWRX: 2110 1968 default: 2111 1969 break; 2112 1970 } ··· 2125 1969 int err; 2126 1970 2127 1971 decoder->set_fup_tx_flags = false; 1972 + decoder->set_fup_ptw = false; 1973 + decoder->set_fup_mwait = false; 1974 + decoder->set_fup_pwre = false; 1975 + decoder->set_fup_exstop = false; 2128 1976 2129 1977 if (!decoder->branch_enable) { 2130 1978 decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
+10
tools/perf/util/intel-pt-decoder/intel-pt-decoder.h
··· 25 25 #define INTEL_PT_IN_TX (1 << 0) 26 26 #define INTEL_PT_ABORT_TX (1 << 1) 27 27 #define INTEL_PT_ASYNC (1 << 2) 28 + #define INTEL_PT_FUP_IP (1 << 3) 28 29 29 30 enum intel_pt_sample_type { 30 31 INTEL_PT_BRANCH = 1 << 0, 31 32 INTEL_PT_INSTRUCTION = 1 << 1, 32 33 INTEL_PT_TRANSACTION = 1 << 2, 34 + INTEL_PT_PTW = 1 << 3, 35 + INTEL_PT_MWAIT_OP = 1 << 4, 36 + INTEL_PT_PWR_ENTRY = 1 << 5, 37 + INTEL_PT_EX_STOP = 1 << 6, 38 + INTEL_PT_PWR_EXIT = 1 << 7, 33 39 }; 34 40 35 41 enum intel_pt_period_type { ··· 69 63 uint64_t timestamp; 70 64 uint64_t est_timestamp; 71 65 uint64_t trace_nr; 66 + uint64_t ptw_payload; 67 + uint64_t mwait_payload; 68 + uint64_t pwre_payload; 69 + uint64_t pwrx_payload; 72 70 uint32_t flags; 73 71 enum intel_pt_insn_op insn_op; 74 72 int insn_len;
+108
tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c
··· 64 64 [INTEL_PT_PIP] = "PIP", 65 65 [INTEL_PT_OVF] = "OVF", 66 66 [INTEL_PT_MNT] = "MNT", 67 + [INTEL_PT_PTWRITE] = "PTWRITE", 68 + [INTEL_PT_PTWRITE_IP] = "PTWRITE", 69 + [INTEL_PT_EXSTOP] = "EXSTOP", 70 + [INTEL_PT_EXSTOP_IP] = "EXSTOP", 71 + [INTEL_PT_MWAIT] = "MWAIT", 72 + [INTEL_PT_PWRE] = "PWRE", 73 + [INTEL_PT_PWRX] = "PWRX", 67 74 }; 68 75 69 76 const char *intel_pt_pkt_name(enum intel_pt_pkt_type type) ··· 224 217 } 225 218 } 226 219 220 + static int intel_pt_get_ptwrite(const unsigned char *buf, size_t len, 221 + struct intel_pt_pkt *packet) 222 + { 223 + packet->count = (buf[1] >> 5) & 0x3; 224 + packet->type = buf[1] & BIT(7) ? INTEL_PT_PTWRITE_IP : 225 + INTEL_PT_PTWRITE; 226 + 227 + switch (packet->count) { 228 + case 0: 229 + if (len < 6) 230 + return INTEL_PT_NEED_MORE_BYTES; 231 + packet->payload = le32_to_cpu(*(uint32_t *)(buf + 2)); 232 + return 6; 233 + case 1: 234 + if (len < 10) 235 + return INTEL_PT_NEED_MORE_BYTES; 236 + packet->payload = le64_to_cpu(*(uint64_t *)(buf + 2)); 237 + return 10; 238 + default: 239 + return INTEL_PT_BAD_PACKET; 240 + } 241 + } 242 + 243 + static int intel_pt_get_exstop(struct intel_pt_pkt *packet) 244 + { 245 + packet->type = INTEL_PT_EXSTOP; 246 + return 2; 247 + } 248 + 249 + static int intel_pt_get_exstop_ip(struct intel_pt_pkt *packet) 250 + { 251 + packet->type = INTEL_PT_EXSTOP_IP; 252 + return 2; 253 + } 254 + 255 + static int intel_pt_get_mwait(const unsigned char *buf, size_t len, 256 + struct intel_pt_pkt *packet) 257 + { 258 + if (len < 10) 259 + return INTEL_PT_NEED_MORE_BYTES; 260 + packet->type = INTEL_PT_MWAIT; 261 + packet->payload = le64_to_cpu(*(uint64_t *)(buf + 2)); 262 + return 10; 263 + } 264 + 265 + static int intel_pt_get_pwre(const unsigned char *buf, size_t len, 266 + struct intel_pt_pkt *packet) 267 + { 268 + if (len < 4) 269 + return INTEL_PT_NEED_MORE_BYTES; 270 + packet->type = INTEL_PT_PWRE; 271 + memcpy_le64(&packet->payload, buf + 2, 2); 272 + return 4; 273 + } 274 + 275 + static int intel_pt_get_pwrx(const unsigned char *buf, size_t len, 276 + struct intel_pt_pkt *packet) 277 + { 278 + if (len < 7) 279 + return INTEL_PT_NEED_MORE_BYTES; 280 + packet->type = INTEL_PT_PWRX; 281 + memcpy_le64(&packet->payload, buf + 2, 5); 282 + return 7; 283 + } 284 + 227 285 static int intel_pt_get_ext(const unsigned char *buf, size_t len, 228 286 struct intel_pt_pkt *packet) 229 287 { 230 288 if (len < 2) 231 289 return INTEL_PT_NEED_MORE_BYTES; 290 + 291 + if ((buf[1] & 0x1f) == 0x12) 292 + return intel_pt_get_ptwrite(buf, len, packet); 232 293 233 294 switch (buf[1]) { 234 295 case 0xa3: /* Long TNT */ ··· 319 244 return intel_pt_get_tma(buf, len, packet); 320 245 case 0xC3: /* 3-byte header */ 321 246 return intel_pt_get_3byte(buf, len, packet); 247 + case 0x62: /* EXSTOP no IP */ 248 + return intel_pt_get_exstop(packet); 249 + case 0xE2: /* EXSTOP with IP */ 250 + return intel_pt_get_exstop_ip(packet); 251 + case 0xC2: /* MWAIT */ 252 + return intel_pt_get_mwait(buf, len, packet); 253 + case 0x22: /* PWRE */ 254 + return intel_pt_get_pwre(buf, len, packet); 255 + case 0xA2: /* PWRX */ 256 + return intel_pt_get_pwrx(buf, len, packet); 322 257 default: 323 258 return INTEL_PT_BAD_PACKET; 324 259 } ··· 607 522 ret = snprintf(buf, buf_len, "%s 0x%llx (NR=%d)", 608 523 name, payload, nr); 609 524 return ret; 525 + case INTEL_PT_PTWRITE: 526 + return snprintf(buf, buf_len, "%s 0x%llx IP:0", name, payload); 527 + case INTEL_PT_PTWRITE_IP: 528 + return snprintf(buf, buf_len, "%s 0x%llx IP:1", name, payload); 529 + case INTEL_PT_EXSTOP: 530 + return snprintf(buf, buf_len, "%s IP:0", name); 531 + case INTEL_PT_EXSTOP_IP: 532 + return snprintf(buf, buf_len, "%s IP:1", name); 533 + case INTEL_PT_MWAIT: 534 + return snprintf(buf, buf_len, "%s 0x%llx Hints 0x%x Extensions 0x%x", 535 + name, payload, (unsigned int)(payload & 0xff), 536 + (unsigned int)((payload >> 32) & 0x3)); 537 + case INTEL_PT_PWRE: 538 + return snprintf(buf, buf_len, "%s 0x%llx HW:%u CState:%u Sub-CState:%u", 539 + name, payload, !!(payload & 0x80), 540 + (unsigned int)((payload >> 12) & 0xf), 541 + (unsigned int)((payload >> 8) & 0xf)); 542 + case INTEL_PT_PWRX: 543 + return snprintf(buf, buf_len, "%s 0x%llx Last CState:%u Deepest CState:%u Wake Reason 0x%x", 544 + name, payload, 545 + (unsigned int)((payload >> 4) & 0xf), 546 + (unsigned int)(payload & 0xf), 547 + (unsigned int)((payload >> 8) & 0xf)); 610 548 default: 611 549 break; 612 550 }
+7
tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.h
··· 52 52 INTEL_PT_PIP, 53 53 INTEL_PT_OVF, 54 54 INTEL_PT_MNT, 55 + INTEL_PT_PTWRITE, 56 + INTEL_PT_PTWRITE_IP, 57 + INTEL_PT_EXSTOP, 58 + INTEL_PT_EXSTOP_IP, 59 + INTEL_PT_MWAIT, 60 + INTEL_PT_PWRE, 61 + INTEL_PT_PWRX, 55 62 }; 56 63 57 64 struct intel_pt_pkt {