perf_event.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
  4. * Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
  5. * Copyright (C) 2009 Jaswinder Singh Rajput
  6. * Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
  7. * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra
  8. * Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
  9. * Copyright (C) 2009 Google, Inc., Stephane Eranian
  10. * Copyright 2014 Tilera Corporation. All Rights Reserved.
  11. * Copyright (C) 2018 Andes Technology Corporation
  12. *
  13. * Perf_events support for RISC-V platforms.
  14. *
  15. * Since the spec. (as of now, Priv-Spec 1.10) does not provide enough
  16. * functionality for perf event to fully work, this file provides
  17. * the very basic framework only.
  18. *
  19. * For platform portings, please check Documentations/riscv/pmu.txt.
  20. *
  21. * The Copyright line includes x86 and tile ones.
  22. */
  23. #include <linux/kprobes.h>
  24. #include <linux/kernel.h>
  25. #include <linux/kdebug.h>
  26. #include <linux/mutex.h>
  27. #include <linux/bitmap.h>
  28. #include <linux/irq.h>
  29. #include <linux/interrupt.h>
  30. #include <linux/perf_event.h>
  31. #include <linux/atomic.h>
  32. #include <linux/of.h>
  33. #include <asm/perf_event.h>
  34. static const struct riscv_pmu *riscv_pmu __read_mostly;
  35. static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
  36. /*
  37. * Hardware & cache maps and their methods
  38. */
  39. static const int riscv_hw_event_map[] = {
  40. [PERF_COUNT_HW_CPU_CYCLES] = RISCV_PMU_CYCLE,
  41. [PERF_COUNT_HW_INSTRUCTIONS] = RISCV_PMU_INSTRET,
  42. [PERF_COUNT_HW_CACHE_REFERENCES] = RISCV_OP_UNSUPP,
  43. [PERF_COUNT_HW_CACHE_MISSES] = RISCV_OP_UNSUPP,
  44. [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = RISCV_OP_UNSUPP,
  45. [PERF_COUNT_HW_BRANCH_MISSES] = RISCV_OP_UNSUPP,
  46. [PERF_COUNT_HW_BUS_CYCLES] = RISCV_OP_UNSUPP,
  47. };
  48. #define C(x) PERF_COUNT_HW_CACHE_##x
  49. static const int riscv_cache_event_map[PERF_COUNT_HW_CACHE_MAX]
  50. [PERF_COUNT_HW_CACHE_OP_MAX]
  51. [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
  52. [C(L1D)] = {
  53. [C(OP_READ)] = {
  54. [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP,
  55. [C(RESULT_MISS)] = RISCV_OP_UNSUPP,
  56. },
  57. [C(OP_WRITE)] = {
  58. [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP,
  59. [C(RESULT_MISS)] = RISCV_OP_UNSUPP,
  60. },
  61. [C(OP_PREFETCH)] = {
  62. [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP,
  63. [C(RESULT_MISS)] = RISCV_OP_UNSUPP,
  64. },
  65. },
  66. [C(L1I)] = {
  67. [C(OP_READ)] = {
  68. [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP,
  69. [C(RESULT_MISS)] = RISCV_OP_UNSUPP,
  70. },
  71. [C(OP_WRITE)] = {
  72. [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP,
  73. [C(RESULT_MISS)] = RISCV_OP_UNSUPP,
  74. },
  75. [C(OP_PREFETCH)] = {
  76. [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP,
  77. [C(RESULT_MISS)] = RISCV_OP_UNSUPP,
  78. },
  79. },
  80. [C(LL)] = {
  81. [C(OP_READ)] = {
  82. [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP,
  83. [C(RESULT_MISS)] = RISCV_OP_UNSUPP,
  84. },
  85. [C(OP_WRITE)] = {
  86. [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP,
  87. [C(RESULT_MISS)] = RISCV_OP_UNSUPP,
  88. },
  89. [C(OP_PREFETCH)] = {
  90. [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP,
  91. [C(RESULT_MISS)] = RISCV_OP_UNSUPP,
  92. },
  93. },
  94. [C(DTLB)] = {
  95. [C(OP_READ)] = {
  96. [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP,
  97. [C(RESULT_MISS)] = RISCV_OP_UNSUPP,
  98. },
  99. [C(OP_WRITE)] = {
  100. [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP,
  101. [C(RESULT_MISS)] = RISCV_OP_UNSUPP,
  102. },
  103. [C(OP_PREFETCH)] = {
  104. [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP,
  105. [C(RESULT_MISS)] = RISCV_OP_UNSUPP,
  106. },
  107. },
  108. [C(ITLB)] = {
  109. [C(OP_READ)] = {
  110. [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP,
  111. [C(RESULT_MISS)] = RISCV_OP_UNSUPP,
  112. },
  113. [C(OP_WRITE)] = {
  114. [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP,
  115. [C(RESULT_MISS)] = RISCV_OP_UNSUPP,
  116. },
  117. [C(OP_PREFETCH)] = {
  118. [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP,
  119. [C(RESULT_MISS)] = RISCV_OP_UNSUPP,
  120. },
  121. },
  122. [C(BPU)] = {
  123. [C(OP_READ)] = {
  124. [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP,
  125. [C(RESULT_MISS)] = RISCV_OP_UNSUPP,
  126. },
  127. [C(OP_WRITE)] = {
  128. [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP,
  129. [C(RESULT_MISS)] = RISCV_OP_UNSUPP,
  130. },
  131. [C(OP_PREFETCH)] = {
  132. [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP,
  133. [C(RESULT_MISS)] = RISCV_OP_UNSUPP,
  134. },
  135. },
  136. };
  137. static int riscv_map_hw_event(u64 config)
  138. {
  139. if (config >= riscv_pmu->max_events)
  140. return -EINVAL;
  141. return riscv_pmu->hw_events[config];
  142. }
  143. int riscv_map_cache_decode(u64 config, unsigned int *type,
  144. unsigned int *op, unsigned int *result)
  145. {
  146. return -ENOENT;
  147. }
  148. static int riscv_map_cache_event(u64 config)
  149. {
  150. unsigned int type, op, result;
  151. int err = -ENOENT;
  152. int code;
  153. err = riscv_map_cache_decode(config, &type, &op, &result);
  154. if (!riscv_pmu->cache_events || err)
  155. return err;
  156. if (type >= PERF_COUNT_HW_CACHE_MAX ||
  157. op >= PERF_COUNT_HW_CACHE_OP_MAX ||
  158. result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
  159. return -EINVAL;
  160. code = (*riscv_pmu->cache_events)[type][op][result];
  161. if (code == RISCV_OP_UNSUPP)
  162. return -EINVAL;
  163. return code;
  164. }
  165. /*
  166. * Low-level functions: reading/writing counters
  167. */
  168. static inline u64 read_counter(int idx)
  169. {
  170. u64 val = 0;
  171. switch (idx) {
  172. case RISCV_PMU_CYCLE:
  173. val = csr_read(cycle);
  174. break;
  175. case RISCV_PMU_INSTRET:
  176. val = csr_read(instret);
  177. break;
  178. default:
  179. WARN_ON_ONCE(idx < 0 || idx > RISCV_MAX_COUNTERS);
  180. return -EINVAL;
  181. }
  182. return val;
  183. }
  184. static inline void write_counter(int idx, u64 value)
  185. {
  186. /* currently not supported */
  187. WARN_ON_ONCE(1);
  188. }
  189. /*
  190. * pmu->read: read and update the counter
  191. *
  192. * Other architectures' implementation often have a xxx_perf_event_update
  193. * routine, which can return counter values when called in the IRQ, but
  194. * return void when being called by the pmu->read method.
  195. */
  196. static void riscv_pmu_read(struct perf_event *event)
  197. {
  198. struct hw_perf_event *hwc = &event->hw;
  199. u64 prev_raw_count, new_raw_count;
  200. u64 oldval;
  201. int idx = hwc->idx;
  202. u64 delta;
  203. do {
  204. prev_raw_count = local64_read(&hwc->prev_count);
  205. new_raw_count = read_counter(idx);
  206. oldval = local64_cmpxchg(&hwc->prev_count, prev_raw_count,
  207. new_raw_count);
  208. } while (oldval != prev_raw_count);
  209. /*
  210. * delta is the value to update the counter we maintain in the kernel.
  211. */
  212. delta = (new_raw_count - prev_raw_count) &
  213. ((1ULL << riscv_pmu->counter_width) - 1);
  214. local64_add(delta, &event->count);
  215. /*
  216. * Something like local64_sub(delta, &hwc->period_left) here is
  217. * needed if there is an interrupt for perf.
  218. */
  219. }
  220. /*
  221. * State transition functions:
  222. *
  223. * stop()/start() & add()/del()
  224. */
  225. /*
  226. * pmu->stop: stop the counter
  227. */
  228. static void riscv_pmu_stop(struct perf_event *event, int flags)
  229. {
  230. struct hw_perf_event *hwc = &event->hw;
  231. WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
  232. hwc->state |= PERF_HES_STOPPED;
  233. if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
  234. riscv_pmu->pmu->read(event);
  235. hwc->state |= PERF_HES_UPTODATE;
  236. }
  237. }
  238. /*
  239. * pmu->start: start the event.
  240. */
  241. static void riscv_pmu_start(struct perf_event *event, int flags)
  242. {
  243. struct hw_perf_event *hwc = &event->hw;
  244. if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
  245. return;
  246. if (flags & PERF_EF_RELOAD) {
  247. WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE));
  248. /*
  249. * Set the counter to the period to the next interrupt here,
  250. * if you have any.
  251. */
  252. }
  253. hwc->state = 0;
  254. perf_event_update_userpage(event);
  255. /*
  256. * Since we cannot write to counters, this serves as an initialization
  257. * to the delta-mechanism in pmu->read(); otherwise, the delta would be
  258. * wrong when pmu->read is called for the first time.
  259. */
  260. local64_set(&hwc->prev_count, read_counter(hwc->idx));
  261. }
  262. /*
  263. * pmu->add: add the event to PMU.
  264. */
  265. static int riscv_pmu_add(struct perf_event *event, int flags)
  266. {
  267. struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
  268. struct hw_perf_event *hwc = &event->hw;
  269. if (cpuc->n_events == riscv_pmu->num_counters)
  270. return -ENOSPC;
  271. /*
  272. * We don't have general conunters, so no binding-event-to-counter
  273. * process here.
  274. *
  275. * Indexing using hwc->config generally not works, since config may
  276. * contain extra information, but here the only info we have in
  277. * hwc->config is the event index.
  278. */
  279. hwc->idx = hwc->config;
  280. cpuc->events[hwc->idx] = event;
  281. cpuc->n_events++;
  282. hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
  283. if (flags & PERF_EF_START)
  284. riscv_pmu->pmu->start(event, PERF_EF_RELOAD);
  285. return 0;
  286. }
  287. /*
  288. * pmu->del: delete the event from PMU.
  289. */
  290. static void riscv_pmu_del(struct perf_event *event, int flags)
  291. {
  292. struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
  293. struct hw_perf_event *hwc = &event->hw;
  294. cpuc->events[hwc->idx] = NULL;
  295. cpuc->n_events--;
  296. riscv_pmu->pmu->stop(event, PERF_EF_UPDATE);
  297. perf_event_update_userpage(event);
  298. }
  299. /*
  300. * Interrupt: a skeletion for reference.
  301. */
  302. static DEFINE_MUTEX(pmc_reserve_mutex);
  303. irqreturn_t riscv_base_pmu_handle_irq(int irq_num, void *dev)
  304. {
  305. return IRQ_NONE;
  306. }
  307. static int reserve_pmc_hardware(void)
  308. {
  309. int err = 0;
  310. mutex_lock(&pmc_reserve_mutex);
  311. if (riscv_pmu->irq >= 0 && riscv_pmu->handle_irq) {
  312. err = request_irq(riscv_pmu->irq, riscv_pmu->handle_irq,
  313. IRQF_PERCPU, "riscv-base-perf", NULL);
  314. }
  315. mutex_unlock(&pmc_reserve_mutex);
  316. return err;
  317. }
  318. void release_pmc_hardware(void)
  319. {
  320. mutex_lock(&pmc_reserve_mutex);
  321. if (riscv_pmu->irq >= 0)
  322. free_irq(riscv_pmu->irq, NULL);
  323. mutex_unlock(&pmc_reserve_mutex);
  324. }
  325. /*
  326. * Event Initialization/Finalization
  327. */
  328. static atomic_t riscv_active_events = ATOMIC_INIT(0);
  329. static void riscv_event_destroy(struct perf_event *event)
  330. {
  331. if (atomic_dec_return(&riscv_active_events) == 0)
  332. release_pmc_hardware();
  333. }
  334. static int riscv_event_init(struct perf_event *event)
  335. {
  336. struct perf_event_attr *attr = &event->attr;
  337. struct hw_perf_event *hwc = &event->hw;
  338. int err;
  339. int code;
  340. if (atomic_inc_return(&riscv_active_events) == 1) {
  341. err = reserve_pmc_hardware();
  342. if (err) {
  343. pr_warn("PMC hardware not available\n");
  344. atomic_dec(&riscv_active_events);
  345. return -EBUSY;
  346. }
  347. }
  348. switch (event->attr.type) {
  349. case PERF_TYPE_HARDWARE:
  350. code = riscv_pmu->map_hw_event(attr->config);
  351. break;
  352. case PERF_TYPE_HW_CACHE:
  353. code = riscv_pmu->map_cache_event(attr->config);
  354. break;
  355. case PERF_TYPE_RAW:
  356. return -EOPNOTSUPP;
  357. default:
  358. return -ENOENT;
  359. }
  360. event->destroy = riscv_event_destroy;
  361. if (code < 0) {
  362. event->destroy(event);
  363. return code;
  364. }
  365. /*
  366. * idx is set to -1 because the index of a general event should not be
  367. * decided until binding to some counter in pmu->add().
  368. *
  369. * But since we don't have such support, later in pmu->add(), we just
  370. * use hwc->config as the index instead.
  371. */
  372. hwc->config = code;
  373. hwc->idx = -1;
  374. return 0;
  375. }
  376. /*
  377. * Initialization
  378. */
  379. static struct pmu min_pmu = {
  380. .name = "riscv-base",
  381. .event_init = riscv_event_init,
  382. .add = riscv_pmu_add,
  383. .del = riscv_pmu_del,
  384. .start = riscv_pmu_start,
  385. .stop = riscv_pmu_stop,
  386. .read = riscv_pmu_read,
  387. };
  388. static const struct riscv_pmu riscv_base_pmu = {
  389. .pmu = &min_pmu,
  390. .max_events = ARRAY_SIZE(riscv_hw_event_map),
  391. .map_hw_event = riscv_map_hw_event,
  392. .hw_events = riscv_hw_event_map,
  393. .map_cache_event = riscv_map_cache_event,
  394. .cache_events = &riscv_cache_event_map,
  395. .counter_width = 63,
  396. .num_counters = RISCV_BASE_COUNTERS + 0,
  397. .handle_irq = &riscv_base_pmu_handle_irq,
  398. /* This means this PMU has no IRQ. */
  399. .irq = -1,
  400. };
  401. static const struct of_device_id riscv_pmu_of_ids[] = {
  402. {.compatible = "riscv,base-pmu", .data = &riscv_base_pmu},
  403. { /* sentinel value */ }
  404. };
  405. int __init init_hw_perf_events(void)
  406. {
  407. struct device_node *node = of_find_node_by_type(NULL, "pmu");
  408. const struct of_device_id *of_id;
  409. riscv_pmu = &riscv_base_pmu;
  410. if (node) {
  411. of_id = of_match_node(riscv_pmu_of_ids, node);
  412. if (of_id)
  413. riscv_pmu = of_id->data;
  414. }
  415. perf_pmu_register(riscv_pmu->pmu, "cpu", PERF_TYPE_RAW);
  416. return 0;
  417. }
  418. arch_initcall(init_hw_perf_events);