perf_event_intel_rapl.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679
  1. /*
  2. * perf_event_intel_rapl.c: support Intel RAPL energy consumption counters
  3. * Copyright (C) 2013 Google, Inc., Stephane Eranian
  4. *
  5. * Intel RAPL interface is specified in the IA-32 Manual Vol3b
  6. * section 14.7.1 (September 2013)
  7. *
  8. * RAPL provides more controls than just reporting energy consumption
  9. * however here we only expose the 3 energy consumption free running
  10. * counters (pp0, pkg, dram).
  11. *
  12. * Each of those counters increments in a power unit defined by the
  13. * RAPL_POWER_UNIT MSR. On SandyBridge, this unit is 1/(2^16) Joules
  14. * but it can vary.
  15. *
  16. * Counter to rapl events mappings:
  17. *
  18. * pp0 counter: consumption of all physical cores (power plane 0)
  19. * event: rapl_energy_cores
  20. * perf code: 0x1
  21. *
  22. * pkg counter: consumption of the whole processor package
  23. * event: rapl_energy_pkg
  24. * perf code: 0x2
  25. *
  26. * dram counter: consumption of the dram domain (servers only)
  27. * event: rapl_energy_dram
  28. * perf code: 0x3
  29. *
  30. * dram counter: consumption of the builtin-gpu domain (client only)
  31. * event: rapl_energy_gpu
  32. * perf code: 0x4
  33. *
  34. * We manage those counters as free running (read-only). They may be
  35. * use simultaneously by other tools, such as turbostat.
  36. *
  37. * The events only support system-wide mode counting. There is no
  38. * sampling support because it does not make sense and is not
  39. * supported by the RAPL hardware.
  40. *
  41. * Because we want to avoid floating-point operations in the kernel,
  42. * the events are all reported in fixed point arithmetic (32.32).
  43. * Tools must adjust the counts to convert them to Watts using
  44. * the duration of the measurement. Tools may use a function such as
  45. * ldexp(raw_count, -32);
  46. */
  47. #include <linux/module.h>
  48. #include <linux/slab.h>
  49. #include <linux/perf_event.h>
  50. #include <asm/cpu_device_id.h>
  51. #include "perf_event.h"
  52. /*
  53. * RAPL energy status counters
  54. */
  55. #define RAPL_IDX_PP0_NRG_STAT 0 /* all cores */
  56. #define INTEL_RAPL_PP0 0x1 /* pseudo-encoding */
  57. #define RAPL_IDX_PKG_NRG_STAT 1 /* entire package */
  58. #define INTEL_RAPL_PKG 0x2 /* pseudo-encoding */
  59. #define RAPL_IDX_RAM_NRG_STAT 2 /* DRAM */
  60. #define INTEL_RAPL_RAM 0x3 /* pseudo-encoding */
  61. #define RAPL_IDX_PP1_NRG_STAT 3 /* DRAM */
  62. #define INTEL_RAPL_PP1 0x4 /* pseudo-encoding */
  63. /* Clients have PP0, PKG */
  64. #define RAPL_IDX_CLN (1<<RAPL_IDX_PP0_NRG_STAT|\
  65. 1<<RAPL_IDX_PKG_NRG_STAT|\
  66. 1<<RAPL_IDX_PP1_NRG_STAT)
  67. /* Servers have PP0, PKG, RAM */
  68. #define RAPL_IDX_SRV (1<<RAPL_IDX_PP0_NRG_STAT|\
  69. 1<<RAPL_IDX_PKG_NRG_STAT|\
  70. 1<<RAPL_IDX_RAM_NRG_STAT)
  71. /*
  72. * event code: LSB 8 bits, passed in attr->config
  73. * any other bit is reserved
  74. */
  75. #define RAPL_EVENT_MASK 0xFFULL
  76. #define DEFINE_RAPL_FORMAT_ATTR(_var, _name, _format) \
  77. static ssize_t __rapl_##_var##_show(struct kobject *kobj, \
  78. struct kobj_attribute *attr, \
  79. char *page) \
  80. { \
  81. BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \
  82. return sprintf(page, _format "\n"); \
  83. } \
  84. static struct kobj_attribute format_attr_##_var = \
  85. __ATTR(_name, 0444, __rapl_##_var##_show, NULL)
  86. #define RAPL_EVENT_DESC(_name, _config) \
  87. { \
  88. .attr = __ATTR(_name, 0444, rapl_event_show, NULL), \
  89. .config = _config, \
  90. }
  91. #define RAPL_CNTR_WIDTH 32 /* 32-bit rapl counters */
  92. struct rapl_pmu {
  93. spinlock_t lock;
  94. int hw_unit; /* 1/2^hw_unit Joule */
  95. int n_active; /* number of active events */
  96. struct list_head active_list;
  97. struct pmu *pmu; /* pointer to rapl_pmu_class */
  98. ktime_t timer_interval; /* in ktime_t unit */
  99. struct hrtimer hrtimer;
  100. };
  101. static struct pmu rapl_pmu_class;
  102. static cpumask_t rapl_cpu_mask;
  103. static int rapl_cntr_mask;
  104. static DEFINE_PER_CPU(struct rapl_pmu *, rapl_pmu);
  105. static DEFINE_PER_CPU(struct rapl_pmu *, rapl_pmu_to_free);
  106. static inline u64 rapl_read_counter(struct perf_event *event)
  107. {
  108. u64 raw;
  109. rdmsrl(event->hw.event_base, raw);
  110. return raw;
  111. }
  112. static inline u64 rapl_scale(u64 v)
  113. {
  114. /*
  115. * scale delta to smallest unit (1/2^32)
  116. * users must then scale back: count * 1/(1e9*2^32) to get Joules
  117. * or use ldexp(count, -32).
  118. * Watts = Joules/Time delta
  119. */
  120. return v << (32 - __get_cpu_var(rapl_pmu)->hw_unit);
  121. }
  122. static u64 rapl_event_update(struct perf_event *event)
  123. {
  124. struct hw_perf_event *hwc = &event->hw;
  125. u64 prev_raw_count, new_raw_count;
  126. s64 delta, sdelta;
  127. int shift = RAPL_CNTR_WIDTH;
  128. again:
  129. prev_raw_count = local64_read(&hwc->prev_count);
  130. rdmsrl(event->hw.event_base, new_raw_count);
  131. if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
  132. new_raw_count) != prev_raw_count) {
  133. cpu_relax();
  134. goto again;
  135. }
  136. /*
  137. * Now we have the new raw value and have updated the prev
  138. * timestamp already. We can now calculate the elapsed delta
  139. * (event-)time and add that to the generic event.
  140. *
  141. * Careful, not all hw sign-extends above the physical width
  142. * of the count.
  143. */
  144. delta = (new_raw_count << shift) - (prev_raw_count << shift);
  145. delta >>= shift;
  146. sdelta = rapl_scale(delta);
  147. local64_add(sdelta, &event->count);
  148. return new_raw_count;
  149. }
  150. static void rapl_start_hrtimer(struct rapl_pmu *pmu)
  151. {
  152. __hrtimer_start_range_ns(&pmu->hrtimer,
  153. pmu->timer_interval, 0,
  154. HRTIMER_MODE_REL_PINNED, 0);
  155. }
  156. static void rapl_stop_hrtimer(struct rapl_pmu *pmu)
  157. {
  158. hrtimer_cancel(&pmu->hrtimer);
  159. }
  160. static enum hrtimer_restart rapl_hrtimer_handle(struct hrtimer *hrtimer)
  161. {
  162. struct rapl_pmu *pmu = __get_cpu_var(rapl_pmu);
  163. struct perf_event *event;
  164. unsigned long flags;
  165. if (!pmu->n_active)
  166. return HRTIMER_NORESTART;
  167. spin_lock_irqsave(&pmu->lock, flags);
  168. list_for_each_entry(event, &pmu->active_list, active_entry) {
  169. rapl_event_update(event);
  170. }
  171. spin_unlock_irqrestore(&pmu->lock, flags);
  172. hrtimer_forward_now(hrtimer, pmu->timer_interval);
  173. return HRTIMER_RESTART;
  174. }
  175. static void rapl_hrtimer_init(struct rapl_pmu *pmu)
  176. {
  177. struct hrtimer *hr = &pmu->hrtimer;
  178. hrtimer_init(hr, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
  179. hr->function = rapl_hrtimer_handle;
  180. }
  181. static void __rapl_pmu_event_start(struct rapl_pmu *pmu,
  182. struct perf_event *event)
  183. {
  184. if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
  185. return;
  186. event->hw.state = 0;
  187. list_add_tail(&event->active_entry, &pmu->active_list);
  188. local64_set(&event->hw.prev_count, rapl_read_counter(event));
  189. pmu->n_active++;
  190. if (pmu->n_active == 1)
  191. rapl_start_hrtimer(pmu);
  192. }
  193. static void rapl_pmu_event_start(struct perf_event *event, int mode)
  194. {
  195. struct rapl_pmu *pmu = __get_cpu_var(rapl_pmu);
  196. unsigned long flags;
  197. spin_lock_irqsave(&pmu->lock, flags);
  198. __rapl_pmu_event_start(pmu, event);
  199. spin_unlock_irqrestore(&pmu->lock, flags);
  200. }
  201. static void rapl_pmu_event_stop(struct perf_event *event, int mode)
  202. {
  203. struct rapl_pmu *pmu = __get_cpu_var(rapl_pmu);
  204. struct hw_perf_event *hwc = &event->hw;
  205. unsigned long flags;
  206. spin_lock_irqsave(&pmu->lock, flags);
  207. /* mark event as deactivated and stopped */
  208. if (!(hwc->state & PERF_HES_STOPPED)) {
  209. WARN_ON_ONCE(pmu->n_active <= 0);
  210. pmu->n_active--;
  211. if (pmu->n_active == 0)
  212. rapl_stop_hrtimer(pmu);
  213. list_del(&event->active_entry);
  214. WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
  215. hwc->state |= PERF_HES_STOPPED;
  216. }
  217. /* check if update of sw counter is necessary */
  218. if ((mode & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
  219. /*
  220. * Drain the remaining delta count out of a event
  221. * that we are disabling:
  222. */
  223. rapl_event_update(event);
  224. hwc->state |= PERF_HES_UPTODATE;
  225. }
  226. spin_unlock_irqrestore(&pmu->lock, flags);
  227. }
  228. static int rapl_pmu_event_add(struct perf_event *event, int mode)
  229. {
  230. struct rapl_pmu *pmu = __get_cpu_var(rapl_pmu);
  231. struct hw_perf_event *hwc = &event->hw;
  232. unsigned long flags;
  233. spin_lock_irqsave(&pmu->lock, flags);
  234. hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
  235. if (mode & PERF_EF_START)
  236. __rapl_pmu_event_start(pmu, event);
  237. spin_unlock_irqrestore(&pmu->lock, flags);
  238. return 0;
  239. }
  240. static void rapl_pmu_event_del(struct perf_event *event, int flags)
  241. {
  242. rapl_pmu_event_stop(event, PERF_EF_UPDATE);
  243. }
  244. static int rapl_pmu_event_init(struct perf_event *event)
  245. {
  246. u64 cfg = event->attr.config & RAPL_EVENT_MASK;
  247. int bit, msr, ret = 0;
  248. /* only look at RAPL events */
  249. if (event->attr.type != rapl_pmu_class.type)
  250. return -ENOENT;
  251. /* check only supported bits are set */
  252. if (event->attr.config & ~RAPL_EVENT_MASK)
  253. return -EINVAL;
  254. /*
  255. * check event is known (determines counter)
  256. */
  257. switch (cfg) {
  258. case INTEL_RAPL_PP0:
  259. bit = RAPL_IDX_PP0_NRG_STAT;
  260. msr = MSR_PP0_ENERGY_STATUS;
  261. break;
  262. case INTEL_RAPL_PKG:
  263. bit = RAPL_IDX_PKG_NRG_STAT;
  264. msr = MSR_PKG_ENERGY_STATUS;
  265. break;
  266. case INTEL_RAPL_RAM:
  267. bit = RAPL_IDX_RAM_NRG_STAT;
  268. msr = MSR_DRAM_ENERGY_STATUS;
  269. break;
  270. case INTEL_RAPL_PP1:
  271. bit = RAPL_IDX_PP1_NRG_STAT;
  272. msr = MSR_PP1_ENERGY_STATUS;
  273. break;
  274. default:
  275. return -EINVAL;
  276. }
  277. /* check event supported */
  278. if (!(rapl_cntr_mask & (1 << bit)))
  279. return -EINVAL;
  280. /* unsupported modes and filters */
  281. if (event->attr.exclude_user ||
  282. event->attr.exclude_kernel ||
  283. event->attr.exclude_hv ||
  284. event->attr.exclude_idle ||
  285. event->attr.exclude_host ||
  286. event->attr.exclude_guest ||
  287. event->attr.sample_period) /* no sampling */
  288. return -EINVAL;
  289. /* must be done before validate_group */
  290. event->hw.event_base = msr;
  291. event->hw.config = cfg;
  292. event->hw.idx = bit;
  293. return ret;
  294. }
  295. static void rapl_pmu_event_read(struct perf_event *event)
  296. {
  297. rapl_event_update(event);
  298. }
  299. static ssize_t rapl_get_attr_cpumask(struct device *dev,
  300. struct device_attribute *attr, char *buf)
  301. {
  302. int n = cpulist_scnprintf(buf, PAGE_SIZE - 2, &rapl_cpu_mask);
  303. buf[n++] = '\n';
  304. buf[n] = '\0';
  305. return n;
  306. }
  307. static DEVICE_ATTR(cpumask, S_IRUGO, rapl_get_attr_cpumask, NULL);
  308. static struct attribute *rapl_pmu_attrs[] = {
  309. &dev_attr_cpumask.attr,
  310. NULL,
  311. };
  312. static struct attribute_group rapl_pmu_attr_group = {
  313. .attrs = rapl_pmu_attrs,
  314. };
  315. EVENT_ATTR_STR(energy-cores, rapl_cores, "event=0x01");
  316. EVENT_ATTR_STR(energy-pkg , rapl_pkg, "event=0x02");
  317. EVENT_ATTR_STR(energy-ram , rapl_ram, "event=0x03");
  318. EVENT_ATTR_STR(energy-gpu , rapl_gpu, "event=0x04");
  319. EVENT_ATTR_STR(energy-cores.unit, rapl_cores_unit, "Joules");
  320. EVENT_ATTR_STR(energy-pkg.unit , rapl_pkg_unit, "Joules");
  321. EVENT_ATTR_STR(energy-ram.unit , rapl_ram_unit, "Joules");
  322. EVENT_ATTR_STR(energy-gpu.unit , rapl_gpu_unit, "Joules");
  323. /*
  324. * we compute in 0.23 nJ increments regardless of MSR
  325. */
  326. EVENT_ATTR_STR(energy-cores.scale, rapl_cores_scale, "2.3283064365386962890625e-10");
  327. EVENT_ATTR_STR(energy-pkg.scale, rapl_pkg_scale, "2.3283064365386962890625e-10");
  328. EVENT_ATTR_STR(energy-ram.scale, rapl_ram_scale, "2.3283064365386962890625e-10");
  329. EVENT_ATTR_STR(energy-gpu.scale, rapl_gpu_scale, "2.3283064365386962890625e-10");
  330. static struct attribute *rapl_events_srv_attr[] = {
  331. EVENT_PTR(rapl_cores),
  332. EVENT_PTR(rapl_pkg),
  333. EVENT_PTR(rapl_ram),
  334. EVENT_PTR(rapl_cores_unit),
  335. EVENT_PTR(rapl_pkg_unit),
  336. EVENT_PTR(rapl_ram_unit),
  337. EVENT_PTR(rapl_cores_scale),
  338. EVENT_PTR(rapl_pkg_scale),
  339. EVENT_PTR(rapl_ram_scale),
  340. NULL,
  341. };
  342. static struct attribute *rapl_events_cln_attr[] = {
  343. EVENT_PTR(rapl_cores),
  344. EVENT_PTR(rapl_pkg),
  345. EVENT_PTR(rapl_gpu),
  346. EVENT_PTR(rapl_cores_unit),
  347. EVENT_PTR(rapl_pkg_unit),
  348. EVENT_PTR(rapl_gpu_unit),
  349. EVENT_PTR(rapl_cores_scale),
  350. EVENT_PTR(rapl_pkg_scale),
  351. EVENT_PTR(rapl_gpu_scale),
  352. NULL,
  353. };
  354. static struct attribute_group rapl_pmu_events_group = {
  355. .name = "events",
  356. .attrs = NULL, /* patched at runtime */
  357. };
  358. DEFINE_RAPL_FORMAT_ATTR(event, event, "config:0-7");
  359. static struct attribute *rapl_formats_attr[] = {
  360. &format_attr_event.attr,
  361. NULL,
  362. };
  363. static struct attribute_group rapl_pmu_format_group = {
  364. .name = "format",
  365. .attrs = rapl_formats_attr,
  366. };
  367. const struct attribute_group *rapl_attr_groups[] = {
  368. &rapl_pmu_attr_group,
  369. &rapl_pmu_format_group,
  370. &rapl_pmu_events_group,
  371. NULL,
  372. };
  373. static struct pmu rapl_pmu_class = {
  374. .attr_groups = rapl_attr_groups,
  375. .task_ctx_nr = perf_invalid_context, /* system-wide only */
  376. .event_init = rapl_pmu_event_init,
  377. .add = rapl_pmu_event_add, /* must have */
  378. .del = rapl_pmu_event_del, /* must have */
  379. .start = rapl_pmu_event_start,
  380. .stop = rapl_pmu_event_stop,
  381. .read = rapl_pmu_event_read,
  382. };
  383. static void rapl_cpu_exit(int cpu)
  384. {
  385. struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu);
  386. int i, phys_id = topology_physical_package_id(cpu);
  387. int target = -1;
  388. /* find a new cpu on same package */
  389. for_each_online_cpu(i) {
  390. if (i == cpu)
  391. continue;
  392. if (phys_id == topology_physical_package_id(i)) {
  393. target = i;
  394. break;
  395. }
  396. }
  397. /*
  398. * clear cpu from cpumask
  399. * if was set in cpumask and still some cpu on package,
  400. * then move to new cpu
  401. */
  402. if (cpumask_test_and_clear_cpu(cpu, &rapl_cpu_mask) && target >= 0)
  403. cpumask_set_cpu(target, &rapl_cpu_mask);
  404. WARN_ON(cpumask_empty(&rapl_cpu_mask));
  405. /*
  406. * migrate events and context to new cpu
  407. */
  408. if (target >= 0)
  409. perf_pmu_migrate_context(pmu->pmu, cpu, target);
  410. /* cancel overflow polling timer for CPU */
  411. rapl_stop_hrtimer(pmu);
  412. }
  413. static void rapl_cpu_init(int cpu)
  414. {
  415. int i, phys_id = topology_physical_package_id(cpu);
  416. /* check if phys_is is already covered */
  417. for_each_cpu(i, &rapl_cpu_mask) {
  418. if (phys_id == topology_physical_package_id(i))
  419. return;
  420. }
  421. /* was not found, so add it */
  422. cpumask_set_cpu(cpu, &rapl_cpu_mask);
  423. }
  424. static int rapl_cpu_prepare(int cpu)
  425. {
  426. struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu);
  427. int phys_id = topology_physical_package_id(cpu);
  428. u64 ms;
  429. if (pmu)
  430. return 0;
  431. if (phys_id < 0)
  432. return -1;
  433. pmu = kzalloc_node(sizeof(*pmu), GFP_KERNEL, cpu_to_node(cpu));
  434. if (!pmu)
  435. return -1;
  436. spin_lock_init(&pmu->lock);
  437. INIT_LIST_HEAD(&pmu->active_list);
  438. /*
  439. * grab power unit as: 1/2^unit Joules
  440. *
  441. * we cache in local PMU instance
  442. */
  443. rdmsrl(MSR_RAPL_POWER_UNIT, pmu->hw_unit);
  444. pmu->hw_unit = (pmu->hw_unit >> 8) & 0x1FULL;
  445. pmu->pmu = &rapl_pmu_class;
  446. /*
  447. * use reference of 200W for scaling the timeout
  448. * to avoid missing counter overflows.
  449. * 200W = 200 Joules/sec
  450. * divide interval by 2 to avoid lockstep (2 * 100)
  451. * if hw unit is 32, then we use 2 ms 1/200/2
  452. */
  453. if (pmu->hw_unit < 32)
  454. ms = (1000 / (2 * 100)) * (1ULL << (32 - pmu->hw_unit - 1));
  455. else
  456. ms = 2;
  457. pmu->timer_interval = ms_to_ktime(ms);
  458. rapl_hrtimer_init(pmu);
  459. /* set RAPL pmu for this cpu for now */
  460. per_cpu(rapl_pmu, cpu) = pmu;
  461. per_cpu(rapl_pmu_to_free, cpu) = NULL;
  462. return 0;
  463. }
  464. static void rapl_cpu_kfree(int cpu)
  465. {
  466. struct rapl_pmu *pmu = per_cpu(rapl_pmu_to_free, cpu);
  467. kfree(pmu);
  468. per_cpu(rapl_pmu_to_free, cpu) = NULL;
  469. }
  470. static int rapl_cpu_dying(int cpu)
  471. {
  472. struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu);
  473. if (!pmu)
  474. return 0;
  475. per_cpu(rapl_pmu, cpu) = NULL;
  476. per_cpu(rapl_pmu_to_free, cpu) = pmu;
  477. return 0;
  478. }
  479. static int rapl_cpu_notifier(struct notifier_block *self,
  480. unsigned long action, void *hcpu)
  481. {
  482. unsigned int cpu = (long)hcpu;
  483. switch (action & ~CPU_TASKS_FROZEN) {
  484. case CPU_UP_PREPARE:
  485. rapl_cpu_prepare(cpu);
  486. break;
  487. case CPU_STARTING:
  488. rapl_cpu_init(cpu);
  489. break;
  490. case CPU_UP_CANCELED:
  491. case CPU_DYING:
  492. rapl_cpu_dying(cpu);
  493. break;
  494. case CPU_ONLINE:
  495. case CPU_DEAD:
  496. rapl_cpu_kfree(cpu);
  497. break;
  498. case CPU_DOWN_PREPARE:
  499. rapl_cpu_exit(cpu);
  500. break;
  501. default:
  502. break;
  503. }
  504. return NOTIFY_OK;
  505. }
  506. static const struct x86_cpu_id rapl_cpu_match[] = {
  507. [0] = { .vendor = X86_VENDOR_INTEL, .family = 6 },
  508. [1] = {},
  509. };
  510. static int __init rapl_pmu_init(void)
  511. {
  512. struct rapl_pmu *pmu;
  513. int cpu, ret;
  514. /*
  515. * check for Intel processor family 6
  516. */
  517. if (!x86_match_cpu(rapl_cpu_match))
  518. return 0;
  519. /* check supported CPU */
  520. switch (boot_cpu_data.x86_model) {
  521. case 42: /* Sandy Bridge */
  522. case 58: /* Ivy Bridge */
  523. case 60: /* Haswell */
  524. case 69: /* Haswell-Celeron */
  525. rapl_cntr_mask = RAPL_IDX_CLN;
  526. rapl_pmu_events_group.attrs = rapl_events_cln_attr;
  527. break;
  528. case 45: /* Sandy Bridge-EP */
  529. case 62: /* IvyTown */
  530. rapl_cntr_mask = RAPL_IDX_SRV;
  531. rapl_pmu_events_group.attrs = rapl_events_srv_attr;
  532. break;
  533. default:
  534. /* unsupported */
  535. return 0;
  536. }
  537. get_online_cpus();
  538. for_each_online_cpu(cpu) {
  539. rapl_cpu_prepare(cpu);
  540. rapl_cpu_init(cpu);
  541. }
  542. perf_cpu_notifier(rapl_cpu_notifier);
  543. ret = perf_pmu_register(&rapl_pmu_class, "power", -1);
  544. if (WARN_ON(ret)) {
  545. pr_info("RAPL PMU detected, registration failed (%d), RAPL PMU disabled\n", ret);
  546. put_online_cpus();
  547. return -1;
  548. }
  549. pmu = __get_cpu_var(rapl_pmu);
  550. pr_info("RAPL PMU detected, hw unit 2^-%d Joules,"
  551. " API unit is 2^-32 Joules,"
  552. " %d fixed counters"
  553. " %llu ms ovfl timer\n",
  554. pmu->hw_unit,
  555. hweight32(rapl_cntr_mask),
  556. ktime_to_ms(pmu->timer_interval));
  557. put_online_cpus();
  558. return 0;
  559. }
  560. device_initcall(rapl_pmu_init);