akaros/user/perfmon/pfmlib_intel_rapl.c
<<
>>
Prefs
   1/*
   2 * pfmlib_intel_rapl.c : Intel RAPL PMU
   3 *
   4 * Copyright (c) 2013 Google, Inc
   5 * Contributed by Stephane Eranian <eranian@gmail.com>
   6 *
   7 * Based on:
   8 * Copyright (c) 2006 Hewlett-Packard Development Company, L.P.
   9 * Contributed by Stephane Eranian <eranian@hpl.hp.com>
  10 *
  11 * Permission is hereby granted, free of charge, to any person obtaining a copy
  12 * of this software and associated documentation files (the "Software"), to deal
  13 * in the Software without restriction, including without limitation the rights
  14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  15 * of the Software, and to permit persons to whom the Software is furnished to do so,
  16 * subject to the following conditions:
  17 *
  18 * The above copyright notice and this permission notice shall be included in all
  19 * copies or substantial portions of the Software.
  20 *
  21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  22 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  23 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  24 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  25 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
  26 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27 *
  28 * RAPL PMU (SNB, IVB, HSW)
  29 */
  30
  31/* private headers */
  32#include "pfmlib_priv.h"
  33/*
  34 * for now, we reuse the x86 table entry format and callback to avoid duplicating
  35 * code. We may revisit this later on
  36 */
  37#include "pfmlib_intel_x86_priv.h"
  38
  39extern pfmlib_pmu_t intel_rapl_support;
  40
  41#define RAPL_COMMON_EVENTS \
  42  { .name   = "RAPL_ENERGY_CORES",\
  43    .desc   = "Number of Joules consumed by all cores on the package. Unit is 2^-32 Joules",\
  44    .cntmsk = 0x1,\
  45    .code   = 0x1,\
  46  },\
  47  { .name   = "RAPL_ENERGY_PKG",\
  48    .desc   = "Number of Joules consumed by all cores and Last level cache on the package. Unit is 2^-32 Joules",\
  49    .cntmsk = 0x2,\
  50    .code   = 0x2,\
  51  }
  52
  53static const intel_x86_entry_t intel_rapl_cln_pe[]={
  54  RAPL_COMMON_EVENTS,
  55  { .name   = "RAPL_ENERGY_GPU",
  56    .desc   = "Number of Joules consumed by the builtin GPU. Unit is 2^-32 Joules",
  57    .cntmsk = 0x8,
  58    .code   = 0x4,
  59  }
  60};
  61
  62static const intel_x86_entry_t intel_rapl_srv_pe[]={
  63  RAPL_COMMON_EVENTS,
  64  { .name   = "RAPL_ENERGY_DRAM",
  65    .desc   = "Number of Joules consumed by the DRAM. Unit is 2^-32 Joules",
  66    .cntmsk = 0x4,
  67    .code   = 0x3,
  68  },
  69};
  70
  71static int
  72pfm_rapl_detect(void *this)
  73{
  74        int ret;
  75
  76        ret = pfm_intel_x86_detect();
  77        if (ret != PFM_SUCCESS)
  78                return ret;
  79
  80        if (pfm_intel_x86_cfg.family != 6)
  81                return PFM_ERR_NOTSUPP;
  82
  83        switch(pfm_intel_x86_cfg.model) {
  84                case 42: /* Sandy Bridge */
  85                case 58: /* Ivy Bridge */
  86                case 60: /* Haswell */
  87                case 69: /* Haswell */
  88                case 70: /* Haswell */
  89                case 71: /* Haswell */
  90                         /* already setup by default */
  91                          break;
  92                case 45: /* Sandy Bridg-EP  */
  93                case 62: /* Ivy Bridge-EP  */
  94                        intel_rapl_support.pe        = intel_rapl_srv_pe;
  95                        intel_rapl_support.pme_count = LIBPFM_ARRAY_SIZE(intel_rapl_srv_pe);
  96                        break;
  97                default:
  98                        return PFM_ERR_NOTSUPP;
  99        }
 100        return PFM_SUCCESS;
 101}
 102
 103static int
 104pfm_intel_rapl_get_encoding(void *this, pfmlib_event_desc_t *e)
 105
 106{
 107        const intel_x86_entry_t *pe;
 108
 109        pe = this_pe(this);
 110
 111        e->fstr[0] = '\0';
 112
 113        e->codes[0] = pe[e->event].code;
 114        e->count = 1;
 115        evt_strcat(e->fstr, "%s", pe[e->event].name);
 116
 117        __pfm_vbprintf("[0x%"PRIx64" event=0x%x] %s\n",
 118                       e->codes[0],
 119                       e->codes[0], e->fstr);
 120
 121        return PFM_SUCCESS;
 122}
 123
 124/*
 125 * number modifiers for RAPL
 126 * define an empty modifier to avoid firing the
 127 * sanity pfm_intel_x86_validate_table(). We are
 128 * using this function to avoid duplicating code.
 129 */
 130static const pfmlib_attr_desc_t rapl_mods[]=
 131{};
 132
 133pfmlib_pmu_t intel_rapl_support={
 134        .desc                   = "Intel RAPL",
 135        .name                   = "rapl",
 136        .perf_name              = "power",
 137        .pmu                    = PFM_PMU_INTEL_RAPL,
 138        .pme_count              = LIBPFM_ARRAY_SIZE(intel_rapl_cln_pe),
 139        .type                   = PFM_PMU_TYPE_UNCORE,
 140        .num_cntrs              = 0,
 141        .num_fixed_cntrs        = 3,
 142        .max_encoding           = 1,
 143        .pe                     = intel_rapl_cln_pe, /* default, maybe updated */
 144        .pmu_detect             = pfm_rapl_detect,
 145        .atdesc                 = rapl_mods,
 146
 147        .get_event_encoding[PFM_OS_NONE] = pfm_intel_rapl_get_encoding,
 148         PFMLIB_ENCODE_PERF(pfm_intel_x86_get_perf_encoding),
 149         PFMLIB_OS_DETECT(pfm_intel_x86_perf_detect), \
 150        .get_event_first        = pfm_intel_x86_get_event_first,
 151        .get_event_next         = pfm_intel_x86_get_event_next,
 152        .event_is_valid         = pfm_intel_x86_event_is_valid,
 153        .validate_table         = pfm_intel_x86_validate_table,
 154        .get_event_info         = pfm_intel_x86_get_event_info,
 155        .get_event_attr_info    = pfm_intel_x86_get_event_attr_info,
 156         PFMLIB_VALID_PERF_PATTRS(pfm_intel_x86_perf_validate_pattrs),
 157        .get_event_nattrs       = pfm_intel_x86_get_event_nattrs,
 158};
 159