blob: 80ee3d4e70054d74ab397da7c426d729d95ce90b [file] [log] [blame]
Borislav Petkov6bcb2db2016-02-10 10:55:15 +01001#include "uncore.h"
Yan, Zheng087bfbb2012-06-15 14:31:34 +08002
3static struct intel_uncore_type *empty_uncore[] = { NULL, };
Yan, Zheng514b2342014-07-30 15:22:12 +08004struct intel_uncore_type **uncore_msr_uncores = empty_uncore;
5struct intel_uncore_type **uncore_pci_uncores = empty_uncore;
Yan, Zheng14371cc2012-06-15 14:31:36 +08006
Yan, Zheng514b2342014-07-30 15:22:12 +08007static bool pcidrv_registered;
8struct pci_driver *uncore_pci_driver;
9/* pci bus to socket mapping */
Taku Izumi712df652015-09-24 21:10:21 +090010DEFINE_RAW_SPINLOCK(pci2phy_map_lock);
11struct list_head pci2phy_map_head = LIST_HEAD_INIT(pci2phy_map_head);
Yan, Zheng514b2342014-07-30 15:22:12 +080012struct pci_dev *uncore_extra_pci_dev[UNCORE_SOCKET_MAX][UNCORE_EXTRA_PCI_DEV_MAX];
Yan, Zheng899396c2013-08-07 14:17:23 +080013
Yan, Zheng14371cc2012-06-15 14:31:36 +080014static DEFINE_RAW_SPINLOCK(uncore_box_lock);
Yan, Zheng087bfbb2012-06-15 14:31:34 +080015/* mask of cpus that collect uncore events */
16static cpumask_t uncore_cpu_mask;
17
18/* constraint for the fixed counter */
Yan, Zheng514b2342014-07-30 15:22:12 +080019static struct event_constraint uncore_constraint_fixed =
Yan, Zheng087bfbb2012-06-15 14:31:34 +080020 EVENT_CONSTRAINT(~0ULL, 1 << UNCORE_PMC_IDX_FIXED, ~0ULL);
Yan, Zheng514b2342014-07-30 15:22:12 +080021struct event_constraint uncore_constraint_empty =
Yan, Zheng6a679432012-07-04 14:00:15 +080022 EVENT_CONSTRAINT(0, 0, 0);
Yan, Zheng087bfbb2012-06-15 14:31:34 +080023
Thomas Gleixner1384c702016-02-22 22:19:13 +000024static int uncore_pcibus_to_physid(struct pci_bus *bus)
Taku Izumi712df652015-09-24 21:10:21 +090025{
26 struct pci2phy_map *map;
27 int phys_id = -1;
28
29 raw_spin_lock(&pci2phy_map_lock);
30 list_for_each_entry(map, &pci2phy_map_head, list) {
31 if (map->segment == pci_domain_nr(bus)) {
32 phys_id = map->pbus_to_physid[bus->number];
33 break;
34 }
35 }
36 raw_spin_unlock(&pci2phy_map_lock);
37
38 return phys_id;
39}
40
Thomas Gleixner4f089672016-02-22 22:19:09 +000041static void uncore_free_pcibus_map(void)
42{
43 struct pci2phy_map *map, *tmp;
44
45 list_for_each_entry_safe(map, tmp, &pci2phy_map_head, list) {
46 list_del(&map->list);
47 kfree(map);
48 }
49}
50
Taku Izumi712df652015-09-24 21:10:21 +090051struct pci2phy_map *__find_pci2phy_map(int segment)
52{
53 struct pci2phy_map *map, *alloc = NULL;
54 int i;
55
56 lockdep_assert_held(&pci2phy_map_lock);
57
58lookup:
59 list_for_each_entry(map, &pci2phy_map_head, list) {
60 if (map->segment == segment)
61 goto end;
62 }
63
64 if (!alloc) {
65 raw_spin_unlock(&pci2phy_map_lock);
66 alloc = kmalloc(sizeof(struct pci2phy_map), GFP_KERNEL);
67 raw_spin_lock(&pci2phy_map_lock);
68
69 if (!alloc)
70 return NULL;
71
72 goto lookup;
73 }
74
75 map = alloc;
76 alloc = NULL;
77 map->segment = segment;
78 for (i = 0; i < 256; i++)
79 map->pbus_to_physid[i] = -1;
80 list_add_tail(&map->list, &pci2phy_map_head);
81
82end:
83 kfree(alloc);
84 return map;
85}
86
Yan, Zheng514b2342014-07-30 15:22:12 +080087ssize_t uncore_event_show(struct kobject *kobj,
88 struct kobj_attribute *attr, char *buf)
89{
90 struct uncore_event_desc *event =
91 container_of(attr, struct uncore_event_desc, attr);
92 return sprintf(buf, "%s", event->config);
93}
94
Yan, Zheng514b2342014-07-30 15:22:12 +080095struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event)
Stephane Eranian001e4132014-02-11 16:20:11 +010096{
97 return container_of(event->pmu, struct intel_uncore_pmu, pmu);
98}
99
Yan, Zheng514b2342014-07-30 15:22:12 +0800100struct intel_uncore_box *uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu)
Stephane Eranian001e4132014-02-11 16:20:11 +0100101{
102 struct intel_uncore_box *box;
103
104 box = *per_cpu_ptr(pmu->box, cpu);
105 if (box)
106 return box;
107
108 raw_spin_lock(&uncore_box_lock);
Andi Kleen4f971242014-09-22 15:27:06 -0700109 /* Recheck in lock to handle races. */
110 if (*per_cpu_ptr(pmu->box, cpu))
111 goto out;
Stephane Eranian001e4132014-02-11 16:20:11 +0100112 list_for_each_entry(box, &pmu->box_list, list) {
113 if (box->phys_id == topology_physical_package_id(cpu)) {
114 atomic_inc(&box->refcnt);
115 *per_cpu_ptr(pmu->box, cpu) = box;
116 break;
117 }
118 }
Andi Kleen4f971242014-09-22 15:27:06 -0700119out:
Stephane Eranian001e4132014-02-11 16:20:11 +0100120 raw_spin_unlock(&uncore_box_lock);
121
122 return *per_cpu_ptr(pmu->box, cpu);
123}
124
Yan, Zheng514b2342014-07-30 15:22:12 +0800125struct intel_uncore_box *uncore_event_to_box(struct perf_event *event)
Stephane Eranian001e4132014-02-11 16:20:11 +0100126{
127 /*
128 * perf core schedules event on the basis of cpu, uncore events are
129 * collected by one of the cpus inside a physical package.
130 */
131 return uncore_pmu_to_box(uncore_event_to_pmu(event), smp_processor_id());
132}
133
Yan, Zheng514b2342014-07-30 15:22:12 +0800134u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event)
Yan, Zheng254298c2012-07-05 14:32:17 +0800135{
136 u64 count;
137
138 rdmsrl(event->hw.event_base, count);
139
140 return count;
141}
142
143/*
144 * generic get constraint function for shared match/mask registers.
145 */
Yan, Zheng514b2342014-07-30 15:22:12 +0800146struct event_constraint *
Yan, Zheng254298c2012-07-05 14:32:17 +0800147uncore_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
148{
149 struct intel_uncore_extra_reg *er;
150 struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
151 struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
152 unsigned long flags;
153 bool ok = false;
154
155 /*
156 * reg->alloc can be set due to existing state, so for fake box we
157 * need to ignore this, otherwise we might fail to allocate proper
158 * fake state for this extra reg constraint.
159 */
160 if (reg1->idx == EXTRA_REG_NONE ||
161 (!uncore_box_is_fake(box) && reg1->alloc))
162 return NULL;
163
164 er = &box->shared_regs[reg1->idx];
165 raw_spin_lock_irqsave(&er->lock, flags);
166 if (!atomic_read(&er->ref) ||
167 (er->config1 == reg1->config && er->config2 == reg2->config)) {
168 atomic_inc(&er->ref);
169 er->config1 = reg1->config;
170 er->config2 = reg2->config;
171 ok = true;
172 }
173 raw_spin_unlock_irqrestore(&er->lock, flags);
174
175 if (ok) {
176 if (!uncore_box_is_fake(box))
177 reg1->alloc = 1;
178 return NULL;
179 }
180
Yan, Zheng514b2342014-07-30 15:22:12 +0800181 return &uncore_constraint_empty;
Yan, Zheng254298c2012-07-05 14:32:17 +0800182}
183
Yan, Zheng514b2342014-07-30 15:22:12 +0800184void uncore_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
Yan, Zheng254298c2012-07-05 14:32:17 +0800185{
186 struct intel_uncore_extra_reg *er;
187 struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
188
189 /*
190 * Only put constraint if extra reg was actually allocated. Also
191 * takes care of event which do not use an extra shared reg.
192 *
193 * Also, if this is a fake box we shouldn't touch any event state
194 * (reg->alloc) and we don't care about leaving inconsistent box
195 * state either since it will be thrown out.
196 */
197 if (uncore_box_is_fake(box) || !reg1->alloc)
198 return;
199
200 er = &box->shared_regs[reg1->idx];
201 atomic_dec(&er->ref);
202 reg1->alloc = 0;
203}
204
Yan, Zheng514b2342014-07-30 15:22:12 +0800205u64 uncore_shared_reg_config(struct intel_uncore_box *box, int idx)
Yan, Zheng46bdd902013-04-16 19:51:06 +0800206{
207 struct intel_uncore_extra_reg *er;
208 unsigned long flags;
209 u64 config;
210
211 er = &box->shared_regs[idx];
212
213 raw_spin_lock_irqsave(&er->lock, flags);
214 config = er->config;
215 raw_spin_unlock_irqrestore(&er->lock, flags);
216
217 return config;
218}
219
Thomas Gleixner12297352016-02-22 22:19:12 +0000220static void uncore_assign_hw_event(struct intel_uncore_box *box,
221 struct perf_event *event, int idx)
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800222{
223 struct hw_perf_event *hwc = &event->hw;
224
225 hwc->idx = idx;
226 hwc->last_tag = ++box->tags[idx];
227
228 if (hwc->idx == UNCORE_PMC_IDX_FIXED) {
Yan, Zheng14371cc2012-06-15 14:31:36 +0800229 hwc->event_base = uncore_fixed_ctr(box);
230 hwc->config_base = uncore_fixed_ctl(box);
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800231 return;
232 }
233
Yan, Zheng14371cc2012-06-15 14:31:36 +0800234 hwc->config_base = uncore_event_ctl(box, hwc->idx);
235 hwc->event_base = uncore_perf_ctr(box, hwc->idx);
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800236}
237
Yan, Zheng514b2342014-07-30 15:22:12 +0800238void uncore_perf_event_update(struct intel_uncore_box *box, struct perf_event *event)
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800239{
240 u64 prev_count, new_count, delta;
241 int shift;
242
243 if (event->hw.idx >= UNCORE_PMC_IDX_FIXED)
244 shift = 64 - uncore_fixed_ctr_bits(box);
245 else
246 shift = 64 - uncore_perf_ctr_bits(box);
247
248 /* the hrtimer might modify the previous event value */
249again:
250 prev_count = local64_read(&event->hw.prev_count);
251 new_count = uncore_read_counter(box, event);
252 if (local64_xchg(&event->hw.prev_count, new_count) != prev_count)
253 goto again;
254
255 delta = (new_count << shift) - (prev_count << shift);
256 delta >>= shift;
257
258 local64_add(delta, &event->count);
259}
260
261/*
262 * The overflow interrupt is unavailable for SandyBridge-EP, is broken
263 * for SandyBridge. So we use hrtimer to periodically poll the counter
264 * to avoid overflow.
265 */
266static enum hrtimer_restart uncore_pmu_hrtimer(struct hrtimer *hrtimer)
267{
268 struct intel_uncore_box *box;
Stephane Eranianced2efb2014-02-11 16:20:13 +0100269 struct perf_event *event;
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800270 unsigned long flags;
271 int bit;
272
273 box = container_of(hrtimer, struct intel_uncore_box, hrtimer);
274 if (!box->n_active || box->cpu != smp_processor_id())
275 return HRTIMER_NORESTART;
276 /*
277 * disable local interrupt to prevent uncore_pmu_event_start/stop
278 * to interrupt the update process
279 */
280 local_irq_save(flags);
281
Stephane Eranianced2efb2014-02-11 16:20:13 +0100282 /*
283 * handle boxes with an active event list as opposed to active
284 * counters
285 */
286 list_for_each_entry(event, &box->active_list, active_entry) {
287 uncore_perf_event_update(box, event);
288 }
289
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800290 for_each_set_bit(bit, box->active_mask, UNCORE_PMC_IDX_MAX)
291 uncore_perf_event_update(box, box->events[bit]);
292
293 local_irq_restore(flags);
294
Stephane Eranian79859cc2014-02-11 16:20:10 +0100295 hrtimer_forward_now(hrtimer, ns_to_ktime(box->hrtimer_duration));
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800296 return HRTIMER_RESTART;
297}
298
Yan, Zheng514b2342014-07-30 15:22:12 +0800299void uncore_pmu_start_hrtimer(struct intel_uncore_box *box)
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800300{
Thomas Gleixner576b0702015-04-14 21:09:01 +0000301 hrtimer_start(&box->hrtimer, ns_to_ktime(box->hrtimer_duration),
302 HRTIMER_MODE_REL_PINNED);
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800303}
304
Yan, Zheng514b2342014-07-30 15:22:12 +0800305void uncore_pmu_cancel_hrtimer(struct intel_uncore_box *box)
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800306{
307 hrtimer_cancel(&box->hrtimer);
308}
309
310static void uncore_pmu_init_hrtimer(struct intel_uncore_box *box)
311{
312 hrtimer_init(&box->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
313 box->hrtimer.function = uncore_pmu_hrtimer;
314}
315
Thomas Gleixner12297352016-02-22 22:19:12 +0000316static struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type,
317 int node)
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800318{
Thomas Gleixner12297352016-02-22 22:19:12 +0000319 int i, size, numshared = type->num_shared_regs ;
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800320 struct intel_uncore_box *box;
321
Thomas Gleixner12297352016-02-22 22:19:12 +0000322 size = sizeof(*box) + numshared * sizeof(struct intel_uncore_extra_reg);
Yan, Zheng6a679432012-07-04 14:00:15 +0800323
Yan, Zheng73c44272013-09-17 14:48:13 +0800324 box = kzalloc_node(size, GFP_KERNEL, node);
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800325 if (!box)
326 return NULL;
327
Thomas Gleixner12297352016-02-22 22:19:12 +0000328 for (i = 0; i < numshared; i++)
Yan, Zheng6a679432012-07-04 14:00:15 +0800329 raw_spin_lock_init(&box->shared_regs[i].lock);
330
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800331 uncore_pmu_init_hrtimer(box);
332 atomic_set(&box->refcnt, 1);
333 box->cpu = -1;
334 box->phys_id = -1;
335
Stephane Eranian79859cc2014-02-11 16:20:10 +0100336 /* set default hrtimer timeout */
337 box->hrtimer_duration = UNCORE_PMU_HRTIMER_INTERVAL;
338
Stephane Eranianced2efb2014-02-11 16:20:13 +0100339 INIT_LIST_HEAD(&box->active_list);
340
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800341 return box;
342}
343
Jiri Olsaaf915682014-12-10 21:23:50 +0100344/*
345 * Using uncore_pmu_event_init pmu event_init callback
346 * as a detection point for uncore events.
347 */
348static int uncore_pmu_event_init(struct perf_event *event);
349
350static bool is_uncore_event(struct perf_event *event)
351{
352 return event->pmu->event_init == uncore_pmu_event_init;
353}
354
Yan, Zheng254298c2012-07-05 14:32:17 +0800355static int
Thomas Gleixner12297352016-02-22 22:19:12 +0000356uncore_collect_events(struct intel_uncore_box *box, struct perf_event *leader,
357 bool dogrp)
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800358{
359 struct perf_event *event;
360 int n, max_count;
361
362 max_count = box->pmu->type->num_counters;
363 if (box->pmu->type->fixed_ctl)
364 max_count++;
365
366 if (box->n_events >= max_count)
367 return -EINVAL;
368
369 n = box->n_events;
Jiri Olsaaf915682014-12-10 21:23:50 +0100370
371 if (is_uncore_event(leader)) {
372 box->event_list[n] = leader;
373 n++;
374 }
375
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800376 if (!dogrp)
377 return n;
378
379 list_for_each_entry(event, &leader->sibling_list, group_entry) {
Jiri Olsaaf915682014-12-10 21:23:50 +0100380 if (!is_uncore_event(event) ||
381 event->state <= PERF_EVENT_STATE_OFF)
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800382 continue;
383
384 if (n >= max_count)
385 return -EINVAL;
386
387 box->event_list[n] = event;
388 n++;
389 }
390 return n;
391}
392
393static struct event_constraint *
Yan, Zheng254298c2012-07-05 14:32:17 +0800394uncore_get_event_constraint(struct intel_uncore_box *box, struct perf_event *event)
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800395{
Yan, Zheng6a679432012-07-04 14:00:15 +0800396 struct intel_uncore_type *type = box->pmu->type;
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800397 struct event_constraint *c;
398
Yan, Zheng6a679432012-07-04 14:00:15 +0800399 if (type->ops->get_constraint) {
400 c = type->ops->get_constraint(box, event);
401 if (c)
402 return c;
403 }
404
Stephane Eraniandbc33f72013-09-09 12:53:50 -0700405 if (event->attr.config == UNCORE_FIXED_EVENT)
Yan, Zheng514b2342014-07-30 15:22:12 +0800406 return &uncore_constraint_fixed;
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800407
408 if (type->constraints) {
409 for_each_event_constraint(c, type->constraints) {
410 if ((event->hw.config & c->cmask) == c->code)
411 return c;
412 }
413 }
414
415 return &type->unconstrainted;
416}
417
Thomas Gleixner12297352016-02-22 22:19:12 +0000418static void uncore_put_event_constraint(struct intel_uncore_box *box,
419 struct perf_event *event)
Yan, Zheng6a679432012-07-04 14:00:15 +0800420{
421 if (box->pmu->type->ops->put_constraint)
422 box->pmu->type->ops->put_constraint(box, event);
423}
424
Yan, Zheng254298c2012-07-05 14:32:17 +0800425static int uncore_assign_events(struct intel_uncore_box *box, int assign[], int n)
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800426{
427 unsigned long used_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)];
Andrew Hunter43b457802013-05-23 11:07:03 -0700428 struct event_constraint *c;
Yan, Zheng6a679432012-07-04 14:00:15 +0800429 int i, wmin, wmax, ret = 0;
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800430 struct hw_perf_event *hwc;
431
432 bitmap_zero(used_mask, UNCORE_PMC_IDX_MAX);
433
434 for (i = 0, wmin = UNCORE_PMC_IDX_MAX, wmax = 0; i < n; i++) {
Yan, Zheng6a679432012-07-04 14:00:15 +0800435 c = uncore_get_event_constraint(box, box->event_list[i]);
Peter Zijlstrab371b592015-05-21 10:57:13 +0200436 box->event_constraint[i] = c;
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800437 wmin = min(wmin, c->weight);
438 wmax = max(wmax, c->weight);
439 }
440
441 /* fastpath, try to reuse previous register */
442 for (i = 0; i < n; i++) {
443 hwc = &box->event_list[i]->hw;
Peter Zijlstrab371b592015-05-21 10:57:13 +0200444 c = box->event_constraint[i];
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800445
446 /* never assigned */
447 if (hwc->idx == -1)
448 break;
449
450 /* constraint still honored */
451 if (!test_bit(hwc->idx, c->idxmsk))
452 break;
453
454 /* not already used */
455 if (test_bit(hwc->idx, used_mask))
456 break;
457
458 __set_bit(hwc->idx, used_mask);
Yan, Zheng6a679432012-07-04 14:00:15 +0800459 if (assign)
460 assign[i] = hwc->idx;
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800461 }
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800462 /* slow path */
Yan, Zheng6a679432012-07-04 14:00:15 +0800463 if (i != n)
Peter Zijlstrab371b592015-05-21 10:57:13 +0200464 ret = perf_assign_events(box->event_constraint, n,
Peter Zijlstracc1790c2015-05-21 10:57:17 +0200465 wmin, wmax, n, assign);
Yan, Zheng6a679432012-07-04 14:00:15 +0800466
467 if (!assign || ret) {
468 for (i = 0; i < n; i++)
469 uncore_put_event_constraint(box, box->event_list[i]);
470 }
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800471 return ret ? -EINVAL : 0;
472}
473
474static void uncore_pmu_event_start(struct perf_event *event, int flags)
475{
476 struct intel_uncore_box *box = uncore_event_to_box(event);
477 int idx = event->hw.idx;
478
479 if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
480 return;
481
482 if (WARN_ON_ONCE(idx == -1 || idx >= UNCORE_PMC_IDX_MAX))
483 return;
484
485 event->hw.state = 0;
486 box->events[idx] = event;
487 box->n_active++;
488 __set_bit(idx, box->active_mask);
489
490 local64_set(&event->hw.prev_count, uncore_read_counter(box, event));
491 uncore_enable_event(box, event);
492
493 if (box->n_active == 1) {
494 uncore_enable_box(box);
495 uncore_pmu_start_hrtimer(box);
496 }
497}
498
499static void uncore_pmu_event_stop(struct perf_event *event, int flags)
500{
501 struct intel_uncore_box *box = uncore_event_to_box(event);
502 struct hw_perf_event *hwc = &event->hw;
503
504 if (__test_and_clear_bit(hwc->idx, box->active_mask)) {
505 uncore_disable_event(box, event);
506 box->n_active--;
507 box->events[hwc->idx] = NULL;
508 WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
509 hwc->state |= PERF_HES_STOPPED;
510
511 if (box->n_active == 0) {
512 uncore_disable_box(box);
513 uncore_pmu_cancel_hrtimer(box);
514 }
515 }
516
517 if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
518 /*
519 * Drain the remaining delta count out of a event
520 * that we are disabling:
521 */
522 uncore_perf_event_update(box, event);
523 hwc->state |= PERF_HES_UPTODATE;
524 }
525}
526
527static int uncore_pmu_event_add(struct perf_event *event, int flags)
528{
529 struct intel_uncore_box *box = uncore_event_to_box(event);
530 struct hw_perf_event *hwc = &event->hw;
531 int assign[UNCORE_PMC_IDX_MAX];
532 int i, n, ret;
533
534 if (!box)
535 return -ENODEV;
536
537 ret = n = uncore_collect_events(box, event, false);
538 if (ret < 0)
539 return ret;
540
541 hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
542 if (!(flags & PERF_EF_START))
543 hwc->state |= PERF_HES_ARCH;
544
545 ret = uncore_assign_events(box, assign, n);
546 if (ret)
547 return ret;
548
549 /* save events moving to new counters */
550 for (i = 0; i < box->n_events; i++) {
551 event = box->event_list[i];
552 hwc = &event->hw;
553
554 if (hwc->idx == assign[i] &&
555 hwc->last_tag == box->tags[assign[i]])
556 continue;
557 /*
558 * Ensure we don't accidentally enable a stopped
559 * counter simply because we rescheduled.
560 */
561 if (hwc->state & PERF_HES_STOPPED)
562 hwc->state |= PERF_HES_ARCH;
563
564 uncore_pmu_event_stop(event, PERF_EF_UPDATE);
565 }
566
567 /* reprogram moved events into new counters */
568 for (i = 0; i < n; i++) {
569 event = box->event_list[i];
570 hwc = &event->hw;
571
572 if (hwc->idx != assign[i] ||
573 hwc->last_tag != box->tags[assign[i]])
574 uncore_assign_hw_event(box, event, assign[i]);
575 else if (i < box->n_events)
576 continue;
577
578 if (hwc->state & PERF_HES_ARCH)
579 continue;
580
581 uncore_pmu_event_start(event, 0);
582 }
583 box->n_events = n;
584
585 return 0;
586}
587
588static void uncore_pmu_event_del(struct perf_event *event, int flags)
589{
590 struct intel_uncore_box *box = uncore_event_to_box(event);
591 int i;
592
593 uncore_pmu_event_stop(event, PERF_EF_UPDATE);
594
595 for (i = 0; i < box->n_events; i++) {
596 if (event == box->event_list[i]) {
Yan, Zheng6a679432012-07-04 14:00:15 +0800597 uncore_put_event_constraint(box, event);
598
Thomas Gleixner12297352016-02-22 22:19:12 +0000599 for (++i; i < box->n_events; i++)
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800600 box->event_list[i - 1] = box->event_list[i];
601
602 --box->n_events;
603 break;
604 }
605 }
606
607 event->hw.idx = -1;
608 event->hw.last_tag = ~0ULL;
609}
610
Yan, Zheng514b2342014-07-30 15:22:12 +0800611void uncore_pmu_event_read(struct perf_event *event)
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800612{
613 struct intel_uncore_box *box = uncore_event_to_box(event);
614 uncore_perf_event_update(box, event);
615}
616
617/*
618 * validation ensures the group can be loaded onto the
619 * PMU if it was the only group available.
620 */
621static int uncore_validate_group(struct intel_uncore_pmu *pmu,
622 struct perf_event *event)
623{
624 struct perf_event *leader = event->group_leader;
625 struct intel_uncore_box *fake_box;
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800626 int ret = -EINVAL, n;
627
Yan, Zheng73c44272013-09-17 14:48:13 +0800628 fake_box = uncore_alloc_box(pmu->type, NUMA_NO_NODE);
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800629 if (!fake_box)
630 return -ENOMEM;
631
632 fake_box->pmu = pmu;
633 /*
634 * the event is not yet connected with its
635 * siblings therefore we must first collect
636 * existing siblings, then add the new event
637 * before we can simulate the scheduling
638 */
639 n = uncore_collect_events(fake_box, leader, true);
640 if (n < 0)
641 goto out;
642
643 fake_box->n_events = n;
644 n = uncore_collect_events(fake_box, event, false);
645 if (n < 0)
646 goto out;
647
648 fake_box->n_events = n;
649
Yan, Zheng6a679432012-07-04 14:00:15 +0800650 ret = uncore_assign_events(fake_box, NULL, n);
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800651out:
652 kfree(fake_box);
653 return ret;
654}
655
Yan, Zheng46bdd902013-04-16 19:51:06 +0800656static int uncore_pmu_event_init(struct perf_event *event)
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800657{
658 struct intel_uncore_pmu *pmu;
659 struct intel_uncore_box *box;
660 struct hw_perf_event *hwc = &event->hw;
661 int ret;
662
663 if (event->attr.type != event->pmu->type)
664 return -ENOENT;
665
666 pmu = uncore_event_to_pmu(event);
667 /* no device found for this pmu */
668 if (pmu->func_id < 0)
669 return -ENOENT;
670
671 /*
672 * Uncore PMU does measure at all privilege level all the time.
673 * So it doesn't make sense to specify any exclude bits.
674 */
675 if (event->attr.exclude_user || event->attr.exclude_kernel ||
676 event->attr.exclude_hv || event->attr.exclude_idle)
677 return -EINVAL;
678
679 /* Sampling not supported yet */
680 if (hwc->sample_period)
681 return -EINVAL;
682
683 /*
684 * Place all uncore events for a particular physical package
685 * onto a single cpu
686 */
687 if (event->cpu < 0)
688 return -EINVAL;
689 box = uncore_pmu_to_box(pmu, event->cpu);
690 if (!box || box->cpu < 0)
691 return -EINVAL;
692 event->cpu = box->cpu;
693
Yan, Zheng6a679432012-07-04 14:00:15 +0800694 event->hw.idx = -1;
695 event->hw.last_tag = ~0ULL;
696 event->hw.extra_reg.idx = EXTRA_REG_NONE;
Yan, Zhengebb6cc02012-08-06 13:11:21 +0800697 event->hw.branch_reg.idx = EXTRA_REG_NONE;
Yan, Zheng6a679432012-07-04 14:00:15 +0800698
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800699 if (event->attr.config == UNCORE_FIXED_EVENT) {
700 /* no fixed counter */
701 if (!pmu->type->fixed_ctl)
702 return -EINVAL;
703 /*
704 * if there is only one fixed counter, only the first pmu
705 * can access the fixed counter
706 */
707 if (pmu->type->single_fixed && pmu->pmu_idx > 0)
708 return -EINVAL;
Stephane Eraniandbc33f72013-09-09 12:53:50 -0700709
710 /* fixed counters have event field hardcoded to zero */
711 hwc->config = 0ULL;
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800712 } else {
713 hwc->config = event->attr.config & pmu->type->event_mask;
Yan, Zheng6a679432012-07-04 14:00:15 +0800714 if (pmu->type->ops->hw_config) {
715 ret = pmu->type->ops->hw_config(box, event);
716 if (ret)
717 return ret;
718 }
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800719 }
720
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800721 if (event->group_leader != event)
722 ret = uncore_validate_group(pmu, event);
723 else
724 ret = 0;
725
726 return ret;
727}
728
Yan, Zheng314d9f62012-09-10 15:53:49 +0800729static ssize_t uncore_get_attr_cpumask(struct device *dev,
730 struct device_attribute *attr, char *buf)
731{
Sudeep Holla5aaba362014-09-30 14:48:22 +0100732 return cpumap_print_to_pagebuf(true, buf, &uncore_cpu_mask);
Yan, Zheng314d9f62012-09-10 15:53:49 +0800733}
734
735static DEVICE_ATTR(cpumask, S_IRUGO, uncore_get_attr_cpumask, NULL);
736
737static struct attribute *uncore_pmu_attrs[] = {
738 &dev_attr_cpumask.attr,
739 NULL,
740};
741
742static struct attribute_group uncore_pmu_attr_group = {
743 .attrs = uncore_pmu_attrs,
744};
745
Andi Kleena08b6762014-08-29 10:20:58 -0700746static int uncore_pmu_register(struct intel_uncore_pmu *pmu)
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800747{
748 int ret;
749
Stephane Eraniand64b25b2014-02-11 16:20:08 +0100750 if (!pmu->type->pmu) {
751 pmu->pmu = (struct pmu) {
752 .attr_groups = pmu->type->attr_groups,
753 .task_ctx_nr = perf_invalid_context,
754 .event_init = uncore_pmu_event_init,
755 .add = uncore_pmu_event_add,
756 .del = uncore_pmu_event_del,
757 .start = uncore_pmu_event_start,
758 .stop = uncore_pmu_event_stop,
759 .read = uncore_pmu_event_read,
760 };
761 } else {
762 pmu->pmu = *pmu->type->pmu;
763 pmu->pmu.attr_groups = pmu->type->attr_groups;
764 }
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800765
766 if (pmu->type->num_boxes == 1) {
767 if (strlen(pmu->type->name) > 0)
768 sprintf(pmu->name, "uncore_%s", pmu->type->name);
769 else
770 sprintf(pmu->name, "uncore");
771 } else {
772 sprintf(pmu->name, "uncore_%s_%d", pmu->type->name,
773 pmu->pmu_idx);
774 }
775
776 ret = perf_pmu_register(&pmu->pmu, pmu->name, -1);
Thomas Gleixner4f089672016-02-22 22:19:09 +0000777 if (!ret)
778 pmu->registered = true;
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800779 return ret;
780}
781
Thomas Gleixner4f089672016-02-22 22:19:09 +0000782static void uncore_pmu_unregister(struct intel_uncore_pmu *pmu)
783{
784 if (!pmu->registered)
785 return;
786 perf_pmu_unregister(&pmu->pmu);
787 pmu->registered = false;
788}
789
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800790static void __init uncore_type_exit(struct intel_uncore_type *type)
791{
792 int i;
793
Thomas Gleixnerffeda002016-02-22 22:19:09 +0000794 if (type->pmus) {
Thomas Gleixner4f089672016-02-22 22:19:09 +0000795 for (i = 0; i < type->num_boxes; i++) {
796 uncore_pmu_unregister(&type->pmus[i]);
Thomas Gleixnerffeda002016-02-22 22:19:09 +0000797 free_percpu(type->pmus[i].box);
Thomas Gleixner4f089672016-02-22 22:19:09 +0000798 }
Thomas Gleixnerffeda002016-02-22 22:19:09 +0000799 kfree(type->pmus);
800 type->pmus = NULL;
801 }
Yan, Zheng314d9f62012-09-10 15:53:49 +0800802 kfree(type->events_group);
803 type->events_group = NULL;
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800804}
805
Borislav Petkovcffa59b2012-08-02 12:55:27 +0200806static void __init uncore_types_exit(struct intel_uncore_type **types)
Yan, Zheng14371cc2012-06-15 14:31:36 +0800807{
Thomas Gleixner12297352016-02-22 22:19:12 +0000808 for (; *types; types++)
809 uncore_type_exit(*types);
Yan, Zheng14371cc2012-06-15 14:31:36 +0800810}
811
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800812static int __init uncore_type_init(struct intel_uncore_type *type)
813{
814 struct intel_uncore_pmu *pmus;
Jan-Simon Möller1b0dac22013-04-30 12:02:33 +0200815 struct attribute_group *attr_group;
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800816 struct attribute **attrs;
817 int i, j;
818
819 pmus = kzalloc(sizeof(*pmus) * type->num_boxes, GFP_KERNEL);
820 if (!pmus)
821 return -ENOMEM;
822
Dave Jonesb7b48392014-03-06 12:20:28 -0500823 type->pmus = pmus;
824
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800825 type->unconstrainted = (struct event_constraint)
826 __EVENT_CONSTRAINT(0, (1ULL << type->num_counters) - 1,
Stephane Eranian9fac2cf2013-01-24 16:10:27 +0100827 0, type->num_counters, 0, 0);
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800828
829 for (i = 0; i < type->num_boxes; i++) {
830 pmus[i].func_id = -1;
831 pmus[i].pmu_idx = i;
832 pmus[i].type = type;
Yan, Zheng14371cc2012-06-15 14:31:36 +0800833 INIT_LIST_HEAD(&pmus[i].box_list);
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800834 pmus[i].box = alloc_percpu(struct intel_uncore_box *);
835 if (!pmus[i].box)
Thomas Gleixnerffeda002016-02-22 22:19:09 +0000836 return -ENOMEM;
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800837 }
838
839 if (type->event_descs) {
840 i = 0;
841 while (type->event_descs[i].attr.attr.name)
842 i++;
843
Jan-Simon Möller1b0dac22013-04-30 12:02:33 +0200844 attr_group = kzalloc(sizeof(struct attribute *) * (i + 1) +
845 sizeof(*attr_group), GFP_KERNEL);
846 if (!attr_group)
Thomas Gleixnerffeda002016-02-22 22:19:09 +0000847 return -ENOMEM;
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800848
Jan-Simon Möller1b0dac22013-04-30 12:02:33 +0200849 attrs = (struct attribute **)(attr_group + 1);
850 attr_group->name = "events";
851 attr_group->attrs = attrs;
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800852
853 for (j = 0; j < i; j++)
854 attrs[j] = &type->event_descs[j].attr.attr;
855
Jan-Simon Möller1b0dac22013-04-30 12:02:33 +0200856 type->events_group = attr_group;
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800857 }
858
Yan, Zheng314d9f62012-09-10 15:53:49 +0800859 type->pmu_group = &uncore_pmu_attr_group;
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800860 return 0;
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800861}
862
863static int __init uncore_types_init(struct intel_uncore_type **types)
864{
865 int i, ret;
866
867 for (i = 0; types[i]; i++) {
868 ret = uncore_type_init(types[i]);
869 if (ret)
Thomas Gleixnerffeda002016-02-22 22:19:09 +0000870 return ret;
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800871 }
872 return 0;
Yan, Zheng087bfbb2012-06-15 14:31:34 +0800873}
874
Yan, Zheng14371cc2012-06-15 14:31:36 +0800875/*
876 * add a pci uncore device
877 */
Yan, Zheng899396c2013-08-07 14:17:23 +0800878static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
Yan, Zheng14371cc2012-06-15 14:31:36 +0800879{
880 struct intel_uncore_pmu *pmu;
881 struct intel_uncore_box *box;
Yan, Zheng899396c2013-08-07 14:17:23 +0800882 struct intel_uncore_type *type;
Yan, Zheng513d7932014-09-04 16:08:27 -0700883 bool first_box = false;
Thomas Gleixner4f089672016-02-22 22:19:09 +0000884 int phys_id, ret;
Yan, Zheng14371cc2012-06-15 14:31:36 +0800885
Taku Izumi712df652015-09-24 21:10:21 +0900886 phys_id = uncore_pcibus_to_physid(pdev->bus);
Thomas Gleixner83f8ebd2016-02-22 22:19:10 +0000887 if (phys_id < 0 || phys_id >= UNCORE_SOCKET_MAX)
Yan, Zheng14371cc2012-06-15 14:31:36 +0800888 return -ENODEV;
889
Yan, Zheng899396c2013-08-07 14:17:23 +0800890 if (UNCORE_PCI_DEV_TYPE(id->driver_data) == UNCORE_EXTRA_PCI_DEV) {
Yan, Zheng514b2342014-07-30 15:22:12 +0800891 int idx = UNCORE_PCI_DEV_IDX(id->driver_data);
892 uncore_extra_pci_dev[phys_id][idx] = pdev;
Yan, Zheng899396c2013-08-07 14:17:23 +0800893 pci_set_drvdata(pdev, NULL);
894 return 0;
895 }
896
Yan, Zheng514b2342014-07-30 15:22:12 +0800897 type = uncore_pci_uncores[UNCORE_PCI_DEV_TYPE(id->driver_data)];
Yan, Zheng73c44272013-09-17 14:48:13 +0800898 box = uncore_alloc_box(type, NUMA_NO_NODE);
Yan, Zheng14371cc2012-06-15 14:31:36 +0800899 if (!box)
900 return -ENOMEM;
901
902 /*
903 * for performance monitoring unit with multiple boxes,
904 * each box has a different function id.
905 */
Yan, Zheng899396c2013-08-07 14:17:23 +0800906 pmu = &type->pmus[UNCORE_PCI_DEV_IDX(id->driver_data)];
Harish Chegondi77af0032015-12-07 14:32:32 -0800907 /* Knights Landing uses a common PCI device ID for multiple instances of
908 * an uncore PMU device type. There is only one entry per device type in
909 * the knl_uncore_pci_ids table inspite of multiple devices present for
910 * some device types. Hence PCI device idx would be 0 for all devices.
911 * So increment pmu pointer to point to an unused array element.
912 */
Thomas Gleixner12297352016-02-22 22:19:12 +0000913 if (boot_cpu_data.x86_model == 87) {
Harish Chegondi77af0032015-12-07 14:32:32 -0800914 while (pmu->func_id >= 0)
915 pmu++;
Thomas Gleixner12297352016-02-22 22:19:12 +0000916 }
917
Yan, Zheng899396c2013-08-07 14:17:23 +0800918 if (pmu->func_id < 0)
919 pmu->func_id = pdev->devfn;
920 else
921 WARN_ON_ONCE(pmu->func_id != pdev->devfn);
Yan, Zheng14371cc2012-06-15 14:31:36 +0800922
923 box->phys_id = phys_id;
924 box->pci_dev = pdev;
925 box->pmu = pmu;
Ingo Molnar15c12472015-06-09 11:40:28 +0200926 uncore_box_init(box);
Yan, Zheng14371cc2012-06-15 14:31:36 +0800927 pci_set_drvdata(pdev, box);
928
929 raw_spin_lock(&uncore_box_lock);
Yan, Zheng513d7932014-09-04 16:08:27 -0700930 if (list_empty(&pmu->box_list))
931 first_box = true;
Yan, Zheng14371cc2012-06-15 14:31:36 +0800932 list_add_tail(&box->list, &pmu->box_list);
933 raw_spin_unlock(&uncore_box_lock);
934
Thomas Gleixner4f089672016-02-22 22:19:09 +0000935 if (!first_box)
936 return 0;
937
938 ret = uncore_pmu_register(pmu);
939 if (ret) {
940 pci_set_drvdata(pdev, NULL);
941 raw_spin_lock(&uncore_box_lock);
942 list_del(&box->list);
943 raw_spin_unlock(&uncore_box_lock);
Thomas Gleixnera46195f2016-02-22 22:19:11 +0000944 uncore_box_exit(box);
Thomas Gleixner4f089672016-02-22 22:19:09 +0000945 kfree(box);
946 }
947 return ret;
Yan, Zheng14371cc2012-06-15 14:31:36 +0800948}
949
Robert Richter357398e2012-06-20 18:39:27 +0200950static void uncore_pci_remove(struct pci_dev *pdev)
Yan, Zheng14371cc2012-06-15 14:31:36 +0800951{
952 struct intel_uncore_box *box = pci_get_drvdata(pdev);
Yan, Zheng899396c2013-08-07 14:17:23 +0800953 struct intel_uncore_pmu *pmu;
Taku Izumi712df652015-09-24 21:10:21 +0900954 int i, cpu, phys_id;
Yan, Zheng513d7932014-09-04 16:08:27 -0700955 bool last_box = false;
Yan, Zheng14371cc2012-06-15 14:31:36 +0800956
Taku Izumi712df652015-09-24 21:10:21 +0900957 phys_id = uncore_pcibus_to_physid(pdev->bus);
Yan, Zheng899396c2013-08-07 14:17:23 +0800958 box = pci_get_drvdata(pdev);
959 if (!box) {
960 for (i = 0; i < UNCORE_EXTRA_PCI_DEV_MAX; i++) {
Yan, Zheng514b2342014-07-30 15:22:12 +0800961 if (uncore_extra_pci_dev[phys_id][i] == pdev) {
962 uncore_extra_pci_dev[phys_id][i] = NULL;
Yan, Zheng899396c2013-08-07 14:17:23 +0800963 break;
964 }
965 }
966 WARN_ON_ONCE(i >= UNCORE_EXTRA_PCI_DEV_MAX);
967 return;
968 }
969
970 pmu = box->pmu;
Yan, Zheng14371cc2012-06-15 14:31:36 +0800971 if (WARN_ON_ONCE(phys_id != box->phys_id))
972 return;
973
Yan, Zhenge850f9c2013-04-16 19:51:07 +0800974 pci_set_drvdata(pdev, NULL);
975
Yan, Zheng14371cc2012-06-15 14:31:36 +0800976 raw_spin_lock(&uncore_box_lock);
977 list_del(&box->list);
Yan, Zheng513d7932014-09-04 16:08:27 -0700978 if (list_empty(&pmu->box_list))
979 last_box = true;
Yan, Zheng14371cc2012-06-15 14:31:36 +0800980 raw_spin_unlock(&uncore_box_lock);
981
982 for_each_possible_cpu(cpu) {
983 if (*per_cpu_ptr(pmu->box, cpu) == box) {
984 *per_cpu_ptr(pmu->box, cpu) = NULL;
985 atomic_dec(&box->refcnt);
986 }
987 }
988
989 WARN_ON_ONCE(atomic_read(&box->refcnt) != 1);
Thomas Gleixnera46195f2016-02-22 22:19:11 +0000990 uncore_box_exit(box);
Yan, Zheng14371cc2012-06-15 14:31:36 +0800991 kfree(box);
Yan, Zheng513d7932014-09-04 16:08:27 -0700992
993 if (last_box)
Thomas Gleixner4f089672016-02-22 22:19:09 +0000994 uncore_pmu_unregister(pmu);
Yan, Zheng14371cc2012-06-15 14:31:36 +0800995}
996
Yan, Zheng14371cc2012-06-15 14:31:36 +0800997static int __init uncore_pci_init(void)
998{
999 int ret;
1000
1001 switch (boot_cpu_data.x86_model) {
Yan, Zheng7c94ee22012-06-15 14:31:37 +08001002 case 45: /* Sandy Bridge-EP */
Yan, Zheng8268fdf2014-07-30 15:22:14 +08001003 ret = snbep_uncore_pci_init();
Yan, Zheng7c94ee22012-06-15 14:31:37 +08001004 break;
Peter Zijlstraddcd0972014-08-12 09:15:25 +02001005 case 62: /* Ivy Bridge-EP */
1006 ret = ivbep_uncore_pci_init();
Yan, Zhenge850f9c2013-04-16 19:51:07 +08001007 break;
Yan, Zhenge735b9d2014-09-04 16:08:26 -07001008 case 63: /* Haswell-EP */
1009 ret = hswep_uncore_pci_init();
1010 break;
Kan Liangd6980ef2015-12-03 16:00:11 -05001011 case 79: /* BDX-EP */
Kan Liang070e9882015-07-02 08:12:52 -04001012 case 86: /* BDX-DE */
1013 ret = bdx_uncore_pci_init();
1014 break;
Stephane Eranianb9e1ab62014-02-11 16:20:12 +01001015 case 42: /* Sandy Bridge */
Yan, Zheng92807ffd2014-07-30 15:22:13 +08001016 ret = snb_uncore_pci_init();
Stephane Eranianb9e1ab62014-02-11 16:20:12 +01001017 break;
1018 case 58: /* Ivy Bridge */
Yan, Zheng92807ffd2014-07-30 15:22:13 +08001019 ret = ivb_uncore_pci_init();
Stephane Eranianb9e1ab62014-02-11 16:20:12 +01001020 break;
1021 case 60: /* Haswell */
1022 case 69: /* Haswell Celeron */
Yan, Zheng92807ffd2014-07-30 15:22:13 +08001023 ret = hsw_uncore_pci_init();
Stephane Eranianb9e1ab62014-02-11 16:20:12 +01001024 break;
Stephane Eraniana41f3c82015-04-23 08:56:42 +02001025 case 61: /* Broadwell */
1026 ret = bdw_uncore_pci_init();
1027 break;
Harish Chegondi77af0032015-12-07 14:32:32 -08001028 case 87: /* Knights Landing */
1029 ret = knl_uncore_pci_init();
1030 break;
Stephane Eranian0e1eb0a2016-01-07 08:25:46 +01001031 case 94: /* SkyLake */
1032 ret = skl_uncore_pci_init();
1033 break;
Yan, Zheng14371cc2012-06-15 14:31:36 +08001034 default:
1035 return 0;
1036 }
1037
Yan, Zheng92807ffd2014-07-30 15:22:13 +08001038 if (ret)
1039 return ret;
1040
Yan, Zheng514b2342014-07-30 15:22:12 +08001041 ret = uncore_types_init(uncore_pci_uncores);
Yan, Zheng14371cc2012-06-15 14:31:36 +08001042 if (ret)
Thomas Gleixnerffeda002016-02-22 22:19:09 +00001043 goto err;
Yan, Zheng14371cc2012-06-15 14:31:36 +08001044
1045 uncore_pci_driver->probe = uncore_pci_probe;
1046 uncore_pci_driver->remove = uncore_pci_remove;
1047
1048 ret = pci_register_driver(uncore_pci_driver);
Thomas Gleixnerffeda002016-02-22 22:19:09 +00001049 if (ret)
1050 goto err;
Yan, Zheng14371cc2012-06-15 14:31:36 +08001051
Thomas Gleixnerffeda002016-02-22 22:19:09 +00001052 pcidrv_registered = true;
1053 return 0;
1054
1055err:
1056 uncore_types_exit(uncore_pci_uncores);
1057 uncore_pci_uncores = empty_uncore;
Thomas Gleixner4f089672016-02-22 22:19:09 +00001058 uncore_free_pcibus_map();
Yan, Zheng14371cc2012-06-15 14:31:36 +08001059 return ret;
1060}
1061
1062static void __init uncore_pci_exit(void)
1063{
1064 if (pcidrv_registered) {
1065 pcidrv_registered = false;
1066 pci_unregister_driver(uncore_pci_driver);
Yan, Zheng514b2342014-07-30 15:22:12 +08001067 uncore_types_exit(uncore_pci_uncores);
Thomas Gleixner4f089672016-02-22 22:19:09 +00001068 uncore_free_pcibus_map();
Yan, Zheng14371cc2012-06-15 14:31:36 +08001069 }
1070}
1071
Yan, Zheng22cc4cc2013-04-16 19:51:05 +08001072/* CPU hot plug/unplug are serialized by cpu_add_remove_lock mutex */
1073static LIST_HEAD(boxes_to_free);
1074
Paul Gortmaker148f9bb2013-06-18 18:23:59 -04001075static void uncore_kfree_boxes(void)
Yan, Zheng22cc4cc2013-04-16 19:51:05 +08001076{
1077 struct intel_uncore_box *box;
1078
1079 while (!list_empty(&boxes_to_free)) {
1080 box = list_entry(boxes_to_free.next,
1081 struct intel_uncore_box, list);
1082 list_del(&box->list);
1083 kfree(box);
1084 }
1085}
1086
Paul Gortmaker148f9bb2013-06-18 18:23:59 -04001087static void uncore_cpu_dying(int cpu)
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001088{
1089 struct intel_uncore_type *type;
1090 struct intel_uncore_pmu *pmu;
1091 struct intel_uncore_box *box;
1092 int i, j;
1093
Yan, Zheng514b2342014-07-30 15:22:12 +08001094 for (i = 0; uncore_msr_uncores[i]; i++) {
1095 type = uncore_msr_uncores[i];
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001096 for (j = 0; j < type->num_boxes; j++) {
1097 pmu = &type->pmus[j];
1098 box = *per_cpu_ptr(pmu->box, cpu);
1099 *per_cpu_ptr(pmu->box, cpu) = NULL;
Thomas Gleixnera46195f2016-02-22 22:19:11 +00001100 if (box && atomic_dec_and_test(&box->refcnt)) {
Yan, Zheng22cc4cc2013-04-16 19:51:05 +08001101 list_add(&box->list, &boxes_to_free);
Thomas Gleixnera46195f2016-02-22 22:19:11 +00001102 uncore_box_exit(box);
1103 }
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001104 }
1105 }
1106}
1107
Paul Gortmaker148f9bb2013-06-18 18:23:59 -04001108static int uncore_cpu_starting(int cpu)
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001109{
1110 struct intel_uncore_type *type;
1111 struct intel_uncore_pmu *pmu;
1112 struct intel_uncore_box *box, *exist;
1113 int i, j, k, phys_id;
1114
1115 phys_id = topology_physical_package_id(cpu);
1116
Yan, Zheng514b2342014-07-30 15:22:12 +08001117 for (i = 0; uncore_msr_uncores[i]; i++) {
1118 type = uncore_msr_uncores[i];
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001119 for (j = 0; j < type->num_boxes; j++) {
1120 pmu = &type->pmus[j];
1121 box = *per_cpu_ptr(pmu->box, cpu);
1122 /* called by uncore_cpu_init? */
Ingo Molnar15c12472015-06-09 11:40:28 +02001123 if (box && box->phys_id >= 0) {
1124 uncore_box_init(box);
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001125 continue;
Ingo Molnar15c12472015-06-09 11:40:28 +02001126 }
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001127
1128 for_each_online_cpu(k) {
1129 exist = *per_cpu_ptr(pmu->box, k);
1130 if (exist && exist->phys_id == phys_id) {
1131 atomic_inc(&exist->refcnt);
1132 *per_cpu_ptr(pmu->box, cpu) = exist;
Yan, Zheng22cc4cc2013-04-16 19:51:05 +08001133 if (box) {
1134 list_add(&box->list,
1135 &boxes_to_free);
1136 box = NULL;
1137 }
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001138 break;
1139 }
1140 }
1141
Ingo Molnar15c12472015-06-09 11:40:28 +02001142 if (box) {
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001143 box->phys_id = phys_id;
Ingo Molnar15c12472015-06-09 11:40:28 +02001144 uncore_box_init(box);
1145 }
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001146 }
1147 }
1148 return 0;
1149}
1150
Paul Gortmaker148f9bb2013-06-18 18:23:59 -04001151static int uncore_cpu_prepare(int cpu, int phys_id)
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001152{
1153 struct intel_uncore_type *type;
1154 struct intel_uncore_pmu *pmu;
1155 struct intel_uncore_box *box;
1156 int i, j;
1157
Yan, Zheng514b2342014-07-30 15:22:12 +08001158 for (i = 0; uncore_msr_uncores[i]; i++) {
1159 type = uncore_msr_uncores[i];
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001160 for (j = 0; j < type->num_boxes; j++) {
1161 pmu = &type->pmus[j];
1162 if (pmu->func_id < 0)
1163 pmu->func_id = j;
1164
Yan, Zheng73c44272013-09-17 14:48:13 +08001165 box = uncore_alloc_box(type, cpu_to_node(cpu));
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001166 if (!box)
1167 return -ENOMEM;
1168
1169 box->pmu = pmu;
1170 box->phys_id = phys_id;
1171 *per_cpu_ptr(pmu->box, cpu) = box;
1172 }
1173 }
1174 return 0;
1175}
1176
Thomas Gleixner12297352016-02-22 22:19:12 +00001177static void uncore_change_type_ctx(struct intel_uncore_type *type, int old_cpu,
1178 int new_cpu)
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001179{
Thomas Gleixner12297352016-02-22 22:19:12 +00001180 struct intel_uncore_pmu *pmu = type->pmus;
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001181 struct intel_uncore_box *box;
Thomas Gleixner12297352016-02-22 22:19:12 +00001182 int i;
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001183
Thomas Gleixner12297352016-02-22 22:19:12 +00001184 for (i = 0; i < type->num_boxes; i++, pmu++) {
1185 if (old_cpu < 0)
1186 box = uncore_pmu_to_box(pmu, new_cpu);
1187 else
1188 box = uncore_pmu_to_box(pmu, old_cpu);
1189 if (!box)
1190 continue;
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001191
Thomas Gleixner12297352016-02-22 22:19:12 +00001192 if (old_cpu < 0) {
1193 WARN_ON_ONCE(box->cpu != -1);
1194 box->cpu = new_cpu;
1195 continue;
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001196 }
Thomas Gleixner12297352016-02-22 22:19:12 +00001197
1198 WARN_ON_ONCE(box->cpu != old_cpu);
1199 box->cpu = -1;
1200 if (new_cpu < 0)
1201 continue;
1202
1203 uncore_pmu_cancel_hrtimer(box);
1204 perf_pmu_migrate_context(&pmu->pmu, old_cpu, new_cpu);
1205 box->cpu = new_cpu;
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001206 }
1207}
1208
Thomas Gleixner12297352016-02-22 22:19:12 +00001209static void uncore_change_context(struct intel_uncore_type **uncores,
1210 int old_cpu, int new_cpu)
1211{
1212 for (; *uncores; uncores++)
1213 uncore_change_type_ctx(*uncores, old_cpu, new_cpu);
1214}
1215
Paul Gortmaker148f9bb2013-06-18 18:23:59 -04001216static void uncore_event_exit_cpu(int cpu)
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001217{
1218 int i, phys_id, target;
1219
1220 /* if exiting cpu is used for collecting uncore events */
1221 if (!cpumask_test_and_clear_cpu(cpu, &uncore_cpu_mask))
1222 return;
1223
1224 /* find a new cpu to collect uncore events */
1225 phys_id = topology_physical_package_id(cpu);
1226 target = -1;
1227 for_each_online_cpu(i) {
1228 if (i == cpu)
1229 continue;
1230 if (phys_id == topology_physical_package_id(i)) {
1231 target = i;
1232 break;
1233 }
1234 }
1235
1236 /* migrate uncore events to the new cpu */
1237 if (target >= 0)
1238 cpumask_set_cpu(target, &uncore_cpu_mask);
1239
Yan, Zheng514b2342014-07-30 15:22:12 +08001240 uncore_change_context(uncore_msr_uncores, cpu, target);
1241 uncore_change_context(uncore_pci_uncores, cpu, target);
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001242}
1243
Paul Gortmaker148f9bb2013-06-18 18:23:59 -04001244static void uncore_event_init_cpu(int cpu)
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001245{
1246 int i, phys_id;
1247
1248 phys_id = topology_physical_package_id(cpu);
1249 for_each_cpu(i, &uncore_cpu_mask) {
1250 if (phys_id == topology_physical_package_id(i))
1251 return;
1252 }
1253
1254 cpumask_set_cpu(cpu, &uncore_cpu_mask);
1255
Yan, Zheng514b2342014-07-30 15:22:12 +08001256 uncore_change_context(uncore_msr_uncores, -1, cpu);
1257 uncore_change_context(uncore_pci_uncores, -1, cpu);
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001258}
1259
Paul Gortmaker148f9bb2013-06-18 18:23:59 -04001260static int uncore_cpu_notifier(struct notifier_block *self,
1261 unsigned long action, void *hcpu)
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001262{
1263 unsigned int cpu = (long)hcpu;
1264
1265 /* allocate/free data structure for uncore box */
1266 switch (action & ~CPU_TASKS_FROZEN) {
1267 case CPU_UP_PREPARE:
Thomas Gleixner4f089672016-02-22 22:19:09 +00001268 return notifier_from_errno(uncore_cpu_prepare(cpu, -1));
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001269 case CPU_STARTING:
1270 uncore_cpu_starting(cpu);
1271 break;
1272 case CPU_UP_CANCELED:
1273 case CPU_DYING:
1274 uncore_cpu_dying(cpu);
1275 break;
Yan, Zheng22cc4cc2013-04-16 19:51:05 +08001276 case CPU_ONLINE:
1277 case CPU_DEAD:
1278 uncore_kfree_boxes();
1279 break;
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001280 default:
1281 break;
1282 }
1283
1284 /* select the cpu that collects uncore events */
1285 switch (action & ~CPU_TASKS_FROZEN) {
1286 case CPU_DOWN_FAILED:
1287 case CPU_STARTING:
1288 uncore_event_init_cpu(cpu);
1289 break;
1290 case CPU_DOWN_PREPARE:
1291 uncore_event_exit_cpu(cpu);
1292 break;
1293 default:
1294 break;
1295 }
1296
1297 return NOTIFY_OK;
1298}
1299
Paul Gortmaker148f9bb2013-06-18 18:23:59 -04001300static struct notifier_block uncore_cpu_nb = {
Yan, Zheng254298c2012-07-05 14:32:17 +08001301 .notifier_call = uncore_cpu_notifier,
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001302 /*
1303 * to migrate uncore events, our notifier should be executed
1304 * before perf core's notifier.
1305 */
Yan, Zheng254298c2012-07-05 14:32:17 +08001306 .priority = CPU_PRI_PERF + 1,
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001307};
1308
Thomas Gleixner4f089672016-02-22 22:19:09 +00001309static int __init type_pmu_register(struct intel_uncore_type *type)
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001310{
Thomas Gleixner4f089672016-02-22 22:19:09 +00001311 int i, ret;
1312
1313 for (i = 0; i < type->num_boxes; i++) {
1314 ret = uncore_pmu_register(&type->pmus[i]);
1315 if (ret)
1316 return ret;
1317 }
1318 return 0;
1319}
1320
1321static int __init uncore_msr_pmus_register(void)
1322{
1323 struct intel_uncore_type **types = uncore_msr_uncores;
1324 int ret;
1325
Thomas Gleixner12297352016-02-22 22:19:12 +00001326 for (; *types; types++) {
1327 ret = type_pmu_register(*types);
Thomas Gleixner4f089672016-02-22 22:19:09 +00001328 if (ret)
1329 return ret;
1330 }
1331 return 0;
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001332}
1333
1334static int __init uncore_cpu_init(void)
1335{
Yan, Zhengc1e46582014-07-30 15:22:15 +08001336 int ret;
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001337
1338 switch (boot_cpu_data.x86_model) {
Yan, Zhengfcde10e2012-06-15 14:31:35 +08001339 case 26: /* Nehalem */
1340 case 30:
1341 case 37: /* Westmere */
1342 case 44:
Yan, Zheng92807ffd2014-07-30 15:22:13 +08001343 nhm_uncore_cpu_init();
Yan, Zhengfcde10e2012-06-15 14:31:35 +08001344 break;
1345 case 42: /* Sandy Bridge */
Vince Weaver9a6bc1432013-04-29 15:52:27 -04001346 case 58: /* Ivy Bridge */
Andi Kleen3a999582015-06-14 22:57:41 -07001347 case 60: /* Haswell */
1348 case 69: /* Haswell */
1349 case 70: /* Haswell */
1350 case 61: /* Broadwell */
1351 case 71: /* Broadwell */
Yan, Zheng92807ffd2014-07-30 15:22:13 +08001352 snb_uncore_cpu_init();
Yan, Zhengfcde10e2012-06-15 14:31:35 +08001353 break;
Vince Weaver80e217e2013-04-29 15:49:28 -04001354 case 45: /* Sandy Bridge-EP */
Yan, Zheng8268fdf2014-07-30 15:22:14 +08001355 snbep_uncore_cpu_init();
Yan, Zheng7c94ee22012-06-15 14:31:37 +08001356 break;
Yan, Zhengcb37af72012-08-06 13:11:22 +08001357 case 46: /* Nehalem-EX */
Yan, Zhengcb37af72012-08-06 13:11:22 +08001358 case 47: /* Westmere-EX aka. Xeon E7 */
Yan, Zhengc1e46582014-07-30 15:22:15 +08001359 nhmex_uncore_cpu_init();
Yan, Zheng254298c2012-07-05 14:32:17 +08001360 break;
Peter Zijlstraddcd0972014-08-12 09:15:25 +02001361 case 62: /* Ivy Bridge-EP */
1362 ivbep_uncore_cpu_init();
Yan, Zhenge850f9c2013-04-16 19:51:07 +08001363 break;
Yan, Zhenge735b9d2014-09-04 16:08:26 -07001364 case 63: /* Haswell-EP */
1365 hswep_uncore_cpu_init();
1366 break;
Kan Liangd6980ef2015-12-03 16:00:11 -05001367 case 79: /* BDX-EP */
Kan Liang070e9882015-07-02 08:12:52 -04001368 case 86: /* BDX-DE */
1369 bdx_uncore_cpu_init();
1370 break;
Harish Chegondi77af0032015-12-07 14:32:32 -08001371 case 87: /* Knights Landing */
1372 knl_uncore_cpu_init();
1373 break;
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001374 default:
1375 return 0;
1376 }
1377
Yan, Zheng514b2342014-07-30 15:22:12 +08001378 ret = uncore_types_init(uncore_msr_uncores);
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001379 if (ret)
Thomas Gleixnerffeda002016-02-22 22:19:09 +00001380 goto err;
Thomas Gleixner4f089672016-02-22 22:19:09 +00001381
1382 ret = uncore_msr_pmus_register();
1383 if (ret)
1384 goto err;
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001385 return 0;
Thomas Gleixnerffeda002016-02-22 22:19:09 +00001386err:
1387 uncore_types_exit(uncore_msr_uncores);
1388 uncore_msr_uncores = empty_uncore;
1389 return ret;
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001390}
1391
Thomas Gleixner4f089672016-02-22 22:19:09 +00001392static void __init uncore_cpu_setup(void *dummy)
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001393{
Thomas Gleixner4f089672016-02-22 22:19:09 +00001394 uncore_cpu_starting(smp_processor_id());
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001395}
1396
Thomas Gleixner4f089672016-02-22 22:19:09 +00001397static int __init uncore_cpumask_init(void)
Stephane Eranian411cf182014-02-11 16:20:07 +01001398{
Thomas Gleixner4f089672016-02-22 22:19:09 +00001399 int cpu, ret = 0;
Stephane Eranian411cf182014-02-11 16:20:07 +01001400
Linus Torvalds467a9e12014-04-07 14:55:46 -07001401 cpu_notifier_register_begin();
Stephane Eranian411cf182014-02-11 16:20:07 +01001402
1403 for_each_online_cpu(cpu) {
1404 int i, phys_id = topology_physical_package_id(cpu);
1405
1406 for_each_cpu(i, &uncore_cpu_mask) {
1407 if (phys_id == topology_physical_package_id(i)) {
1408 phys_id = -1;
1409 break;
1410 }
1411 }
1412 if (phys_id < 0)
1413 continue;
1414
Thomas Gleixner4f089672016-02-22 22:19:09 +00001415 ret = uncore_cpu_prepare(cpu, phys_id);
1416 if (ret)
1417 goto out;
Stephane Eranian411cf182014-02-11 16:20:07 +01001418 uncore_event_init_cpu(cpu);
1419 }
1420 on_each_cpu(uncore_cpu_setup, NULL, 1);
1421
Linus Torvalds467a9e12014-04-07 14:55:46 -07001422 __register_cpu_notifier(&uncore_cpu_nb);
Stephane Eranian411cf182014-02-11 16:20:07 +01001423
Thomas Gleixner4f089672016-02-22 22:19:09 +00001424out:
Linus Torvalds467a9e12014-04-07 14:55:46 -07001425 cpu_notifier_register_done();
Thomas Gleixner4f089672016-02-22 22:19:09 +00001426 return ret;
Stephane Eranian411cf182014-02-11 16:20:07 +01001427}
1428
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001429static int __init intel_uncore_init(void)
1430{
1431 int ret;
1432
1433 if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
1434 return -ENODEV;
1435
Yan, Zhenga05123b2012-08-21 17:08:37 +08001436 if (cpu_has_hypervisor)
1437 return -ENODEV;
1438
Yan, Zheng14371cc2012-06-15 14:31:36 +08001439 ret = uncore_pci_init();
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001440 if (ret)
Thomas Gleixner4f089672016-02-22 22:19:09 +00001441 return ret;
Yan, Zheng14371cc2012-06-15 14:31:36 +08001442 ret = uncore_cpu_init();
Thomas Gleixner4f089672016-02-22 22:19:09 +00001443 if (ret)
1444 goto errpci;
1445 ret = uncore_cpumask_init();
1446 if (ret)
1447 goto errcpu;
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001448
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001449 return 0;
Thomas Gleixner4f089672016-02-22 22:19:09 +00001450
1451errcpu:
1452 uncore_types_exit(uncore_msr_uncores);
1453errpci:
1454 uncore_pci_exit();
Yan, Zheng087bfbb2012-06-15 14:31:34 +08001455 return ret;
1456}
1457device_initcall(intel_uncore_init);