Em Wed, Jun 12, 2019 at 08:58:00AM +0300, Adrian Hunter escreveu:
> On 12/06/19 3:09 AM, Arnaldo Carvalho de Melo wrote:
> > Em Mon, Jun 10, 2019 at 10:27:53AM +0300, Adrian Hunter escreveu:
> >> Add 3 new packets to supports PEBS via PT, namely Block Begin Packet (BBP),
> >> Block Item Packet (BIP) and Block End Packet (BEP). PEBS data is encoded
> >> into multiple BIP packets that come between BBP and BEP. The BEP packet
> >> might be associated with a FUP packet. That is indicated by using a
> >> separate packet type (INTEL_PT_BEP_IP) similar to other packets types with
> >> the _IP suffix.
> >>
> >> Refer to the Intel SDM for more information about PEBS via PT.
> > 
> > In these cases would be nice to provide an URL and page number, for
> > convenience.
> 
> Intel SDM:
> 
>       https://software.intel.com/en-us/articles/intel-sdm
> 
> May 2019 version: Vol. 3B 18.5.5.2 PEBS output to IntelĀ® Processor Trace

Thanks! I'll add to that cset.

What about the kernel bits?

- Arnaldo
 
> > 
> > - Arnaldo
> >  
> >> Decoding of BIP packets conflicts with single-byte TNT packets. Since BIP
> >> packets only occur in the context of a block (i.e. between BBP and BEP),
> >> that context must be recorded and passed to the packet decoder.
> >>
> >> Signed-off-by: Adrian Hunter <adrian.hun...@intel.com>
> >> ---
> >>  .../util/intel-pt-decoder/intel-pt-decoder.c  |  38 ++++-
> >>  .../intel-pt-decoder/intel-pt-pkt-decoder.c   | 140 +++++++++++++++++-
> >>  .../intel-pt-decoder/intel-pt-pkt-decoder.h   |  21 ++-
> >>  tools/perf/util/intel-pt.c                    |   3 +-
> >>  4 files changed, 193 insertions(+), 9 deletions(-)
> >>
> >> diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c 
> >> b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
> >> index 9eb778f9c911..44218f9cf16a 100644
> >> --- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
> >> +++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
> >> @@ -140,6 +140,7 @@ struct intel_pt_decoder {
> >>    int mtc_shift;
> >>    struct intel_pt_stack stack;
> >>    enum intel_pt_pkt_state pkt_state;
> >> +  enum intel_pt_pkt_ctx pkt_ctx;
> >>    struct intel_pt_pkt packet;
> >>    struct intel_pt_pkt tnt;
> >>    int pkt_step;
> >> @@ -558,7 +559,7 @@ static int intel_pt_get_split_packet(struct 
> >> intel_pt_decoder *decoder)
> >>    memcpy(buf + len, decoder->buf, n);
> >>    len += n;
> >>  
> >> -  ret = intel_pt_get_packet(buf, len, &decoder->packet);
> >> +  ret = intel_pt_get_packet(buf, len, &decoder->packet, 
> >> &decoder->pkt_ctx);
> >>    if (ret < (int)old_len) {
> >>            decoder->next_buf = decoder->buf;
> >>            decoder->next_len = decoder->len;
> >> @@ -593,6 +594,7 @@ static int intel_pt_pkt_lookahead(struct 
> >> intel_pt_decoder *decoder,
> >>  {
> >>    struct intel_pt_pkt_info pkt_info;
> >>    const unsigned char *buf = decoder->buf;
> >> +  enum intel_pt_pkt_ctx pkt_ctx = decoder->pkt_ctx;
> >>    size_t len = decoder->len;
> >>    int ret;
> >>  
> >> @@ -611,7 +613,8 @@ static int intel_pt_pkt_lookahead(struct 
> >> intel_pt_decoder *decoder,
> >>                    if (!len)
> >>                            return INTEL_PT_NEED_MORE_BYTES;
> >>  
> >> -                  ret = intel_pt_get_packet(buf, len, &pkt_info.packet);
> >> +                  ret = intel_pt_get_packet(buf, len, &pkt_info.packet,
> >> +                                            &pkt_ctx);
> >>                    if (!ret)
> >>                            return INTEL_PT_NEED_MORE_BYTES;
> >>                    if (ret < 0)
> >> @@ -686,6 +689,10 @@ static int intel_pt_calc_cyc_cb(struct 
> >> intel_pt_pkt_info *pkt_info)
> >>    case INTEL_PT_MNT:
> >>    case INTEL_PT_PTWRITE:
> >>    case INTEL_PT_PTWRITE_IP:
> >> +  case INTEL_PT_BBP:
> >> +  case INTEL_PT_BIP:
> >> +  case INTEL_PT_BEP:
> >> +  case INTEL_PT_BEP_IP:
> >>            return 0;
> >>  
> >>    case INTEL_PT_MTC:
> >> @@ -878,7 +885,7 @@ static int intel_pt_get_next_packet(struct 
> >> intel_pt_decoder *decoder)
> >>            }
> >>  
> >>            ret = intel_pt_get_packet(decoder->buf, decoder->len,
> >> -                                    &decoder->packet);
> >> +                                    &decoder->packet, &decoder->pkt_ctx);
> >>            if (ret == INTEL_PT_NEED_MORE_BYTES && BITS_PER_LONG == 32 &&
> >>                decoder->len < INTEL_PT_PKT_MAX_SZ && !decoder->next_buf) {
> >>                    ret = intel_pt_get_split_packet(decoder);
> >> @@ -1624,6 +1631,10 @@ static int intel_pt_walk_psbend(struct 
> >> intel_pt_decoder *decoder)
> >>            case INTEL_PT_MWAIT:
> >>            case INTEL_PT_PWRE:
> >>            case INTEL_PT_PWRX:
> >> +          case INTEL_PT_BBP:
> >> +          case INTEL_PT_BIP:
> >> +          case INTEL_PT_BEP:
> >> +          case INTEL_PT_BEP_IP:
> >>                    decoder->have_tma = false;
> >>                    intel_pt_log("ERROR: Unexpected packet\n");
> >>                    err = -EAGAIN;
> >> @@ -1717,6 +1728,10 @@ static int intel_pt_walk_fup_tip(struct 
> >> intel_pt_decoder *decoder)
> >>            case INTEL_PT_MWAIT:
> >>            case INTEL_PT_PWRE:
> >>            case INTEL_PT_PWRX:
> >> +          case INTEL_PT_BBP:
> >> +          case INTEL_PT_BIP:
> >> +          case INTEL_PT_BEP:
> >> +          case INTEL_PT_BEP_IP:
> >>                    intel_pt_log("ERROR: Missing TIP after FUP\n");
> >>                    decoder->pkt_state = INTEL_PT_STATE_ERR3;
> >>                    decoder->pkt_step = 0;
> >> @@ -2038,6 +2053,12 @@ static int intel_pt_walk_trace(struct 
> >> intel_pt_decoder *decoder)
> >>                    decoder->state.pwrx_payload = decoder->packet.payload;
> >>                    return 0;
> >>  
> >> +          case INTEL_PT_BBP:
> >> +          case INTEL_PT_BIP:
> >> +          case INTEL_PT_BEP:
> >> +          case INTEL_PT_BEP_IP:
> >> +                  break;
> >> +
> >>            default:
> >>                    return intel_pt_bug(decoder);
> >>            }
> >> @@ -2076,6 +2097,10 @@ static int intel_pt_walk_psb(struct 
> >> intel_pt_decoder *decoder)
> >>            case INTEL_PT_MWAIT:
> >>            case INTEL_PT_PWRE:
> >>            case INTEL_PT_PWRX:
> >> +          case INTEL_PT_BBP:
> >> +          case INTEL_PT_BIP:
> >> +          case INTEL_PT_BEP:
> >> +          case INTEL_PT_BEP_IP:
> >>                    intel_pt_log("ERROR: Unexpected packet\n");
> >>                    err = -ENOENT;
> >>                    goto out;
> >> @@ -2282,6 +2307,10 @@ static int intel_pt_walk_to_ip(struct 
> >> intel_pt_decoder *decoder)
> >>            case INTEL_PT_MWAIT:
> >>            case INTEL_PT_PWRE:
> >>            case INTEL_PT_PWRX:
> >> +          case INTEL_PT_BBP:
> >> +          case INTEL_PT_BIP:
> >> +          case INTEL_PT_BEP:
> >> +          case INTEL_PT_BEP_IP:
> >>            default:
> >>                    break;
> >>            }
> >> @@ -2632,11 +2661,12 @@ static unsigned char *intel_pt_last_psb(unsigned 
> >> char *buf, size_t len)
> >>  static bool intel_pt_next_tsc(unsigned char *buf, size_t len, uint64_t 
> >> *tsc,
> >>                          size_t *rem)
> >>  {
> >> +  enum intel_pt_pkt_ctx ctx = INTEL_PT_NO_CTX;
> >>    struct intel_pt_pkt packet;
> >>    int ret;
> >>  
> >>    while (len) {
> >> -          ret = intel_pt_get_packet(buf, len, &packet);
> >> +          ret = intel_pt_get_packet(buf, len, &packet, &ctx);
> >>            if (ret <= 0)
> >>                    return false;
> >>            if (packet.type == INTEL_PT_TSC) {
> >> diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c 
> >> b/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c
> >> index d426761a549d..2b2793b339c0 100644
> >> --- a/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c
> >> +++ b/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c
> >> @@ -71,6 +71,10 @@ static const char * const packet_name[] = {
> >>    [INTEL_PT_MWAIT]        = "MWAIT",
> >>    [INTEL_PT_PWRE]         = "PWRE",
> >>    [INTEL_PT_PWRX]         = "PWRX",
> >> +  [INTEL_PT_BBP]          = "BBP",
> >> +  [INTEL_PT_BIP]          = "BIP",
> >> +  [INTEL_PT_BEP]          = "BEP",
> >> +  [INTEL_PT_BEP_IP]       = "BEP",
> >>  };
> >>  
> >>  const char *intel_pt_pkt_name(enum intel_pt_pkt_type type)
> >> @@ -289,6 +293,55 @@ static int intel_pt_get_pwrx(const unsigned char 
> >> *buf, size_t len,
> >>    return 7;
> >>  }
> >>  
> >> +static int intel_pt_get_bbp(const unsigned char *buf, size_t len,
> >> +                      struct intel_pt_pkt *packet)
> >> +{
> >> +  if (len < 3)
> >> +          return INTEL_PT_NEED_MORE_BYTES;
> >> +  packet->type = INTEL_PT_BBP;
> >> +  packet->count = buf[2] >> 7;
> >> +  packet->payload = buf[2] & 0x1f;
> >> +  return 3;
> >> +}
> >> +
> >> +static int intel_pt_get_bip_4(const unsigned char *buf, size_t len,
> >> +                        struct intel_pt_pkt *packet)
> >> +{
> >> +  if (len < 5)
> >> +          return INTEL_PT_NEED_MORE_BYTES;
> >> +  packet->type = INTEL_PT_BIP;
> >> +  packet->count = buf[0] >> 3;
> >> +  memcpy_le64(&packet->payload, buf + 1, 4);
> >> +  return 5;
> >> +}
> >> +
> >> +static int intel_pt_get_bip_8(const unsigned char *buf, size_t len,
> >> +                        struct intel_pt_pkt *packet)
> >> +{
> >> +  if (len < 9)
> >> +          return INTEL_PT_NEED_MORE_BYTES;
> >> +  packet->type = INTEL_PT_BIP;
> >> +  packet->count = buf[0] >> 3;
> >> +  memcpy_le64(&packet->payload, buf + 1, 8);
> >> +  return 9;
> >> +}
> >> +
> >> +static int intel_pt_get_bep(size_t len, struct intel_pt_pkt *packet)
> >> +{
> >> +  if (len < 2)
> >> +          return INTEL_PT_NEED_MORE_BYTES;
> >> +  packet->type = INTEL_PT_BEP;
> >> +  return 2;
> >> +}
> >> +
> >> +static int intel_pt_get_bep_ip(size_t len, struct intel_pt_pkt *packet)
> >> +{
> >> +  if (len < 2)
> >> +          return INTEL_PT_NEED_MORE_BYTES;
> >> +  packet->type = INTEL_PT_BEP_IP;
> >> +  return 2;
> >> +}
> >> +
> >>  static int intel_pt_get_ext(const unsigned char *buf, size_t len,
> >>                        struct intel_pt_pkt *packet)
> >>  {
> >> @@ -329,6 +382,12 @@ static int intel_pt_get_ext(const unsigned char *buf, 
> >> size_t len,
> >>            return intel_pt_get_pwre(buf, len, packet);
> >>    case 0xA2: /* PWRX */
> >>            return intel_pt_get_pwrx(buf, len, packet);
> >> +  case 0x63: /* BBP */
> >> +          return intel_pt_get_bbp(buf, len, packet);
> >> +  case 0x33: /* BEP no IP */
> >> +          return intel_pt_get_bep(len, packet);
> >> +  case 0xb3: /* BEP with IP */
> >> +          return intel_pt_get_bep_ip(len, packet);
> >>    default:
> >>            return INTEL_PT_BAD_PACKET;
> >>    }
> >> @@ -477,7 +536,8 @@ static int intel_pt_get_mtc(const unsigned char *buf, 
> >> size_t len,
> >>  }
> >>  
> >>  static int intel_pt_do_get_packet(const unsigned char *buf, size_t len,
> >> -                            struct intel_pt_pkt *packet)
> >> +                            struct intel_pt_pkt *packet,
> >> +                            enum intel_pt_pkt_ctx ctx)
> >>  {
> >>    unsigned int byte;
> >>  
> >> @@ -487,6 +547,22 @@ static int intel_pt_do_get_packet(const unsigned char 
> >> *buf, size_t len,
> >>            return INTEL_PT_NEED_MORE_BYTES;
> >>  
> >>    byte = buf[0];
> >> +
> >> +  switch (ctx) {
> >> +  case INTEL_PT_NO_CTX:
> >> +          break;
> >> +  case INTEL_PT_BLK_4_CTX:
> >> +          if ((byte & 0x7) == 4)
> >> +                  return intel_pt_get_bip_4(buf, len, packet);
> >> +          break;
> >> +  case INTEL_PT_BLK_8_CTX:
> >> +          if ((byte & 0x7) == 4)
> >> +                  return intel_pt_get_bip_8(buf, len, packet);
> >> +          break;
> >> +  default:
> >> +          break;
> >> +  };
> >> +
> >>    if (!(byte & BIT(0))) {
> >>            if (byte == 0)
> >>                    return intel_pt_get_pad(packet);
> >> @@ -525,15 +601,65 @@ static int intel_pt_do_get_packet(const unsigned 
> >> char *buf, size_t len,
> >>    }
> >>  }
> >>  
> >> +void intel_pt_upd_pkt_ctx(const struct intel_pt_pkt *packet,
> >> +                    enum intel_pt_pkt_ctx *ctx)
> >> +{
> >> +  switch (packet->type) {
> >> +  case INTEL_PT_BAD:
> >> +  case INTEL_PT_PAD:
> >> +  case INTEL_PT_TSC:
> >> +  case INTEL_PT_TMA:
> >> +  case INTEL_PT_MTC:
> >> +  case INTEL_PT_FUP:
> >> +  case INTEL_PT_CYC:
> >> +  case INTEL_PT_CBR:
> >> +  case INTEL_PT_MNT:
> >> +  case INTEL_PT_EXSTOP:
> >> +  case INTEL_PT_EXSTOP_IP:
> >> +  case INTEL_PT_PWRE:
> >> +  case INTEL_PT_PWRX:
> >> +  case INTEL_PT_BIP:
> >> +          break;
> >> +  case INTEL_PT_TNT:
> >> +  case INTEL_PT_TIP:
> >> +  case INTEL_PT_TIP_PGD:
> >> +  case INTEL_PT_TIP_PGE:
> >> +  case INTEL_PT_MODE_EXEC:
> >> +  case INTEL_PT_MODE_TSX:
> >> +  case INTEL_PT_PIP:
> >> +  case INTEL_PT_OVF:
> >> +  case INTEL_PT_VMCS:
> >> +  case INTEL_PT_TRACESTOP:
> >> +  case INTEL_PT_PSB:
> >> +  case INTEL_PT_PSBEND:
> >> +  case INTEL_PT_PTWRITE:
> >> +  case INTEL_PT_PTWRITE_IP:
> >> +  case INTEL_PT_MWAIT:
> >> +  case INTEL_PT_BEP:
> >> +  case INTEL_PT_BEP_IP:
> >> +          *ctx = INTEL_PT_NO_CTX;
> >> +          break;
> >> +  case INTEL_PT_BBP:
> >> +          if (packet->count)
> >> +                  *ctx = INTEL_PT_BLK_4_CTX;
> >> +          else
> >> +                  *ctx = INTEL_PT_BLK_8_CTX;
> >> +          break;
> >> +  default:
> >> +          break;
> >> +  }
> >> +}
> >> +
> >>  int intel_pt_get_packet(const unsigned char *buf, size_t len,
> >> -                  struct intel_pt_pkt *packet)
> >> +                  struct intel_pt_pkt *packet, enum intel_pt_pkt_ctx *ctx)
> >>  {
> >>    int ret;
> >>  
> >> -  ret = intel_pt_do_get_packet(buf, len, packet);
> >> +  ret = intel_pt_do_get_packet(buf, len, packet, *ctx);
> >>    if (ret > 0) {
> >>            while (ret < 8 && len > (size_t)ret && !buf[ret])
> >>                    ret += 1;
> >> +          intel_pt_upd_pkt_ctx(packet, ctx);
> >>    }
> >>    return ret;
> >>  }
> >> @@ -611,8 +737,10 @@ int intel_pt_pkt_desc(const struct intel_pt_pkt 
> >> *packet, char *buf,
> >>            return snprintf(buf, buf_len, "%s 0x%llx IP:0", name, payload);
> >>    case INTEL_PT_PTWRITE_IP:
> >>            return snprintf(buf, buf_len, "%s 0x%llx IP:1", name, payload);
> >> +  case INTEL_PT_BEP:
> >>    case INTEL_PT_EXSTOP:
> >>            return snprintf(buf, buf_len, "%s IP:0", name);
> >> +  case INTEL_PT_BEP_IP:
> >>    case INTEL_PT_EXSTOP_IP:
> >>            return snprintf(buf, buf_len, "%s IP:1", name);
> >>    case INTEL_PT_MWAIT:
> >> @@ -630,6 +758,12 @@ int intel_pt_pkt_desc(const struct intel_pt_pkt 
> >> *packet, char *buf,
> >>                            (unsigned int)((payload >> 4) & 0xf),
> >>                            (unsigned int)(payload & 0xf),
> >>                            (unsigned int)((payload >> 8) & 0xf));
> >> +  case INTEL_PT_BBP:
> >> +          return snprintf(buf, buf_len, "%s SZ %s-byte Type 0x%llx",
> >> +                          name, packet->count ? "4" : "8", payload);
> >> +  case INTEL_PT_BIP:
> >> +          return snprintf(buf, buf_len, "%s ID 0x%02x Value 0x%llx",
> >> +                          name, packet->count, payload);
> >>    default:
> >>            break;
> >>    }
> >> diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.h 
> >> b/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.h
> >> index 73ddc3a88d07..682b35282abc 100644
> >> --- a/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.h
> >> +++ b/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.h
> >> @@ -59,6 +59,10 @@ enum intel_pt_pkt_type {
> >>    INTEL_PT_MWAIT,
> >>    INTEL_PT_PWRE,
> >>    INTEL_PT_PWRX,
> >> +  INTEL_PT_BBP,
> >> +  INTEL_PT_BIP,
> >> +  INTEL_PT_BEP,
> >> +  INTEL_PT_BEP_IP,
> >>  };
> >>  
> >>  struct intel_pt_pkt {
> >> @@ -67,10 +71,25 @@ struct intel_pt_pkt {
> >>    uint64_t                payload;
> >>  };
> >>  
> >> +/*
> >> + * Decoding of BIP packets conflicts with single-byte TNT packets. Since 
> >> BIP
> >> + * packets only occur in the context of a block (i.e. between BBP and 
> >> BEP), that
> >> + * context must be recorded and passed to the packet decoder.
> >> + */
> >> +enum intel_pt_pkt_ctx {
> >> +  INTEL_PT_NO_CTX,        /* BIP packets are invalid */
> >> +  INTEL_PT_BLK_4_CTX,     /* 4-byte BIP packets */
> >> +  INTEL_PT_BLK_8_CTX,     /* 8-byte BIP packets */
> >> +};
> >> +
> >>  const char *intel_pt_pkt_name(enum intel_pt_pkt_type);
> >>  
> >>  int intel_pt_get_packet(const unsigned char *buf, size_t len,
> >> -                  struct intel_pt_pkt *packet);
> >> +                  struct intel_pt_pkt *packet,
> >> +                  enum intel_pt_pkt_ctx *ctx);
> >> +
> >> +void intel_pt_upd_pkt_ctx(const struct intel_pt_pkt *packet,
> >> +                    enum intel_pt_pkt_ctx *ctx);
> >>  
> >>  int intel_pt_pkt_desc(const struct intel_pt_pkt *packet, char *buf, 
> >> size_t len);
> >>  
> >> diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
> >> index 3cff8fe2eaa0..f43d3ac2db8b 100644
> >> --- a/tools/perf/util/intel-pt.c
> >> +++ b/tools/perf/util/intel-pt.c
> >> @@ -174,13 +174,14 @@ static void intel_pt_dump(struct intel_pt *pt 
> >> __maybe_unused,
> >>    int ret, pkt_len, i;
> >>    char desc[INTEL_PT_PKT_DESC_MAX];
> >>    const char *color = PERF_COLOR_BLUE;
> >> +  enum intel_pt_pkt_ctx ctx = INTEL_PT_NO_CTX;
> >>  
> >>    color_fprintf(stdout, color,
> >>                  ". ... Intel Processor Trace data: size %zu bytes\n",
> >>                  len);
> >>  
> >>    while (len) {
> >> -          ret = intel_pt_get_packet(buf, len, &packet);
> >> +          ret = intel_pt_get_packet(buf, len, &packet, &ctx);
> >>            if (ret > 0)
> >>                    pkt_len = ret;
> >>            else
> >> -- 
> >> 2.17.1
> > 

-- 

- Arnaldo

Reply via email to