perf_cpum_cf.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  1. /*
  2. * Performance event support for s390x - CPU-measurement Counter Facility
  3. *
  4. * Copyright IBM Corp. 2012, 2017
  5. * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License (version 2 only)
  9. * as published by the Free Software Foundation.
  10. */
  11. #define KMSG_COMPONENT "cpum_cf"
  12. #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
  13. #include <linux/kernel.h>
  14. #include <linux/kernel_stat.h>
  15. #include <linux/perf_event.h>
  16. #include <linux/percpu.h>
  17. #include <linux/notifier.h>
  18. #include <linux/init.h>
  19. #include <linux/export.h>
  20. #include <asm/ctl_reg.h>
  21. #include <asm/irq.h>
  22. #include <asm/cpu_mf.h>
  23. enum cpumf_ctr_set {
  24. CPUMF_CTR_SET_BASIC = 0, /* Basic Counter Set */
  25. CPUMF_CTR_SET_USER = 1, /* Problem-State Counter Set */
  26. CPUMF_CTR_SET_CRYPTO = 2, /* Crypto-Activity Counter Set */
  27. CPUMF_CTR_SET_EXT = 3, /* Extended Counter Set */
  28. CPUMF_CTR_SET_MT_DIAG = 4, /* MT-diagnostic Counter Set */
  29. /* Maximum number of counter sets */
  30. CPUMF_CTR_SET_MAX,
  31. };
  32. #define CPUMF_LCCTL_ENABLE_SHIFT 16
  33. #define CPUMF_LCCTL_ACTCTL_SHIFT 0
  34. static const u64 cpumf_state_ctl[CPUMF_CTR_SET_MAX] = {
  35. [CPUMF_CTR_SET_BASIC] = 0x02,
  36. [CPUMF_CTR_SET_USER] = 0x04,
  37. [CPUMF_CTR_SET_CRYPTO] = 0x08,
  38. [CPUMF_CTR_SET_EXT] = 0x01,
  39. [CPUMF_CTR_SET_MT_DIAG] = 0x20,
  40. };
  41. static void ctr_set_enable(u64 *state, int ctr_set)
  42. {
  43. *state |= cpumf_state_ctl[ctr_set] << CPUMF_LCCTL_ENABLE_SHIFT;
  44. }
  45. static void ctr_set_disable(u64 *state, int ctr_set)
  46. {
  47. *state &= ~(cpumf_state_ctl[ctr_set] << CPUMF_LCCTL_ENABLE_SHIFT);
  48. }
  49. static void ctr_set_start(u64 *state, int ctr_set)
  50. {
  51. *state |= cpumf_state_ctl[ctr_set] << CPUMF_LCCTL_ACTCTL_SHIFT;
  52. }
  53. static void ctr_set_stop(u64 *state, int ctr_set)
  54. {
  55. *state &= ~(cpumf_state_ctl[ctr_set] << CPUMF_LCCTL_ACTCTL_SHIFT);
  56. }
  57. /* Local CPUMF event structure */
  58. struct cpu_hw_events {
  59. struct cpumf_ctr_info info;
  60. atomic_t ctr_set[CPUMF_CTR_SET_MAX];
  61. u64 state, tx_state;
  62. unsigned int flags;
  63. unsigned int txn_flags;
  64. };
  65. static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
  66. .ctr_set = {
  67. [CPUMF_CTR_SET_BASIC] = ATOMIC_INIT(0),
  68. [CPUMF_CTR_SET_USER] = ATOMIC_INIT(0),
  69. [CPUMF_CTR_SET_CRYPTO] = ATOMIC_INIT(0),
  70. [CPUMF_CTR_SET_EXT] = ATOMIC_INIT(0),
  71. [CPUMF_CTR_SET_MT_DIAG] = ATOMIC_INIT(0),
  72. },
  73. .state = 0,
  74. .flags = 0,
  75. .txn_flags = 0,
  76. };
  77. static enum cpumf_ctr_set get_counter_set(u64 event)
  78. {
  79. int set = CPUMF_CTR_SET_MAX;
  80. if (event < 32)
  81. set = CPUMF_CTR_SET_BASIC;
  82. else if (event < 64)
  83. set = CPUMF_CTR_SET_USER;
  84. else if (event < 128)
  85. set = CPUMF_CTR_SET_CRYPTO;
  86. else if (event < 256)
  87. set = CPUMF_CTR_SET_EXT;
  88. else if (event >= 448 && event < 496)
  89. set = CPUMF_CTR_SET_MT_DIAG;
  90. return set;
  91. }
  92. static int validate_ctr_version(const struct hw_perf_event *hwc)
  93. {
  94. struct cpu_hw_events *cpuhw;
  95. int err = 0;
  96. u16 mtdiag_ctl;
  97. cpuhw = &get_cpu_var(cpu_hw_events);
  98. /* check required version for counter sets */
  99. switch (hwc->config_base) {
  100. case CPUMF_CTR_SET_BASIC:
  101. case CPUMF_CTR_SET_USER:
  102. if (cpuhw->info.cfvn < 1)
  103. err = -EOPNOTSUPP;
  104. break;
  105. case CPUMF_CTR_SET_CRYPTO:
  106. case CPUMF_CTR_SET_EXT:
  107. if (cpuhw->info.csvn < 1)
  108. err = -EOPNOTSUPP;
  109. if ((cpuhw->info.csvn == 1 && hwc->config > 159) ||
  110. (cpuhw->info.csvn == 2 && hwc->config > 175) ||
  111. (cpuhw->info.csvn > 2 && hwc->config > 255))
  112. err = -EOPNOTSUPP;
  113. break;
  114. case CPUMF_CTR_SET_MT_DIAG:
  115. if (cpuhw->info.csvn <= 3)
  116. err = -EOPNOTSUPP;
  117. /*
  118. * MT-diagnostic counters are read-only. The counter set
  119. * is automatically enabled and activated on all CPUs with
  120. * multithreading (SMT). Deactivation of multithreading
  121. * also disables the counter set. State changes are ignored
  122. * by lcctl(). Because Linux controls SMT enablement through
  123. * a kernel parameter only, the counter set is either disabled
  124. * or enabled and active.
  125. *
  126. * Thus, the counters can only be used if SMT is on and the
  127. * counter set is enabled and active.
  128. */
  129. mtdiag_ctl = cpumf_state_ctl[CPUMF_CTR_SET_MT_DIAG];
  130. if (!((cpuhw->info.auth_ctl & mtdiag_ctl) &&
  131. (cpuhw->info.enable_ctl & mtdiag_ctl) &&
  132. (cpuhw->info.act_ctl & mtdiag_ctl)))
  133. err = -EOPNOTSUPP;
  134. break;
  135. }
  136. put_cpu_var(cpu_hw_events);
  137. return err;
  138. }
  139. static int validate_ctr_auth(const struct hw_perf_event *hwc)
  140. {
  141. struct cpu_hw_events *cpuhw;
  142. u64 ctrs_state;
  143. int err = 0;
  144. cpuhw = &get_cpu_var(cpu_hw_events);
  145. /* Check authorization for cpu counter sets.
  146. * If the particular CPU counter set is not authorized,
  147. * return with -ENOENT in order to fall back to other
  148. * PMUs that might suffice the event request.
  149. */
  150. ctrs_state = cpumf_state_ctl[hwc->config_base];
  151. if (!(ctrs_state & cpuhw->info.auth_ctl))
  152. err = -ENOENT;
  153. put_cpu_var(cpu_hw_events);
  154. return err;
  155. }
  156. /*
  157. * Change the CPUMF state to active.
  158. * Enable and activate the CPU-counter sets according
  159. * to the per-cpu control state.
  160. */
  161. static void cpumf_pmu_enable(struct pmu *pmu)
  162. {
  163. struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
  164. int err;
  165. if (cpuhw->flags & PMU_F_ENABLED)
  166. return;
  167. err = lcctl(cpuhw->state);
  168. if (err) {
  169. pr_err("Enabling the performance measuring unit "
  170. "failed with rc=%x\n", err);
  171. return;
  172. }
  173. cpuhw->flags |= PMU_F_ENABLED;
  174. }
  175. /*
  176. * Change the CPUMF state to inactive.
  177. * Disable and enable (inactive) the CPU-counter sets according
  178. * to the per-cpu control state.
  179. */
  180. static void cpumf_pmu_disable(struct pmu *pmu)
  181. {
  182. struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
  183. int err;
  184. u64 inactive;
  185. if (!(cpuhw->flags & PMU_F_ENABLED))
  186. return;
  187. inactive = cpuhw->state & ~((1 << CPUMF_LCCTL_ENABLE_SHIFT) - 1);
  188. err = lcctl(inactive);
  189. if (err) {
  190. pr_err("Disabling the performance measuring unit "
  191. "failed with rc=%x\n", err);
  192. return;
  193. }
  194. cpuhw->flags &= ~PMU_F_ENABLED;
  195. }
  196. /* Number of perf events counting hardware events */
  197. static atomic_t num_events = ATOMIC_INIT(0);
  198. /* Used to avoid races in calling reserve/release_cpumf_hardware */
  199. static DEFINE_MUTEX(pmc_reserve_mutex);
  200. /* CPU-measurement alerts for the counter facility */
  201. static void cpumf_measurement_alert(struct ext_code ext_code,
  202. unsigned int alert, unsigned long unused)
  203. {
  204. struct cpu_hw_events *cpuhw;
  205. if (!(alert & CPU_MF_INT_CF_MASK))
  206. return;
  207. inc_irq_stat(IRQEXT_CMC);
  208. cpuhw = this_cpu_ptr(&cpu_hw_events);
  209. /* Measurement alerts are shared and might happen when the PMU
  210. * is not reserved. Ignore these alerts in this case. */
  211. if (!(cpuhw->flags & PMU_F_RESERVED))
  212. return;
  213. /* counter authorization change alert */
  214. if (alert & CPU_MF_INT_CF_CACA)
  215. qctri(&cpuhw->info);
  216. /* loss of counter data alert */
  217. if (alert & CPU_MF_INT_CF_LCDA)
  218. pr_err("CPU[%i] Counter data was lost\n", smp_processor_id());
  219. /* loss of MT counter data alert */
  220. if (alert & CPU_MF_INT_CF_MTDA)
  221. pr_warn("CPU[%i] MT counter data was lost\n",
  222. smp_processor_id());
  223. }
  224. #define PMC_INIT 0
  225. #define PMC_RELEASE 1
  226. static void setup_pmc_cpu(void *flags)
  227. {
  228. struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
  229. switch (*((int *) flags)) {
  230. case PMC_INIT:
  231. memset(&cpuhw->info, 0, sizeof(cpuhw->info));
  232. qctri(&cpuhw->info);
  233. cpuhw->flags |= PMU_F_RESERVED;
  234. break;
  235. case PMC_RELEASE:
  236. cpuhw->flags &= ~PMU_F_RESERVED;
  237. break;
  238. }
  239. /* Disable CPU counter sets */
  240. lcctl(0);
  241. }
  242. /* Initialize the CPU-measurement facility */
  243. static int reserve_pmc_hardware(void)
  244. {
  245. int flags = PMC_INIT;
  246. on_each_cpu(setup_pmc_cpu, &flags, 1);
  247. irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT);
  248. return 0;
  249. }
  250. /* Release the CPU-measurement facility */
  251. static void release_pmc_hardware(void)
  252. {
  253. int flags = PMC_RELEASE;
  254. on_each_cpu(setup_pmc_cpu, &flags, 1);
  255. irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT);
  256. }
  257. /* Release the PMU if event is the last perf event */
  258. static void hw_perf_event_destroy(struct perf_event *event)
  259. {
  260. if (!atomic_add_unless(&num_events, -1, 1)) {
  261. mutex_lock(&pmc_reserve_mutex);
  262. if (atomic_dec_return(&num_events) == 0)
  263. release_pmc_hardware();
  264. mutex_unlock(&pmc_reserve_mutex);
  265. }
  266. }
  267. /* CPUMF <-> perf event mappings for kernel+userspace (basic set) */
  268. static const int cpumf_generic_events_basic[] = {
  269. [PERF_COUNT_HW_CPU_CYCLES] = 0,
  270. [PERF_COUNT_HW_INSTRUCTIONS] = 1,
  271. [PERF_COUNT_HW_CACHE_REFERENCES] = -1,
  272. [PERF_COUNT_HW_CACHE_MISSES] = -1,
  273. [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = -1,
  274. [PERF_COUNT_HW_BRANCH_MISSES] = -1,
  275. [PERF_COUNT_HW_BUS_CYCLES] = -1,
  276. };
  277. /* CPUMF <-> perf event mappings for userspace (problem-state set) */
  278. static const int cpumf_generic_events_user[] = {
  279. [PERF_COUNT_HW_CPU_CYCLES] = 32,
  280. [PERF_COUNT_HW_INSTRUCTIONS] = 33,
  281. [PERF_COUNT_HW_CACHE_REFERENCES] = -1,
  282. [PERF_COUNT_HW_CACHE_MISSES] = -1,
  283. [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = -1,
  284. [PERF_COUNT_HW_BRANCH_MISSES] = -1,
  285. [PERF_COUNT_HW_BUS_CYCLES] = -1,
  286. };
  287. static int __hw_perf_event_init(struct perf_event *event)
  288. {
  289. struct perf_event_attr *attr = &event->attr;
  290. struct hw_perf_event *hwc = &event->hw;
  291. enum cpumf_ctr_set set;
  292. int err;
  293. u64 ev;
  294. switch (attr->type) {
  295. case PERF_TYPE_RAW:
  296. /* Raw events are used to access counters directly,
  297. * hence do not permit excludes */
  298. if (attr->exclude_kernel || attr->exclude_user ||
  299. attr->exclude_hv)
  300. return -EOPNOTSUPP;
  301. ev = attr->config;
  302. break;
  303. case PERF_TYPE_HARDWARE:
  304. ev = attr->config;
  305. /* Count user space (problem-state) only */
  306. if (!attr->exclude_user && attr->exclude_kernel) {
  307. if (ev >= ARRAY_SIZE(cpumf_generic_events_user))
  308. return -EOPNOTSUPP;
  309. ev = cpumf_generic_events_user[ev];
  310. /* No support for kernel space counters only */
  311. } else if (!attr->exclude_kernel && attr->exclude_user) {
  312. return -EOPNOTSUPP;
  313. /* Count user and kernel space */
  314. } else {
  315. if (ev >= ARRAY_SIZE(cpumf_generic_events_basic))
  316. return -EOPNOTSUPP;
  317. ev = cpumf_generic_events_basic[ev];
  318. }
  319. break;
  320. default:
  321. return -ENOENT;
  322. }
  323. if (ev == -1)
  324. return -ENOENT;
  325. if (ev > PERF_CPUM_CF_MAX_CTR)
  326. return -EINVAL;
  327. /* Obtain the counter set to which the specified counter belongs */
  328. set = get_counter_set(ev);
  329. switch (set) {
  330. case CPUMF_CTR_SET_BASIC:
  331. case CPUMF_CTR_SET_USER:
  332. case CPUMF_CTR_SET_CRYPTO:
  333. case CPUMF_CTR_SET_EXT:
  334. case CPUMF_CTR_SET_MT_DIAG:
  335. /*
  336. * Use the hardware perf event structure to store the
  337. * counter number in the 'config' member and the counter
  338. * set number in the 'config_base'. The counter set number
  339. * is then later used to enable/disable the counter(s).
  340. */
  341. hwc->config = ev;
  342. hwc->config_base = set;
  343. break;
  344. case CPUMF_CTR_SET_MAX:
  345. /* The counter could not be associated to a counter set */
  346. return -EINVAL;
  347. };
  348. /* Initialize for using the CPU-measurement counter facility */
  349. if (!atomic_inc_not_zero(&num_events)) {
  350. mutex_lock(&pmc_reserve_mutex);
  351. if (atomic_read(&num_events) == 0 && reserve_pmc_hardware())
  352. err = -EBUSY;
  353. else
  354. atomic_inc(&num_events);
  355. mutex_unlock(&pmc_reserve_mutex);
  356. }
  357. event->destroy = hw_perf_event_destroy;
  358. /* Finally, validate version and authorization of the counter set */
  359. err = validate_ctr_auth(hwc);
  360. if (!err)
  361. err = validate_ctr_version(hwc);
  362. return err;
  363. }
  364. static int cpumf_pmu_event_init(struct perf_event *event)
  365. {
  366. int err;
  367. switch (event->attr.type) {
  368. case PERF_TYPE_HARDWARE:
  369. case PERF_TYPE_HW_CACHE:
  370. case PERF_TYPE_RAW:
  371. err = __hw_perf_event_init(event);
  372. break;
  373. default:
  374. return -ENOENT;
  375. }
  376. if (unlikely(err) && event->destroy)
  377. event->destroy(event);
  378. return err;
  379. }
  380. static int hw_perf_event_reset(struct perf_event *event)
  381. {
  382. u64 prev, new;
  383. int err;
  384. do {
  385. prev = local64_read(&event->hw.prev_count);
  386. err = ecctr(event->hw.config, &new);
  387. if (err) {
  388. if (err != 3)
  389. break;
  390. /* The counter is not (yet) available. This
  391. * might happen if the counter set to which
  392. * this counter belongs is in the disabled
  393. * state.
  394. */
  395. new = 0;
  396. }
  397. } while (local64_cmpxchg(&event->hw.prev_count, prev, new) != prev);
  398. return err;
  399. }
  400. static void hw_perf_event_update(struct perf_event *event)
  401. {
  402. u64 prev, new, delta;
  403. int err;
  404. do {
  405. prev = local64_read(&event->hw.prev_count);
  406. err = ecctr(event->hw.config, &new);
  407. if (err)
  408. return;
  409. } while (local64_cmpxchg(&event->hw.prev_count, prev, new) != prev);
  410. delta = (prev <= new) ? new - prev
  411. : (-1ULL - prev) + new + 1; /* overflow */
  412. local64_add(delta, &event->count);
  413. }
  414. static void cpumf_pmu_read(struct perf_event *event)
  415. {
  416. if (event->hw.state & PERF_HES_STOPPED)
  417. return;
  418. hw_perf_event_update(event);
  419. }
  420. static void cpumf_pmu_start(struct perf_event *event, int flags)
  421. {
  422. struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
  423. struct hw_perf_event *hwc = &event->hw;
  424. if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
  425. return;
  426. if (WARN_ON_ONCE(hwc->config == -1))
  427. return;
  428. if (flags & PERF_EF_RELOAD)
  429. WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
  430. hwc->state = 0;
  431. /* (Re-)enable and activate the counter set */
  432. ctr_set_enable(&cpuhw->state, hwc->config_base);
  433. ctr_set_start(&cpuhw->state, hwc->config_base);
  434. /* The counter set to which this counter belongs can be already active.
  435. * Because all counters in a set are active, the event->hw.prev_count
  436. * needs to be synchronized. At this point, the counter set can be in
  437. * the inactive or disabled state.
  438. */
  439. hw_perf_event_reset(event);
  440. /* increment refcount for this counter set */
  441. atomic_inc(&cpuhw->ctr_set[hwc->config_base]);
  442. }
  443. static void cpumf_pmu_stop(struct perf_event *event, int flags)
  444. {
  445. struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
  446. struct hw_perf_event *hwc = &event->hw;
  447. if (!(hwc->state & PERF_HES_STOPPED)) {
  448. /* Decrement reference count for this counter set and if this
  449. * is the last used counter in the set, clear activation
  450. * control and set the counter set state to inactive.
  451. */
  452. if (!atomic_dec_return(&cpuhw->ctr_set[hwc->config_base]))
  453. ctr_set_stop(&cpuhw->state, hwc->config_base);
  454. event->hw.state |= PERF_HES_STOPPED;
  455. }
  456. if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
  457. hw_perf_event_update(event);
  458. event->hw.state |= PERF_HES_UPTODATE;
  459. }
  460. }
  461. static int cpumf_pmu_add(struct perf_event *event, int flags)
  462. {
  463. struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
  464. /* Check authorization for the counter set to which this
  465. * counter belongs.
  466. * For group events transaction, the authorization check is
  467. * done in cpumf_pmu_commit_txn().
  468. */
  469. if (!(cpuhw->txn_flags & PERF_PMU_TXN_ADD))
  470. if (validate_ctr_auth(&event->hw))
  471. return -ENOENT;
  472. ctr_set_enable(&cpuhw->state, event->hw.config_base);
  473. event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
  474. if (flags & PERF_EF_START)
  475. cpumf_pmu_start(event, PERF_EF_RELOAD);
  476. perf_event_update_userpage(event);
  477. return 0;
  478. }
  479. static void cpumf_pmu_del(struct perf_event *event, int flags)
  480. {
  481. struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
  482. cpumf_pmu_stop(event, PERF_EF_UPDATE);
  483. /* Check if any counter in the counter set is still used. If not used,
  484. * change the counter set to the disabled state. This also clears the
  485. * content of all counters in the set.
  486. *
  487. * When a new perf event has been added but not yet started, this can
  488. * clear enable control and resets all counters in a set. Therefore,
  489. * cpumf_pmu_start() always has to reenable a counter set.
  490. */
  491. if (!atomic_read(&cpuhw->ctr_set[event->hw.config_base]))
  492. ctr_set_disable(&cpuhw->state, event->hw.config_base);
  493. perf_event_update_userpage(event);
  494. }
  495. /*
  496. * Start group events scheduling transaction.
  497. * Set flags to perform a single test at commit time.
  498. *
  499. * We only support PERF_PMU_TXN_ADD transactions. Save the
  500. * transaction flags but otherwise ignore non-PERF_PMU_TXN_ADD
  501. * transactions.
  502. */
  503. static void cpumf_pmu_start_txn(struct pmu *pmu, unsigned int txn_flags)
  504. {
  505. struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
  506. WARN_ON_ONCE(cpuhw->txn_flags); /* txn already in flight */
  507. cpuhw->txn_flags = txn_flags;
  508. if (txn_flags & ~PERF_PMU_TXN_ADD)
  509. return;
  510. perf_pmu_disable(pmu);
  511. cpuhw->tx_state = cpuhw->state;
  512. }
  513. /*
  514. * Stop and cancel a group events scheduling tranctions.
  515. * Assumes cpumf_pmu_del() is called for each successful added
  516. * cpumf_pmu_add() during the transaction.
  517. */
  518. static void cpumf_pmu_cancel_txn(struct pmu *pmu)
  519. {
  520. unsigned int txn_flags;
  521. struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
  522. WARN_ON_ONCE(!cpuhw->txn_flags); /* no txn in flight */
  523. txn_flags = cpuhw->txn_flags;
  524. cpuhw->txn_flags = 0;
  525. if (txn_flags & ~PERF_PMU_TXN_ADD)
  526. return;
  527. WARN_ON(cpuhw->tx_state != cpuhw->state);
  528. perf_pmu_enable(pmu);
  529. }
  530. /*
  531. * Commit the group events scheduling transaction. On success, the
  532. * transaction is closed. On error, the transaction is kept open
  533. * until cpumf_pmu_cancel_txn() is called.
  534. */
  535. static int cpumf_pmu_commit_txn(struct pmu *pmu)
  536. {
  537. struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
  538. u64 state;
  539. WARN_ON_ONCE(!cpuhw->txn_flags); /* no txn in flight */
  540. if (cpuhw->txn_flags & ~PERF_PMU_TXN_ADD) {
  541. cpuhw->txn_flags = 0;
  542. return 0;
  543. }
  544. /* check if the updated state can be scheduled */
  545. state = cpuhw->state & ~((1 << CPUMF_LCCTL_ENABLE_SHIFT) - 1);
  546. state >>= CPUMF_LCCTL_ENABLE_SHIFT;
  547. if ((state & cpuhw->info.auth_ctl) != state)
  548. return -ENOENT;
  549. cpuhw->txn_flags = 0;
  550. perf_pmu_enable(pmu);
  551. return 0;
  552. }
  553. /* Performance monitoring unit for s390x */
  554. static struct pmu cpumf_pmu = {
  555. .task_ctx_nr = perf_sw_context,
  556. .capabilities = PERF_PMU_CAP_NO_INTERRUPT,
  557. .pmu_enable = cpumf_pmu_enable,
  558. .pmu_disable = cpumf_pmu_disable,
  559. .event_init = cpumf_pmu_event_init,
  560. .add = cpumf_pmu_add,
  561. .del = cpumf_pmu_del,
  562. .start = cpumf_pmu_start,
  563. .stop = cpumf_pmu_stop,
  564. .read = cpumf_pmu_read,
  565. .start_txn = cpumf_pmu_start_txn,
  566. .commit_txn = cpumf_pmu_commit_txn,
  567. .cancel_txn = cpumf_pmu_cancel_txn,
  568. };
  569. static int cpumf_pmf_setup(unsigned int cpu, int flags)
  570. {
  571. local_irq_disable();
  572. setup_pmc_cpu(&flags);
  573. local_irq_enable();
  574. return 0;
  575. }
  576. static int s390_pmu_online_cpu(unsigned int cpu)
  577. {
  578. return cpumf_pmf_setup(cpu, PMC_INIT);
  579. }
  580. static int s390_pmu_offline_cpu(unsigned int cpu)
  581. {
  582. return cpumf_pmf_setup(cpu, PMC_RELEASE);
  583. }
  584. static int __init cpumf_pmu_init(void)
  585. {
  586. int rc;
  587. if (!cpum_cf_avail())
  588. return -ENODEV;
  589. /* clear bit 15 of cr0 to unauthorize problem-state to
  590. * extract measurement counters */
  591. ctl_clear_bit(0, 48);
  592. /* register handler for measurement-alert interruptions */
  593. rc = register_external_irq(EXT_IRQ_MEASURE_ALERT,
  594. cpumf_measurement_alert);
  595. if (rc) {
  596. pr_err("Registering for CPU-measurement alerts "
  597. "failed with rc=%i\n", rc);
  598. return rc;
  599. }
  600. cpumf_pmu.attr_groups = cpumf_cf_event_group();
  601. rc = perf_pmu_register(&cpumf_pmu, "cpum_cf", PERF_TYPE_RAW);
  602. if (rc) {
  603. pr_err("Registering the cpum_cf PMU failed with rc=%i\n", rc);
  604. unregister_external_irq(EXT_IRQ_MEASURE_ALERT,
  605. cpumf_measurement_alert);
  606. return rc;
  607. }
  608. return cpuhp_setup_state(CPUHP_AP_PERF_S390_CF_ONLINE,
  609. "perf/s390/cf:online",
  610. s390_pmu_online_cpu, s390_pmu_offline_cpu);
  611. }
  612. early_initcall(cpumf_pmu_init);