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