cxl_pmu.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright(c) 2023 Huawei
  4. *
  5. * The CXL 3.0 specification includes a standard Performance Monitoring Unit,
  6. * called the CXL PMU, or CPMU. In order to allow a high degree of
  7. * implementation flexibility the specification provides a wide range of
  8. * options all of which are self describing.
  9. *
  10. * Details in CXL rev 3.0 section 8.2.7 CPMU Register Interface
  11. */
  12. #include <linux/io-64-nonatomic-lo-hi.h>
  13. #include <linux/perf_event.h>
  14. #include <linux/bitops.h>
  15. #include <linux/device.h>
  16. #include <linux/bits.h>
  17. #include <linux/list.h>
  18. #include <linux/bug.h>
  19. #include <linux/pci.h>
  20. #include "../cxl/cxlpci.h"
  21. #include "../cxl/cxl.h"
  22. #include "../cxl/pmu.h"
  23. #define CXL_PMU_CAP_REG 0x0
  24. #define CXL_PMU_CAP_NUM_COUNTERS_MSK GENMASK_ULL(5, 0)
  25. #define CXL_PMU_CAP_COUNTER_WIDTH_MSK GENMASK_ULL(15, 8)
  26. #define CXL_PMU_CAP_NUM_EVN_CAP_REG_SUP_MSK GENMASK_ULL(24, 20)
  27. #define CXL_PMU_CAP_FILTERS_SUP_MSK GENMASK_ULL(39, 32)
  28. #define CXL_PMU_FILTER_HDM BIT(0)
  29. #define CXL_PMU_FILTER_CHAN_RANK_BANK BIT(1)
  30. #define CXL_PMU_CAP_MSI_N_MSK GENMASK_ULL(47, 44)
  31. #define CXL_PMU_CAP_WRITEABLE_WHEN_FROZEN BIT_ULL(48)
  32. #define CXL_PMU_CAP_FREEZE BIT_ULL(49)
  33. #define CXL_PMU_CAP_INT BIT_ULL(50)
  34. #define CXL_PMU_CAP_VERSION_MSK GENMASK_ULL(63, 60)
  35. #define CXL_PMU_OVERFLOW_REG 0x10
  36. #define CXL_PMU_FREEZE_REG 0x18
  37. #define CXL_PMU_EVENT_CAP_REG(n) (0x100 + 8 * (n))
  38. #define CXL_PMU_EVENT_CAP_SUPPORTED_EVENTS_MSK GENMASK_ULL(31, 0)
  39. #define CXL_PMU_EVENT_CAP_GROUP_ID_MSK GENMASK_ULL(47, 32)
  40. #define CXL_PMU_EVENT_CAP_VENDOR_ID_MSK GENMASK_ULL(63, 48)
  41. #define CXL_PMU_COUNTER_CFG_REG(n) (0x200 + 8 * (n))
  42. #define CXL_PMU_COUNTER_CFG_TYPE_MSK GENMASK_ULL(1, 0)
  43. #define CXL_PMU_COUNTER_CFG_TYPE_FREE_RUN 0
  44. #define CXL_PMU_COUNTER_CFG_TYPE_FIXED_FUN 1
  45. #define CXL_PMU_COUNTER_CFG_TYPE_CONFIGURABLE 2
  46. #define CXL_PMU_COUNTER_CFG_ENABLE BIT_ULL(8)
  47. #define CXL_PMU_COUNTER_CFG_INT_ON_OVRFLW BIT_ULL(9)
  48. #define CXL_PMU_COUNTER_CFG_FREEZE_ON_OVRFLW BIT_ULL(10)
  49. #define CXL_PMU_COUNTER_CFG_EDGE BIT_ULL(11)
  50. #define CXL_PMU_COUNTER_CFG_INVERT BIT_ULL(12)
  51. #define CXL_PMU_COUNTER_CFG_THRESHOLD_MSK GENMASK_ULL(23, 16)
  52. #define CXL_PMU_COUNTER_CFG_EVENTS_MSK GENMASK_ULL(55, 24)
  53. #define CXL_PMU_COUNTER_CFG_EVENT_GRP_ID_IDX_MSK GENMASK_ULL(63, 59)
  54. #define CXL_PMU_FILTER_CFG_REG(n, f) (0x400 + 4 * ((f) + (n) * 8))
  55. #define CXL_PMU_FILTER_CFG_VALUE_MSK GENMASK(31, 0)
  56. #define CXL_PMU_COUNTER_REG(n) (0xc00 + 8 * (n))
  57. /* CXL rev 3.0 Table 13-5 Events under CXL Vendor ID */
  58. #define CXL_PMU_GID_CLOCK_TICKS 0x00
  59. #define CXL_PMU_GID_D2H_REQ 0x0010
  60. #define CXL_PMU_GID_D2H_RSP 0x0011
  61. #define CXL_PMU_GID_H2D_REQ 0x0012
  62. #define CXL_PMU_GID_H2D_RSP 0x0013
  63. #define CXL_PMU_GID_CACHE_DATA 0x0014
  64. #define CXL_PMU_GID_M2S_REQ 0x0020
  65. #define CXL_PMU_GID_M2S_RWD 0x0021
  66. #define CXL_PMU_GID_M2S_BIRSP 0x0022
  67. #define CXL_PMU_GID_S2M_BISNP 0x0023
  68. #define CXL_PMU_GID_S2M_NDR 0x0024
  69. #define CXL_PMU_GID_S2M_DRS 0x0025
  70. #define CXL_PMU_GID_DDR 0x8000
  71. static int cxl_pmu_cpuhp_state_num;
  72. struct cxl_pmu_ev_cap {
  73. u16 vid;
  74. u16 gid;
  75. u32 msk;
  76. union {
  77. int counter_idx; /* fixed counters */
  78. int event_idx; /* configurable counters */
  79. };
  80. struct list_head node;
  81. };
  82. #define CXL_PMU_MAX_COUNTERS 64
  83. struct cxl_pmu_info {
  84. struct pmu pmu;
  85. void __iomem *base;
  86. struct perf_event **hw_events;
  87. struct list_head event_caps_configurable;
  88. struct list_head event_caps_fixed;
  89. DECLARE_BITMAP(used_counter_bm, CXL_PMU_MAX_COUNTERS);
  90. DECLARE_BITMAP(conf_counter_bm, CXL_PMU_MAX_COUNTERS);
  91. u16 counter_width;
  92. u8 num_counters;
  93. u8 num_event_capabilities;
  94. int on_cpu;
  95. struct hlist_node node;
  96. bool filter_hdm;
  97. int irq;
  98. };
  99. #define pmu_to_cxl_pmu_info(_pmu) container_of(_pmu, struct cxl_pmu_info, pmu)
  100. /*
  101. * All CPMU counters are discoverable via the Event Capabilities Registers.
  102. * Each Event Capability register contains a a VID / GroupID.
  103. * A counter may then count any combination (by summing) of events in
  104. * that group which are in the Supported Events Bitmask.
  105. * However, there are some complexities to the scheme.
  106. * - Fixed function counters refer to an Event Capabilities register.
  107. * That event capability register is not then used for Configurable
  108. * counters.
  109. */
  110. static int cxl_pmu_parse_caps(struct device *dev, struct cxl_pmu_info *info)
  111. {
  112. unsigned long fixed_counter_event_cap_bm = 0;
  113. void __iomem *base = info->base;
  114. bool freeze_for_enable;
  115. u64 val, eval;
  116. int i;
  117. val = readq(base + CXL_PMU_CAP_REG);
  118. freeze_for_enable = FIELD_GET(CXL_PMU_CAP_WRITEABLE_WHEN_FROZEN, val) &&
  119. FIELD_GET(CXL_PMU_CAP_FREEZE, val);
  120. if (!freeze_for_enable) {
  121. dev_err(dev, "Counters not writable while frozen\n");
  122. return -ENODEV;
  123. }
  124. info->num_counters = FIELD_GET(CXL_PMU_CAP_NUM_COUNTERS_MSK, val) + 1;
  125. info->counter_width = FIELD_GET(CXL_PMU_CAP_COUNTER_WIDTH_MSK, val);
  126. info->num_event_capabilities = FIELD_GET(CXL_PMU_CAP_NUM_EVN_CAP_REG_SUP_MSK, val) + 1;
  127. info->filter_hdm = FIELD_GET(CXL_PMU_CAP_FILTERS_SUP_MSK, val) & CXL_PMU_FILTER_HDM;
  128. if (FIELD_GET(CXL_PMU_CAP_INT, val))
  129. info->irq = FIELD_GET(CXL_PMU_CAP_MSI_N_MSK, val);
  130. else
  131. info->irq = -1;
  132. /* First handle fixed function counters; note if configurable counters found */
  133. for (i = 0; i < info->num_counters; i++) {
  134. struct cxl_pmu_ev_cap *pmu_ev;
  135. u32 events_msk;
  136. u8 group_idx;
  137. val = readq(base + CXL_PMU_COUNTER_CFG_REG(i));
  138. if (FIELD_GET(CXL_PMU_COUNTER_CFG_TYPE_MSK, val) ==
  139. CXL_PMU_COUNTER_CFG_TYPE_CONFIGURABLE) {
  140. set_bit(i, info->conf_counter_bm);
  141. }
  142. if (FIELD_GET(CXL_PMU_COUNTER_CFG_TYPE_MSK, val) !=
  143. CXL_PMU_COUNTER_CFG_TYPE_FIXED_FUN)
  144. continue;
  145. /* In this case we know which fields are const */
  146. group_idx = FIELD_GET(CXL_PMU_COUNTER_CFG_EVENT_GRP_ID_IDX_MSK, val);
  147. events_msk = FIELD_GET(CXL_PMU_COUNTER_CFG_EVENTS_MSK, val);
  148. eval = readq(base + CXL_PMU_EVENT_CAP_REG(group_idx));
  149. pmu_ev = devm_kzalloc(dev, sizeof(*pmu_ev), GFP_KERNEL);
  150. if (!pmu_ev)
  151. return -ENOMEM;
  152. pmu_ev->vid = FIELD_GET(CXL_PMU_EVENT_CAP_VENDOR_ID_MSK, eval);
  153. pmu_ev->gid = FIELD_GET(CXL_PMU_EVENT_CAP_GROUP_ID_MSK, eval);
  154. /* For a fixed purpose counter use the events mask from the counter CFG */
  155. pmu_ev->msk = events_msk;
  156. pmu_ev->counter_idx = i;
  157. /* This list add is never unwound as all entries deleted on remove */
  158. list_add(&pmu_ev->node, &info->event_caps_fixed);
  159. /*
  160. * Configurable counters must not use an Event Capability registers that
  161. * is in use for a Fixed counter
  162. */
  163. set_bit(group_idx, &fixed_counter_event_cap_bm);
  164. }
  165. if (!bitmap_empty(info->conf_counter_bm, CXL_PMU_MAX_COUNTERS)) {
  166. struct cxl_pmu_ev_cap *pmu_ev;
  167. int j;
  168. /* Walk event capabilities unused by fixed counters */
  169. for_each_clear_bit(j, &fixed_counter_event_cap_bm,
  170. info->num_event_capabilities) {
  171. pmu_ev = devm_kzalloc(dev, sizeof(*pmu_ev), GFP_KERNEL);
  172. if (!pmu_ev)
  173. return -ENOMEM;
  174. eval = readq(base + CXL_PMU_EVENT_CAP_REG(j));
  175. pmu_ev->vid = FIELD_GET(CXL_PMU_EVENT_CAP_VENDOR_ID_MSK, eval);
  176. pmu_ev->gid = FIELD_GET(CXL_PMU_EVENT_CAP_GROUP_ID_MSK, eval);
  177. pmu_ev->msk = FIELD_GET(CXL_PMU_EVENT_CAP_SUPPORTED_EVENTS_MSK, eval);
  178. pmu_ev->event_idx = j;
  179. list_add(&pmu_ev->node, &info->event_caps_configurable);
  180. }
  181. }
  182. return 0;
  183. }
  184. #define CXL_PMU_FORMAT_ATTR(_name, _format)\
  185. (&((struct dev_ext_attribute[]) { \
  186. { \
  187. .attr = __ATTR(_name, 0444, device_show_string, NULL), \
  188. .var = (void *)_format \
  189. } \
  190. })[0].attr.attr)
  191. enum {
  192. cxl_pmu_mask_attr,
  193. cxl_pmu_gid_attr,
  194. cxl_pmu_vid_attr,
  195. cxl_pmu_threshold_attr,
  196. cxl_pmu_invert_attr,
  197. cxl_pmu_edge_attr,
  198. cxl_pmu_hdm_filter_en_attr,
  199. cxl_pmu_hdm_attr,
  200. };
  201. static struct attribute *cxl_pmu_format_attr[] = {
  202. [cxl_pmu_mask_attr] = CXL_PMU_FORMAT_ATTR(mask, "config:0-31"),
  203. [cxl_pmu_gid_attr] = CXL_PMU_FORMAT_ATTR(gid, "config:32-47"),
  204. [cxl_pmu_vid_attr] = CXL_PMU_FORMAT_ATTR(vid, "config:48-63"),
  205. [cxl_pmu_threshold_attr] = CXL_PMU_FORMAT_ATTR(threshold, "config1:0-15"),
  206. [cxl_pmu_invert_attr] = CXL_PMU_FORMAT_ATTR(invert, "config1:16"),
  207. [cxl_pmu_edge_attr] = CXL_PMU_FORMAT_ATTR(edge, "config1:17"),
  208. [cxl_pmu_hdm_filter_en_attr] = CXL_PMU_FORMAT_ATTR(hdm_filter_en, "config1:18"),
  209. [cxl_pmu_hdm_attr] = CXL_PMU_FORMAT_ATTR(hdm, "config2:0-15"),
  210. NULL
  211. };
  212. #define CXL_PMU_ATTR_CONFIG_MASK_MSK GENMASK_ULL(31, 0)
  213. #define CXL_PMU_ATTR_CONFIG_GID_MSK GENMASK_ULL(47, 32)
  214. #define CXL_PMU_ATTR_CONFIG_VID_MSK GENMASK_ULL(63, 48)
  215. #define CXL_PMU_ATTR_CONFIG1_THRESHOLD_MSK GENMASK_ULL(15, 0)
  216. #define CXL_PMU_ATTR_CONFIG1_INVERT_MSK BIT(16)
  217. #define CXL_PMU_ATTR_CONFIG1_EDGE_MSK BIT(17)
  218. #define CXL_PMU_ATTR_CONFIG1_FILTER_EN_MSK BIT(18)
  219. #define CXL_PMU_ATTR_CONFIG2_HDM_MSK GENMASK(15, 0)
  220. static umode_t cxl_pmu_format_is_visible(struct kobject *kobj,
  221. struct attribute *attr, int a)
  222. {
  223. struct device *dev = kobj_to_dev(kobj);
  224. struct cxl_pmu_info *info = dev_get_drvdata(dev);
  225. /*
  226. * Filter capability at the CPMU level, so hide the attributes if the particular
  227. * filter is not supported.
  228. */
  229. if (!info->filter_hdm &&
  230. (attr == cxl_pmu_format_attr[cxl_pmu_hdm_filter_en_attr] ||
  231. attr == cxl_pmu_format_attr[cxl_pmu_hdm_attr]))
  232. return 0;
  233. return attr->mode;
  234. }
  235. static const struct attribute_group cxl_pmu_format_group = {
  236. .name = "format",
  237. .attrs = cxl_pmu_format_attr,
  238. .is_visible = cxl_pmu_format_is_visible,
  239. };
  240. static u32 cxl_pmu_config_get_mask(struct perf_event *event)
  241. {
  242. return FIELD_GET(CXL_PMU_ATTR_CONFIG_MASK_MSK, event->attr.config);
  243. }
  244. static u16 cxl_pmu_config_get_gid(struct perf_event *event)
  245. {
  246. return FIELD_GET(CXL_PMU_ATTR_CONFIG_GID_MSK, event->attr.config);
  247. }
  248. static u16 cxl_pmu_config_get_vid(struct perf_event *event)
  249. {
  250. return FIELD_GET(CXL_PMU_ATTR_CONFIG_VID_MSK, event->attr.config);
  251. }
  252. static u8 cxl_pmu_config1_get_threshold(struct perf_event *event)
  253. {
  254. return FIELD_GET(CXL_PMU_ATTR_CONFIG1_THRESHOLD_MSK, event->attr.config1);
  255. }
  256. static bool cxl_pmu_config1_get_invert(struct perf_event *event)
  257. {
  258. return FIELD_GET(CXL_PMU_ATTR_CONFIG1_INVERT_MSK, event->attr.config1);
  259. }
  260. static bool cxl_pmu_config1_get_edge(struct perf_event *event)
  261. {
  262. return FIELD_GET(CXL_PMU_ATTR_CONFIG1_EDGE_MSK, event->attr.config1);
  263. }
  264. /*
  265. * CPMU specification allows for 8 filters, each with a 32 bit value...
  266. * So we need to find 8x32bits to store it in.
  267. * As the value used for disable is 0xffff_ffff, a separate enable switch
  268. * is needed.
  269. */
  270. static bool cxl_pmu_config1_hdm_filter_en(struct perf_event *event)
  271. {
  272. return FIELD_GET(CXL_PMU_ATTR_CONFIG1_FILTER_EN_MSK, event->attr.config1);
  273. }
  274. static u16 cxl_pmu_config2_get_hdm_decoder(struct perf_event *event)
  275. {
  276. return FIELD_GET(CXL_PMU_ATTR_CONFIG2_HDM_MSK, event->attr.config2);
  277. }
  278. static ssize_t cxl_pmu_event_sysfs_show(struct device *dev,
  279. struct device_attribute *attr, char *buf)
  280. {
  281. struct perf_pmu_events_attr *pmu_attr =
  282. container_of(attr, struct perf_pmu_events_attr, attr);
  283. return sysfs_emit(buf, "config=%#llx\n", pmu_attr->id);
  284. }
  285. #define CXL_PMU_EVENT_ATTR(_name, _vid, _gid, _msk) \
  286. PMU_EVENT_ATTR_ID(_name, cxl_pmu_event_sysfs_show, \
  287. ((u64)(_vid) << 48) | ((u64)(_gid) << 32) | (u64)(_msk))
  288. /* For CXL spec defined events */
  289. #define CXL_PMU_EVENT_CXL_ATTR(_name, _gid, _msk) \
  290. CXL_PMU_EVENT_ATTR(_name, PCI_VENDOR_ID_CXL, _gid, _msk)
  291. static struct attribute *cxl_pmu_event_attrs[] = {
  292. CXL_PMU_EVENT_CXL_ATTR(clock_ticks, CXL_PMU_GID_CLOCK_TICKS, BIT(0)),
  293. /* CXL rev 3.0 Table 3-17 - Device to Host Requests */
  294. CXL_PMU_EVENT_CXL_ATTR(d2h_req_rdcurr, CXL_PMU_GID_D2H_REQ, BIT(1)),
  295. CXL_PMU_EVENT_CXL_ATTR(d2h_req_rdown, CXL_PMU_GID_D2H_REQ, BIT(2)),
  296. CXL_PMU_EVENT_CXL_ATTR(d2h_req_rdshared, CXL_PMU_GID_D2H_REQ, BIT(3)),
  297. CXL_PMU_EVENT_CXL_ATTR(d2h_req_rdany, CXL_PMU_GID_D2H_REQ, BIT(4)),
  298. CXL_PMU_EVENT_CXL_ATTR(d2h_req_rdownnodata, CXL_PMU_GID_D2H_REQ, BIT(5)),
  299. CXL_PMU_EVENT_CXL_ATTR(d2h_req_itomwr, CXL_PMU_GID_D2H_REQ, BIT(6)),
  300. CXL_PMU_EVENT_CXL_ATTR(d2h_req_wrcurr, CXL_PMU_GID_D2H_REQ, BIT(7)),
  301. CXL_PMU_EVENT_CXL_ATTR(d2h_req_clflush, CXL_PMU_GID_D2H_REQ, BIT(8)),
  302. CXL_PMU_EVENT_CXL_ATTR(d2h_req_cleanevict, CXL_PMU_GID_D2H_REQ, BIT(9)),
  303. CXL_PMU_EVENT_CXL_ATTR(d2h_req_dirtyevict, CXL_PMU_GID_D2H_REQ, BIT(10)),
  304. CXL_PMU_EVENT_CXL_ATTR(d2h_req_cleanevictnodata, CXL_PMU_GID_D2H_REQ, BIT(11)),
  305. CXL_PMU_EVENT_CXL_ATTR(d2h_req_wowrinv, CXL_PMU_GID_D2H_REQ, BIT(12)),
  306. CXL_PMU_EVENT_CXL_ATTR(d2h_req_wowrinvf, CXL_PMU_GID_D2H_REQ, BIT(13)),
  307. CXL_PMU_EVENT_CXL_ATTR(d2h_req_wrinv, CXL_PMU_GID_D2H_REQ, BIT(14)),
  308. CXL_PMU_EVENT_CXL_ATTR(d2h_req_cacheflushed, CXL_PMU_GID_D2H_REQ, BIT(16)),
  309. /* CXL rev 3.0 Table 3-20 - D2H Repsonse Encodings */
  310. CXL_PMU_EVENT_CXL_ATTR(d2h_rsp_rspihiti, CXL_PMU_GID_D2H_RSP, BIT(4)),
  311. CXL_PMU_EVENT_CXL_ATTR(d2h_rsp_rspvhitv, CXL_PMU_GID_D2H_RSP, BIT(6)),
  312. CXL_PMU_EVENT_CXL_ATTR(d2h_rsp_rspihitse, CXL_PMU_GID_D2H_RSP, BIT(5)),
  313. CXL_PMU_EVENT_CXL_ATTR(d2h_rsp_rspshitse, CXL_PMU_GID_D2H_RSP, BIT(1)),
  314. CXL_PMU_EVENT_CXL_ATTR(d2h_rsp_rspsfwdm, CXL_PMU_GID_D2H_RSP, BIT(7)),
  315. CXL_PMU_EVENT_CXL_ATTR(d2h_rsp_rspifwdm, CXL_PMU_GID_D2H_RSP, BIT(15)),
  316. CXL_PMU_EVENT_CXL_ATTR(d2h_rsp_rspvfwdv, CXL_PMU_GID_D2H_RSP, BIT(22)),
  317. /* CXL rev 3.0 Table 3-21 - CXL.cache - Mapping of H2D Requests to D2H Responses */
  318. CXL_PMU_EVENT_CXL_ATTR(h2d_req_snpdata, CXL_PMU_GID_H2D_REQ, BIT(1)),
  319. CXL_PMU_EVENT_CXL_ATTR(h2d_req_snpinv, CXL_PMU_GID_H2D_REQ, BIT(2)),
  320. CXL_PMU_EVENT_CXL_ATTR(h2d_req_snpcur, CXL_PMU_GID_H2D_REQ, BIT(3)),
  321. /* CXL rev 3.0 Table 3-22 - H2D Response Opcode Encodings */
  322. CXL_PMU_EVENT_CXL_ATTR(h2d_rsp_writepull, CXL_PMU_GID_H2D_RSP, BIT(1)),
  323. CXL_PMU_EVENT_CXL_ATTR(h2d_rsp_go, CXL_PMU_GID_H2D_RSP, BIT(4)),
  324. CXL_PMU_EVENT_CXL_ATTR(h2d_rsp_gowritepull, CXL_PMU_GID_H2D_RSP, BIT(5)),
  325. CXL_PMU_EVENT_CXL_ATTR(h2d_rsp_extcmp, CXL_PMU_GID_H2D_RSP, BIT(6)),
  326. CXL_PMU_EVENT_CXL_ATTR(h2d_rsp_gowritepulldrop, CXL_PMU_GID_H2D_RSP, BIT(8)),
  327. CXL_PMU_EVENT_CXL_ATTR(h2d_rsp_fastgowritepull, CXL_PMU_GID_H2D_RSP, BIT(13)),
  328. CXL_PMU_EVENT_CXL_ATTR(h2d_rsp_goerrwritepull, CXL_PMU_GID_H2D_RSP, BIT(15)),
  329. /* CXL rev 3.0 Table 13-5 directly lists these */
  330. CXL_PMU_EVENT_CXL_ATTR(cachedata_d2h_data, CXL_PMU_GID_CACHE_DATA, BIT(0)),
  331. CXL_PMU_EVENT_CXL_ATTR(cachedata_h2d_data, CXL_PMU_GID_CACHE_DATA, BIT(1)),
  332. /* CXL rev 3.0 Table 3-29 M2S Req Memory Opcodes */
  333. CXL_PMU_EVENT_CXL_ATTR(m2s_req_meminv, CXL_PMU_GID_M2S_REQ, BIT(0)),
  334. CXL_PMU_EVENT_CXL_ATTR(m2s_req_memrd, CXL_PMU_GID_M2S_REQ, BIT(1)),
  335. CXL_PMU_EVENT_CXL_ATTR(m2s_req_memrddata, CXL_PMU_GID_M2S_REQ, BIT(2)),
  336. CXL_PMU_EVENT_CXL_ATTR(m2s_req_memrdfwd, CXL_PMU_GID_M2S_REQ, BIT(3)),
  337. CXL_PMU_EVENT_CXL_ATTR(m2s_req_memwrfwd, CXL_PMU_GID_M2S_REQ, BIT(4)),
  338. CXL_PMU_EVENT_CXL_ATTR(m2s_req_memspecrd, CXL_PMU_GID_M2S_REQ, BIT(8)),
  339. CXL_PMU_EVENT_CXL_ATTR(m2s_req_meminvnt, CXL_PMU_GID_M2S_REQ, BIT(9)),
  340. CXL_PMU_EVENT_CXL_ATTR(m2s_req_memcleanevict, CXL_PMU_GID_M2S_REQ, BIT(10)),
  341. /* CXL rev 3.0 Table 3-35 M2S RwD Memory Opcodes */
  342. CXL_PMU_EVENT_CXL_ATTR(m2s_rwd_memwr, CXL_PMU_GID_M2S_RWD, BIT(1)),
  343. CXL_PMU_EVENT_CXL_ATTR(m2s_rwd_memwrptl, CXL_PMU_GID_M2S_RWD, BIT(2)),
  344. CXL_PMU_EVENT_CXL_ATTR(m2s_rwd_biconflict, CXL_PMU_GID_M2S_RWD, BIT(4)),
  345. /* CXL rev 3.0 Table 3-38 M2S BIRsp Memory Opcodes */
  346. CXL_PMU_EVENT_CXL_ATTR(m2s_birsp_i, CXL_PMU_GID_M2S_BIRSP, BIT(0)),
  347. CXL_PMU_EVENT_CXL_ATTR(m2s_birsp_s, CXL_PMU_GID_M2S_BIRSP, BIT(1)),
  348. CXL_PMU_EVENT_CXL_ATTR(m2s_birsp_e, CXL_PMU_GID_M2S_BIRSP, BIT(2)),
  349. CXL_PMU_EVENT_CXL_ATTR(m2s_birsp_iblk, CXL_PMU_GID_M2S_BIRSP, BIT(4)),
  350. CXL_PMU_EVENT_CXL_ATTR(m2s_birsp_sblk, CXL_PMU_GID_M2S_BIRSP, BIT(5)),
  351. CXL_PMU_EVENT_CXL_ATTR(m2s_birsp_eblk, CXL_PMU_GID_M2S_BIRSP, BIT(6)),
  352. /* CXL rev 3.0 Table 3-40 S2M BISnp Opcodes */
  353. CXL_PMU_EVENT_CXL_ATTR(s2m_bisnp_cur, CXL_PMU_GID_S2M_BISNP, BIT(0)),
  354. CXL_PMU_EVENT_CXL_ATTR(s2m_bisnp_data, CXL_PMU_GID_S2M_BISNP, BIT(1)),
  355. CXL_PMU_EVENT_CXL_ATTR(s2m_bisnp_inv, CXL_PMU_GID_S2M_BISNP, BIT(2)),
  356. CXL_PMU_EVENT_CXL_ATTR(s2m_bisnp_curblk, CXL_PMU_GID_S2M_BISNP, BIT(4)),
  357. CXL_PMU_EVENT_CXL_ATTR(s2m_bisnp_datblk, CXL_PMU_GID_S2M_BISNP, BIT(5)),
  358. CXL_PMU_EVENT_CXL_ATTR(s2m_bisnp_invblk, CXL_PMU_GID_S2M_BISNP, BIT(6)),
  359. /* CXL rev 3.0 Table 3-43 S2M NDR Opcopdes */
  360. CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmp, CXL_PMU_GID_S2M_NDR, BIT(0)),
  361. CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmps, CXL_PMU_GID_S2M_NDR, BIT(1)),
  362. CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_cmpe, CXL_PMU_GID_S2M_NDR, BIT(2)),
  363. CXL_PMU_EVENT_CXL_ATTR(s2m_ndr_biconflictack, CXL_PMU_GID_S2M_NDR, BIT(4)),
  364. /* CXL rev 3.0 Table 3-46 S2M DRS opcodes */
  365. CXL_PMU_EVENT_CXL_ATTR(s2m_drs_memdata, CXL_PMU_GID_S2M_DRS, BIT(0)),
  366. CXL_PMU_EVENT_CXL_ATTR(s2m_drs_memdatanxm, CXL_PMU_GID_S2M_DRS, BIT(1)),
  367. /* CXL rev 3.0 Table 13-5 directly lists these */
  368. CXL_PMU_EVENT_CXL_ATTR(ddr_act, CXL_PMU_GID_DDR, BIT(0)),
  369. CXL_PMU_EVENT_CXL_ATTR(ddr_pre, CXL_PMU_GID_DDR, BIT(1)),
  370. CXL_PMU_EVENT_CXL_ATTR(ddr_casrd, CXL_PMU_GID_DDR, BIT(2)),
  371. CXL_PMU_EVENT_CXL_ATTR(ddr_caswr, CXL_PMU_GID_DDR, BIT(3)),
  372. CXL_PMU_EVENT_CXL_ATTR(ddr_refresh, CXL_PMU_GID_DDR, BIT(4)),
  373. CXL_PMU_EVENT_CXL_ATTR(ddr_selfrefreshent, CXL_PMU_GID_DDR, BIT(5)),
  374. CXL_PMU_EVENT_CXL_ATTR(ddr_rfm, CXL_PMU_GID_DDR, BIT(6)),
  375. NULL
  376. };
  377. static struct cxl_pmu_ev_cap *cxl_pmu_find_fixed_counter_ev_cap(struct cxl_pmu_info *info,
  378. int vid, int gid, int msk)
  379. {
  380. struct cxl_pmu_ev_cap *pmu_ev;
  381. list_for_each_entry(pmu_ev, &info->event_caps_fixed, node) {
  382. if (vid != pmu_ev->vid || gid != pmu_ev->gid)
  383. continue;
  384. /* Precise match for fixed counter */
  385. if (msk == pmu_ev->msk)
  386. return pmu_ev;
  387. }
  388. return ERR_PTR(-EINVAL);
  389. }
  390. static struct cxl_pmu_ev_cap *cxl_pmu_find_config_counter_ev_cap(struct cxl_pmu_info *info,
  391. int vid, int gid, int msk)
  392. {
  393. struct cxl_pmu_ev_cap *pmu_ev;
  394. list_for_each_entry(pmu_ev, &info->event_caps_configurable, node) {
  395. if (vid != pmu_ev->vid || gid != pmu_ev->gid)
  396. continue;
  397. /* Request mask must be subset of supported */
  398. if (msk & ~pmu_ev->msk)
  399. continue;
  400. return pmu_ev;
  401. }
  402. return ERR_PTR(-EINVAL);
  403. }
  404. static umode_t cxl_pmu_event_is_visible(struct kobject *kobj, struct attribute *attr, int a)
  405. {
  406. struct device_attribute *dev_attr = container_of(attr, struct device_attribute, attr);
  407. struct perf_pmu_events_attr *pmu_attr =
  408. container_of(dev_attr, struct perf_pmu_events_attr, attr);
  409. struct device *dev = kobj_to_dev(kobj);
  410. struct cxl_pmu_info *info = dev_get_drvdata(dev);
  411. int vid = FIELD_GET(CXL_PMU_ATTR_CONFIG_VID_MSK, pmu_attr->id);
  412. int gid = FIELD_GET(CXL_PMU_ATTR_CONFIG_GID_MSK, pmu_attr->id);
  413. int msk = FIELD_GET(CXL_PMU_ATTR_CONFIG_MASK_MSK, pmu_attr->id);
  414. if (!IS_ERR(cxl_pmu_find_fixed_counter_ev_cap(info, vid, gid, msk)))
  415. return attr->mode;
  416. if (!IS_ERR(cxl_pmu_find_config_counter_ev_cap(info, vid, gid, msk)))
  417. return attr->mode;
  418. return 0;
  419. }
  420. static const struct attribute_group cxl_pmu_events = {
  421. .name = "events",
  422. .attrs = cxl_pmu_event_attrs,
  423. .is_visible = cxl_pmu_event_is_visible,
  424. };
  425. static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr,
  426. char *buf)
  427. {
  428. struct cxl_pmu_info *info = dev_get_drvdata(dev);
  429. return cpumap_print_to_pagebuf(true, buf, cpumask_of(info->on_cpu));
  430. }
  431. static DEVICE_ATTR_RO(cpumask);
  432. static struct attribute *cxl_pmu_cpumask_attrs[] = {
  433. &dev_attr_cpumask.attr,
  434. NULL
  435. };
  436. static const struct attribute_group cxl_pmu_cpumask_group = {
  437. .attrs = cxl_pmu_cpumask_attrs,
  438. };
  439. static const struct attribute_group *cxl_pmu_attr_groups[] = {
  440. &cxl_pmu_events,
  441. &cxl_pmu_format_group,
  442. &cxl_pmu_cpumask_group,
  443. NULL
  444. };
  445. /* If counter_idx == NULL, don't try to allocate a counter. */
  446. static int cxl_pmu_get_event_idx(struct perf_event *event, int *counter_idx,
  447. int *event_idx)
  448. {
  449. struct cxl_pmu_info *info = pmu_to_cxl_pmu_info(event->pmu);
  450. DECLARE_BITMAP(configurable_and_free, CXL_PMU_MAX_COUNTERS);
  451. struct cxl_pmu_ev_cap *pmu_ev;
  452. u32 mask;
  453. u16 gid, vid;
  454. int i;
  455. vid = cxl_pmu_config_get_vid(event);
  456. gid = cxl_pmu_config_get_gid(event);
  457. mask = cxl_pmu_config_get_mask(event);
  458. pmu_ev = cxl_pmu_find_fixed_counter_ev_cap(info, vid, gid, mask);
  459. if (!IS_ERR(pmu_ev)) {
  460. if (!counter_idx)
  461. return 0;
  462. if (!test_bit(pmu_ev->counter_idx, info->used_counter_bm)) {
  463. *counter_idx = pmu_ev->counter_idx;
  464. return 0;
  465. }
  466. /* Fixed counter is in use, but maybe a configurable one? */
  467. }
  468. pmu_ev = cxl_pmu_find_config_counter_ev_cap(info, vid, gid, mask);
  469. if (!IS_ERR(pmu_ev)) {
  470. if (!counter_idx)
  471. return 0;
  472. bitmap_andnot(configurable_and_free, info->conf_counter_bm,
  473. info->used_counter_bm, CXL_PMU_MAX_COUNTERS);
  474. i = find_first_bit(configurable_and_free, CXL_PMU_MAX_COUNTERS);
  475. if (i == CXL_PMU_MAX_COUNTERS)
  476. return -EINVAL;
  477. *counter_idx = i;
  478. return 0;
  479. }
  480. return -EINVAL;
  481. }
  482. static int cxl_pmu_event_init(struct perf_event *event)
  483. {
  484. struct cxl_pmu_info *info = pmu_to_cxl_pmu_info(event->pmu);
  485. int rc;
  486. /* Top level type sanity check - is this a Hardware Event being requested */
  487. if (event->attr.type != event->pmu->type)
  488. return -ENOENT;
  489. if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
  490. return -EOPNOTSUPP;
  491. /* TODO: Validation of any filter */
  492. /*
  493. * Verify that it is possible to count what was requested. Either must
  494. * be a fixed counter that is a precise match or a configurable counter
  495. * where this is a subset.
  496. */
  497. rc = cxl_pmu_get_event_idx(event, NULL, NULL);
  498. if (rc < 0)
  499. return rc;
  500. event->cpu = info->on_cpu;
  501. return 0;
  502. }
  503. static void cxl_pmu_enable(struct pmu *pmu)
  504. {
  505. struct cxl_pmu_info *info = pmu_to_cxl_pmu_info(pmu);
  506. void __iomem *base = info->base;
  507. /* Can assume frozen at this stage */
  508. writeq(0, base + CXL_PMU_FREEZE_REG);
  509. }
  510. static void cxl_pmu_disable(struct pmu *pmu)
  511. {
  512. struct cxl_pmu_info *info = pmu_to_cxl_pmu_info(pmu);
  513. void __iomem *base = info->base;
  514. /*
  515. * Whilst bits above number of counters are RsvdZ
  516. * they are unlikely to be repurposed given
  517. * number of counters is allowed to be 64 leaving
  518. * no reserved bits. Hence this is only slightly
  519. * naughty.
  520. */
  521. writeq(GENMASK_ULL(63, 0), base + CXL_PMU_FREEZE_REG);
  522. }
  523. static void cxl_pmu_event_start(struct perf_event *event, int flags)
  524. {
  525. struct cxl_pmu_info *info = pmu_to_cxl_pmu_info(event->pmu);
  526. struct hw_perf_event *hwc = &event->hw;
  527. void __iomem *base = info->base;
  528. u64 cfg;
  529. /*
  530. * All paths to here should either set these flags directly or
  531. * call cxl_pmu_event_stop() which will ensure the correct state.
  532. */
  533. if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
  534. return;
  535. WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
  536. hwc->state = 0;
  537. /*
  538. * Currently only hdm filter control is implemnted, this code will
  539. * want generalizing when more filters are added.
  540. */
  541. if (info->filter_hdm) {
  542. if (cxl_pmu_config1_hdm_filter_en(event))
  543. cfg = cxl_pmu_config2_get_hdm_decoder(event);
  544. else
  545. cfg = GENMASK(31, 0); /* No filtering if 0xFFFF_FFFF */
  546. writeq(cfg, base + CXL_PMU_FILTER_CFG_REG(hwc->idx, 0));
  547. }
  548. cfg = readq(base + CXL_PMU_COUNTER_CFG_REG(hwc->idx));
  549. cfg |= FIELD_PREP(CXL_PMU_COUNTER_CFG_INT_ON_OVRFLW, 1);
  550. cfg |= FIELD_PREP(CXL_PMU_COUNTER_CFG_FREEZE_ON_OVRFLW, 1);
  551. cfg |= FIELD_PREP(CXL_PMU_COUNTER_CFG_ENABLE, 1);
  552. cfg |= FIELD_PREP(CXL_PMU_COUNTER_CFG_EDGE,
  553. cxl_pmu_config1_get_edge(event) ? 1 : 0);
  554. cfg |= FIELD_PREP(CXL_PMU_COUNTER_CFG_INVERT,
  555. cxl_pmu_config1_get_invert(event) ? 1 : 0);
  556. /* Fixed purpose counters have next two fields RO */
  557. if (test_bit(hwc->idx, info->conf_counter_bm)) {
  558. cfg |= FIELD_PREP(CXL_PMU_COUNTER_CFG_EVENT_GRP_ID_IDX_MSK,
  559. hwc->event_base);
  560. cfg |= FIELD_PREP(CXL_PMU_COUNTER_CFG_EVENTS_MSK,
  561. cxl_pmu_config_get_mask(event));
  562. }
  563. cfg &= ~CXL_PMU_COUNTER_CFG_THRESHOLD_MSK;
  564. /*
  565. * For events that generate only 1 count per clock the CXL 3.0 spec
  566. * states the threshold shall be set to 1 but if set to 0 it will
  567. * count the raw value anwyay?
  568. * There is no definition of what events will count multiple per cycle
  569. * and hence to which non 1 values of threshold can apply.
  570. * (CXL 3.0 8.2.7.2.1 Counter Configuration - threshold field definition)
  571. */
  572. cfg |= FIELD_PREP(CXL_PMU_COUNTER_CFG_THRESHOLD_MSK,
  573. cxl_pmu_config1_get_threshold(event));
  574. writeq(cfg, base + CXL_PMU_COUNTER_CFG_REG(hwc->idx));
  575. local64_set(&hwc->prev_count, 0);
  576. writeq(0, base + CXL_PMU_COUNTER_REG(hwc->idx));
  577. perf_event_update_userpage(event);
  578. }
  579. static u64 cxl_pmu_read_counter(struct perf_event *event)
  580. {
  581. struct cxl_pmu_info *info = pmu_to_cxl_pmu_info(event->pmu);
  582. void __iomem *base = info->base;
  583. return readq(base + CXL_PMU_COUNTER_REG(event->hw.idx));
  584. }
  585. static void __cxl_pmu_read(struct perf_event *event, bool overflow)
  586. {
  587. struct cxl_pmu_info *info = pmu_to_cxl_pmu_info(event->pmu);
  588. struct hw_perf_event *hwc = &event->hw;
  589. u64 new_cnt, prev_cnt, delta;
  590. do {
  591. prev_cnt = local64_read(&hwc->prev_count);
  592. new_cnt = cxl_pmu_read_counter(event);
  593. } while (local64_cmpxchg(&hwc->prev_count, prev_cnt, new_cnt) != prev_cnt);
  594. /*
  595. * If we know an overflow occur then take that into account.
  596. * Note counter is not reset as that would lose events
  597. */
  598. delta = (new_cnt - prev_cnt) & GENMASK_ULL(info->counter_width - 1, 0);
  599. if (overflow && delta < GENMASK_ULL(info->counter_width - 1, 0))
  600. delta += (1UL << info->counter_width);
  601. local64_add(delta, &event->count);
  602. }
  603. static void cxl_pmu_read(struct perf_event *event)
  604. {
  605. __cxl_pmu_read(event, false);
  606. }
  607. static void cxl_pmu_event_stop(struct perf_event *event, int flags)
  608. {
  609. struct cxl_pmu_info *info = pmu_to_cxl_pmu_info(event->pmu);
  610. void __iomem *base = info->base;
  611. struct hw_perf_event *hwc = &event->hw;
  612. u64 cfg;
  613. cxl_pmu_read(event);
  614. WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
  615. hwc->state |= PERF_HES_STOPPED;
  616. cfg = readq(base + CXL_PMU_COUNTER_CFG_REG(hwc->idx));
  617. cfg &= ~(FIELD_PREP(CXL_PMU_COUNTER_CFG_INT_ON_OVRFLW, 1) |
  618. FIELD_PREP(CXL_PMU_COUNTER_CFG_ENABLE, 1));
  619. writeq(cfg, base + CXL_PMU_COUNTER_CFG_REG(hwc->idx));
  620. hwc->state |= PERF_HES_UPTODATE;
  621. }
  622. static int cxl_pmu_event_add(struct perf_event *event, int flags)
  623. {
  624. struct cxl_pmu_info *info = pmu_to_cxl_pmu_info(event->pmu);
  625. struct hw_perf_event *hwc = &event->hw;
  626. int idx, rc;
  627. int event_idx = 0;
  628. hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
  629. rc = cxl_pmu_get_event_idx(event, &idx, &event_idx);
  630. if (rc < 0)
  631. return rc;
  632. hwc->idx = idx;
  633. /* Only set for configurable counters */
  634. hwc->event_base = event_idx;
  635. info->hw_events[idx] = event;
  636. set_bit(idx, info->used_counter_bm);
  637. if (flags & PERF_EF_START)
  638. cxl_pmu_event_start(event, PERF_EF_RELOAD);
  639. return 0;
  640. }
  641. static void cxl_pmu_event_del(struct perf_event *event, int flags)
  642. {
  643. struct cxl_pmu_info *info = pmu_to_cxl_pmu_info(event->pmu);
  644. struct hw_perf_event *hwc = &event->hw;
  645. cxl_pmu_event_stop(event, PERF_EF_UPDATE);
  646. clear_bit(hwc->idx, info->used_counter_bm);
  647. info->hw_events[hwc->idx] = NULL;
  648. perf_event_update_userpage(event);
  649. }
  650. static irqreturn_t cxl_pmu_irq(int irq, void *data)
  651. {
  652. struct cxl_pmu_info *info = data;
  653. void __iomem *base = info->base;
  654. u64 overflowed;
  655. DECLARE_BITMAP(overflowedbm, 64);
  656. int i;
  657. overflowed = readq(base + CXL_PMU_OVERFLOW_REG);
  658. /* Interrupt may be shared, so maybe it isn't ours */
  659. if (!overflowed)
  660. return IRQ_NONE;
  661. bitmap_from_arr64(overflowedbm, &overflowed, 64);
  662. for_each_set_bit(i, overflowedbm, info->num_counters) {
  663. struct perf_event *event = info->hw_events[i];
  664. if (!event) {
  665. dev_dbg(info->pmu.dev,
  666. "overflow but on non enabled counter %d\n", i);
  667. continue;
  668. }
  669. __cxl_pmu_read(event, true);
  670. }
  671. writeq(overflowed, base + CXL_PMU_OVERFLOW_REG);
  672. return IRQ_HANDLED;
  673. }
  674. static void cxl_pmu_perf_unregister(void *_info)
  675. {
  676. struct cxl_pmu_info *info = _info;
  677. perf_pmu_unregister(&info->pmu);
  678. }
  679. static void cxl_pmu_cpuhp_remove(void *_info)
  680. {
  681. struct cxl_pmu_info *info = _info;
  682. cpuhp_state_remove_instance_nocalls(cxl_pmu_cpuhp_state_num, &info->node);
  683. }
  684. static int cxl_pmu_probe(struct device *dev)
  685. {
  686. struct cxl_pmu *pmu = to_cxl_pmu(dev);
  687. struct pci_dev *pdev = to_pci_dev(dev->parent);
  688. struct cxl_pmu_info *info;
  689. char *irq_name;
  690. char *dev_name;
  691. int rc, irq;
  692. info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
  693. if (!info)
  694. return -ENOMEM;
  695. dev_set_drvdata(dev, info);
  696. INIT_LIST_HEAD(&info->event_caps_fixed);
  697. INIT_LIST_HEAD(&info->event_caps_configurable);
  698. info->base = pmu->base;
  699. info->on_cpu = -1;
  700. rc = cxl_pmu_parse_caps(dev, info);
  701. if (rc)
  702. return rc;
  703. info->hw_events = devm_kcalloc(dev, sizeof(*info->hw_events),
  704. info->num_counters, GFP_KERNEL);
  705. if (!info->hw_events)
  706. return -ENOMEM;
  707. switch (pmu->type) {
  708. case CXL_PMU_MEMDEV:
  709. dev_name = devm_kasprintf(dev, GFP_KERNEL, "cxl_pmu_mem%d.%d",
  710. pmu->assoc_id, pmu->index);
  711. break;
  712. }
  713. if (!dev_name)
  714. return -ENOMEM;
  715. info->pmu = (struct pmu) {
  716. .name = dev_name,
  717. .parent = dev,
  718. .module = THIS_MODULE,
  719. .event_init = cxl_pmu_event_init,
  720. .pmu_enable = cxl_pmu_enable,
  721. .pmu_disable = cxl_pmu_disable,
  722. .add = cxl_pmu_event_add,
  723. .del = cxl_pmu_event_del,
  724. .start = cxl_pmu_event_start,
  725. .stop = cxl_pmu_event_stop,
  726. .read = cxl_pmu_read,
  727. .task_ctx_nr = perf_invalid_context,
  728. .attr_groups = cxl_pmu_attr_groups,
  729. .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
  730. };
  731. if (info->irq <= 0)
  732. return -EINVAL;
  733. rc = pci_irq_vector(pdev, info->irq);
  734. if (rc < 0)
  735. return rc;
  736. irq = rc;
  737. irq_name = devm_kasprintf(dev, GFP_KERNEL, "%s_overflow", dev_name);
  738. if (!irq_name)
  739. return -ENOMEM;
  740. rc = devm_request_irq(dev, irq, cxl_pmu_irq, IRQF_SHARED | IRQF_ONESHOT,
  741. irq_name, info);
  742. if (rc)
  743. return rc;
  744. info->irq = irq;
  745. rc = cpuhp_state_add_instance(cxl_pmu_cpuhp_state_num, &info->node);
  746. if (rc)
  747. return rc;
  748. rc = devm_add_action_or_reset(dev, cxl_pmu_cpuhp_remove, info);
  749. if (rc)
  750. return rc;
  751. rc = perf_pmu_register(&info->pmu, info->pmu.name, -1);
  752. if (rc)
  753. return rc;
  754. rc = devm_add_action_or_reset(dev, cxl_pmu_perf_unregister, info);
  755. if (rc)
  756. return rc;
  757. return 0;
  758. }
  759. static struct cxl_driver cxl_pmu_driver = {
  760. .name = "cxl_pmu",
  761. .probe = cxl_pmu_probe,
  762. .id = CXL_DEVICE_PMU,
  763. };
  764. static int cxl_pmu_online_cpu(unsigned int cpu, struct hlist_node *node)
  765. {
  766. struct cxl_pmu_info *info = hlist_entry_safe(node, struct cxl_pmu_info, node);
  767. if (info->on_cpu != -1)
  768. return 0;
  769. info->on_cpu = cpu;
  770. /*
  771. * CPU HP lock is held so we should be guaranteed that the CPU hasn't yet
  772. * gone away again.
  773. */
  774. WARN_ON(irq_set_affinity(info->irq, cpumask_of(cpu)));
  775. return 0;
  776. }
  777. static int cxl_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
  778. {
  779. struct cxl_pmu_info *info = hlist_entry_safe(node, struct cxl_pmu_info, node);
  780. unsigned int target;
  781. if (info->on_cpu != cpu)
  782. return 0;
  783. info->on_cpu = -1;
  784. target = cpumask_any_but(cpu_online_mask, cpu);
  785. if (target >= nr_cpu_ids) {
  786. dev_err(info->pmu.dev, "Unable to find a suitable CPU\n");
  787. return 0;
  788. }
  789. perf_pmu_migrate_context(&info->pmu, cpu, target);
  790. info->on_cpu = target;
  791. /*
  792. * CPU HP lock is held so we should be guaranteed that this CPU hasn't yet
  793. * gone away.
  794. */
  795. WARN_ON(irq_set_affinity(info->irq, cpumask_of(target)));
  796. return 0;
  797. }
  798. static __init int cxl_pmu_init(void)
  799. {
  800. int rc;
  801. rc = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
  802. "AP_PERF_CXL_PMU_ONLINE",
  803. cxl_pmu_online_cpu, cxl_pmu_offline_cpu);
  804. if (rc < 0)
  805. return rc;
  806. cxl_pmu_cpuhp_state_num = rc;
  807. rc = cxl_driver_register(&cxl_pmu_driver);
  808. if (rc)
  809. cpuhp_remove_multi_state(cxl_pmu_cpuhp_state_num);
  810. return rc;
  811. }
  812. static __exit void cxl_pmu_exit(void)
  813. {
  814. cxl_driver_unregister(&cxl_pmu_driver);
  815. cpuhp_remove_multi_state(cxl_pmu_cpuhp_state_num);
  816. }
  817. MODULE_DESCRIPTION("CXL Performance Monitor Driver");
  818. MODULE_LICENSE("GPL");
  819. MODULE_IMPORT_NS(CXL);
  820. module_init(cxl_pmu_init);
  821. module_exit(cxl_pmu_exit);
  822. MODULE_ALIAS_CXL(CXL_DEVICE_PMU);