0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/of.h>
0010 #include <linux/perf_event.h>
0011 #include <linux/slab.h>
0012 #include <asm/opal.h>
0013 #include <asm/imc-pmu.h>
0014 #include <asm/cputhreads.h>
0015 #include <asm/smp.h>
0016 #include <linux/string.h>
0017
0018
0019
0020
0021
0022
0023
0024 static DEFINE_MUTEX(nest_init_lock);
0025 static DEFINE_PER_CPU(struct imc_pmu_ref *, local_nest_imc_refc);
0026 static struct imc_pmu **per_nest_pmu_arr;
0027 static cpumask_t nest_imc_cpumask;
0028 static struct imc_pmu_ref *nest_imc_refc;
0029 static int nest_pmus;
0030
0031
0032
0033 static cpumask_t core_imc_cpumask;
0034 static struct imc_pmu_ref *core_imc_refc;
0035 static struct imc_pmu *core_imc_pmu;
0036
0037
0038
0039 static DEFINE_PER_CPU(u64 *, thread_imc_mem);
0040 static struct imc_pmu *thread_imc_pmu;
0041 static int thread_imc_mem_size;
0042
0043
0044 static DEFINE_PER_CPU(u64 *, trace_imc_mem);
0045 static struct imc_pmu_ref *trace_imc_refc;
0046 static int trace_imc_mem_size;
0047
0048
0049
0050
0051
0052 static struct imc_pmu_ref imc_global_refc = {
0053 .lock = __MUTEX_INITIALIZER(imc_global_refc.lock),
0054 .id = 0,
0055 .refc = 0,
0056 };
0057
0058 static struct imc_pmu *imc_event_to_pmu(struct perf_event *event)
0059 {
0060 return container_of(event->pmu, struct imc_pmu, pmu);
0061 }
0062
0063 PMU_FORMAT_ATTR(event, "config:0-61");
0064 PMU_FORMAT_ATTR(offset, "config:0-31");
0065 PMU_FORMAT_ATTR(rvalue, "config:32");
0066 PMU_FORMAT_ATTR(mode, "config:33-40");
0067 static struct attribute *imc_format_attrs[] = {
0068 &format_attr_event.attr,
0069 &format_attr_offset.attr,
0070 &format_attr_rvalue.attr,
0071 &format_attr_mode.attr,
0072 NULL,
0073 };
0074
0075 static const struct attribute_group imc_format_group = {
0076 .name = "format",
0077 .attrs = imc_format_attrs,
0078 };
0079
0080
0081 PMU_FORMAT_ATTR(cpmc_reserved, "config:0-19");
0082 PMU_FORMAT_ATTR(cpmc_event, "config:20-27");
0083 PMU_FORMAT_ATTR(cpmc_samplesel, "config:28-29");
0084 PMU_FORMAT_ATTR(cpmc_load, "config:30-61");
0085 static struct attribute *trace_imc_format_attrs[] = {
0086 &format_attr_event.attr,
0087 &format_attr_cpmc_reserved.attr,
0088 &format_attr_cpmc_event.attr,
0089 &format_attr_cpmc_samplesel.attr,
0090 &format_attr_cpmc_load.attr,
0091 NULL,
0092 };
0093
0094 static const struct attribute_group trace_imc_format_group = {
0095 .name = "format",
0096 .attrs = trace_imc_format_attrs,
0097 };
0098
0099
0100 static ssize_t imc_pmu_cpumask_get_attr(struct device *dev,
0101 struct device_attribute *attr,
0102 char *buf)
0103 {
0104 struct pmu *pmu = dev_get_drvdata(dev);
0105 struct imc_pmu *imc_pmu = container_of(pmu, struct imc_pmu, pmu);
0106 cpumask_t *active_mask;
0107
0108 switch(imc_pmu->domain){
0109 case IMC_DOMAIN_NEST:
0110 active_mask = &nest_imc_cpumask;
0111 break;
0112 case IMC_DOMAIN_CORE:
0113 active_mask = &core_imc_cpumask;
0114 break;
0115 default:
0116 return 0;
0117 }
0118
0119 return cpumap_print_to_pagebuf(true, buf, active_mask);
0120 }
0121
0122 static DEVICE_ATTR(cpumask, S_IRUGO, imc_pmu_cpumask_get_attr, NULL);
0123
0124 static struct attribute *imc_pmu_cpumask_attrs[] = {
0125 &dev_attr_cpumask.attr,
0126 NULL,
0127 };
0128
0129 static const struct attribute_group imc_pmu_cpumask_attr_group = {
0130 .attrs = imc_pmu_cpumask_attrs,
0131 };
0132
0133
0134 static struct attribute *device_str_attr_create(const char *name, const char *str)
0135 {
0136 struct perf_pmu_events_attr *attr;
0137
0138 attr = kzalloc(sizeof(*attr), GFP_KERNEL);
0139 if (!attr)
0140 return NULL;
0141 sysfs_attr_init(&attr->attr.attr);
0142
0143 attr->event_str = str;
0144 attr->attr.attr.name = name;
0145 attr->attr.attr.mode = 0444;
0146 attr->attr.show = perf_event_sysfs_show;
0147
0148 return &attr->attr.attr;
0149 }
0150
0151 static int imc_parse_event(struct device_node *np, const char *scale,
0152 const char *unit, const char *prefix,
0153 u32 base, struct imc_events *event)
0154 {
0155 const char *s;
0156 u32 reg;
0157
0158 if (of_property_read_u32(np, "reg", ®))
0159 goto error;
0160
0161 event->value = base + reg;
0162
0163 if (of_property_read_string(np, "event-name", &s))
0164 goto error;
0165
0166 event->name = kasprintf(GFP_KERNEL, "%s%s", prefix, s);
0167 if (!event->name)
0168 goto error;
0169
0170 if (of_property_read_string(np, "scale", &s))
0171 s = scale;
0172
0173 if (s) {
0174 event->scale = kstrdup(s, GFP_KERNEL);
0175 if (!event->scale)
0176 goto error;
0177 }
0178
0179 if (of_property_read_string(np, "unit", &s))
0180 s = unit;
0181
0182 if (s) {
0183 event->unit = kstrdup(s, GFP_KERNEL);
0184 if (!event->unit)
0185 goto error;
0186 }
0187
0188 return 0;
0189 error:
0190 kfree(event->unit);
0191 kfree(event->scale);
0192 kfree(event->name);
0193 return -EINVAL;
0194 }
0195
0196
0197
0198
0199
0200 static void imc_free_events(struct imc_events *events, int nr_entries)
0201 {
0202 int i;
0203
0204
0205 if (!events)
0206 return;
0207 for (i = 0; i < nr_entries; i++) {
0208 kfree(events[i].unit);
0209 kfree(events[i].scale);
0210 kfree(events[i].name);
0211 }
0212
0213 kfree(events);
0214 }
0215
0216
0217
0218
0219
0220 static int update_events_in_group(struct device_node *node, struct imc_pmu *pmu)
0221 {
0222 struct attribute_group *attr_group;
0223 struct attribute **attrs, *dev_str;
0224 struct device_node *np, *pmu_events;
0225 u32 handle, base_reg;
0226 int i = 0, j = 0, ct, ret;
0227 const char *prefix, *g_scale, *g_unit;
0228 const char *ev_val_str, *ev_scale_str, *ev_unit_str;
0229
0230 if (!of_property_read_u32(node, "events", &handle))
0231 pmu_events = of_find_node_by_phandle(handle);
0232 else
0233 return 0;
0234
0235
0236 if (!pmu_events)
0237 return 0;
0238
0239
0240 ct = of_get_child_count(pmu_events);
0241
0242
0243 if (of_property_read_string(node, "events-prefix", &prefix))
0244 return 0;
0245
0246
0247 if (of_property_read_string(node, "scale", &g_scale))
0248 g_scale = NULL;
0249
0250 if (of_property_read_string(node, "unit", &g_unit))
0251 g_unit = NULL;
0252
0253
0254 of_property_read_u32(node, "reg", &base_reg);
0255
0256
0257 pmu->events = kcalloc(ct, sizeof(struct imc_events), GFP_KERNEL);
0258 if (!pmu->events)
0259 return -ENOMEM;
0260
0261 ct = 0;
0262
0263 for_each_child_of_node(pmu_events, np) {
0264 ret = imc_parse_event(np, g_scale, g_unit, prefix, base_reg, &pmu->events[ct]);
0265 if (!ret)
0266 ct++;
0267 }
0268
0269
0270 attr_group = kzalloc(sizeof(*attr_group), GFP_KERNEL);
0271 if (!attr_group) {
0272 imc_free_events(pmu->events, ct);
0273 return -ENOMEM;
0274 }
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284 attrs = kcalloc(((ct * 3) + 1), sizeof(struct attribute *), GFP_KERNEL);
0285 if (!attrs) {
0286 kfree(attr_group);
0287 imc_free_events(pmu->events, ct);
0288 return -ENOMEM;
0289 }
0290
0291 attr_group->name = "events";
0292 attr_group->attrs = attrs;
0293 do {
0294 ev_val_str = kasprintf(GFP_KERNEL, "event=0x%x", pmu->events[i].value);
0295 dev_str = device_str_attr_create(pmu->events[i].name, ev_val_str);
0296 if (!dev_str)
0297 continue;
0298
0299 attrs[j++] = dev_str;
0300 if (pmu->events[i].scale) {
0301 ev_scale_str = kasprintf(GFP_KERNEL, "%s.scale", pmu->events[i].name);
0302 dev_str = device_str_attr_create(ev_scale_str, pmu->events[i].scale);
0303 if (!dev_str)
0304 continue;
0305
0306 attrs[j++] = dev_str;
0307 }
0308
0309 if (pmu->events[i].unit) {
0310 ev_unit_str = kasprintf(GFP_KERNEL, "%s.unit", pmu->events[i].name);
0311 dev_str = device_str_attr_create(ev_unit_str, pmu->events[i].unit);
0312 if (!dev_str)
0313 continue;
0314
0315 attrs[j++] = dev_str;
0316 }
0317 } while (++i < ct);
0318
0319
0320 pmu->attr_groups[IMC_EVENT_ATTR] = attr_group;
0321
0322 return 0;
0323 }
0324
0325
0326 static struct imc_pmu_ref *get_nest_pmu_ref(int cpu)
0327 {
0328 return per_cpu(local_nest_imc_refc, cpu);
0329 }
0330
0331 static void nest_change_cpu_context(int old_cpu, int new_cpu)
0332 {
0333 struct imc_pmu **pn = per_nest_pmu_arr;
0334
0335 if (old_cpu < 0 || new_cpu < 0)
0336 return;
0337
0338 while (*pn) {
0339 perf_pmu_migrate_context(&(*pn)->pmu, old_cpu, new_cpu);
0340 pn++;
0341 }
0342 }
0343
0344 static int ppc_nest_imc_cpu_offline(unsigned int cpu)
0345 {
0346 int nid, target = -1;
0347 const struct cpumask *l_cpumask;
0348 struct imc_pmu_ref *ref;
0349
0350
0351
0352
0353
0354 if (!cpumask_test_and_clear_cpu(cpu, &nest_imc_cpumask))
0355 return 0;
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367 if (!nest_pmus)
0368 return 0;
0369
0370
0371
0372
0373
0374 nid = cpu_to_node(cpu);
0375 l_cpumask = cpumask_of_node(nid);
0376 target = cpumask_last(l_cpumask);
0377
0378
0379
0380
0381
0382 if (unlikely(target == cpu))
0383 target = cpumask_any_but(l_cpumask, cpu);
0384
0385
0386
0387
0388
0389 if (target >= 0 && target < nr_cpu_ids) {
0390 cpumask_set_cpu(target, &nest_imc_cpumask);
0391 nest_change_cpu_context(cpu, target);
0392 } else {
0393 opal_imc_counters_stop(OPAL_IMC_COUNTERS_NEST,
0394 get_hard_smp_processor_id(cpu));
0395
0396
0397
0398
0399 ref = get_nest_pmu_ref(cpu);
0400 if (!ref)
0401 return -EINVAL;
0402
0403 ref->refc = 0;
0404 }
0405 return 0;
0406 }
0407
0408 static int ppc_nest_imc_cpu_online(unsigned int cpu)
0409 {
0410 const struct cpumask *l_cpumask;
0411 static struct cpumask tmp_mask;
0412 int res;
0413
0414
0415 l_cpumask = cpumask_of_node(cpu_to_node(cpu));
0416
0417
0418
0419
0420
0421 if (cpumask_and(&tmp_mask, l_cpumask, &nest_imc_cpumask))
0422 return 0;
0423
0424
0425
0426
0427
0428 res = opal_imc_counters_stop(OPAL_IMC_COUNTERS_NEST,
0429 get_hard_smp_processor_id(cpu));
0430 if (res)
0431 return res;
0432
0433
0434 cpumask_set_cpu(cpu, &nest_imc_cpumask);
0435 return 0;
0436 }
0437
0438 static int nest_pmu_cpumask_init(void)
0439 {
0440 return cpuhp_setup_state(CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE,
0441 "perf/powerpc/imc:online",
0442 ppc_nest_imc_cpu_online,
0443 ppc_nest_imc_cpu_offline);
0444 }
0445
0446 static void nest_imc_counters_release(struct perf_event *event)
0447 {
0448 int rc, node_id;
0449 struct imc_pmu_ref *ref;
0450
0451 if (event->cpu < 0)
0452 return;
0453
0454 node_id = cpu_to_node(event->cpu);
0455
0456
0457
0458
0459
0460
0461
0462 ref = get_nest_pmu_ref(event->cpu);
0463 if (!ref)
0464 return;
0465
0466
0467 mutex_lock(&ref->lock);
0468 if (ref->refc == 0) {
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479 mutex_unlock(&ref->lock);
0480 return;
0481 }
0482 ref->refc--;
0483 if (ref->refc == 0) {
0484 rc = opal_imc_counters_stop(OPAL_IMC_COUNTERS_NEST,
0485 get_hard_smp_processor_id(event->cpu));
0486 if (rc) {
0487 mutex_unlock(&ref->lock);
0488 pr_err("nest-imc: Unable to stop the counters for core %d\n", node_id);
0489 return;
0490 }
0491 } else if (ref->refc < 0) {
0492 WARN(1, "nest-imc: Invalid event reference count\n");
0493 ref->refc = 0;
0494 }
0495 mutex_unlock(&ref->lock);
0496 }
0497
0498 static int nest_imc_event_init(struct perf_event *event)
0499 {
0500 int chip_id, rc, node_id;
0501 u32 l_config, config = event->attr.config;
0502 struct imc_mem_info *pcni;
0503 struct imc_pmu *pmu;
0504 struct imc_pmu_ref *ref;
0505 bool flag = false;
0506
0507 if (event->attr.type != event->pmu->type)
0508 return -ENOENT;
0509
0510
0511 if (event->hw.sample_period)
0512 return -EINVAL;
0513
0514 if (event->cpu < 0)
0515 return -EINVAL;
0516
0517 pmu = imc_event_to_pmu(event);
0518
0519
0520 if ((config & IMC_EVENT_OFFSET_MASK) > pmu->counter_mem_size)
0521 return -EINVAL;
0522
0523
0524
0525
0526
0527 chip_id = cpu_to_chip_id(event->cpu);
0528
0529
0530 if (chip_id < 0)
0531 return -ENODEV;
0532
0533 pcni = pmu->mem_info;
0534 do {
0535 if (pcni->id == chip_id) {
0536 flag = true;
0537 break;
0538 }
0539 pcni++;
0540 } while (pcni->vbase != 0);
0541
0542 if (!flag)
0543 return -ENODEV;
0544
0545
0546
0547
0548 l_config = config & IMC_EVENT_OFFSET_MASK;
0549 event->hw.event_base = (u64)pcni->vbase + l_config;
0550 node_id = cpu_to_node(event->cpu);
0551
0552
0553
0554
0555
0556
0557 ref = get_nest_pmu_ref(event->cpu);
0558 if (!ref)
0559 return -EINVAL;
0560
0561 mutex_lock(&ref->lock);
0562 if (ref->refc == 0) {
0563 rc = opal_imc_counters_start(OPAL_IMC_COUNTERS_NEST,
0564 get_hard_smp_processor_id(event->cpu));
0565 if (rc) {
0566 mutex_unlock(&ref->lock);
0567 pr_err("nest-imc: Unable to start the counters for node %d\n",
0568 node_id);
0569 return rc;
0570 }
0571 }
0572 ++ref->refc;
0573 mutex_unlock(&ref->lock);
0574
0575 event->destroy = nest_imc_counters_release;
0576 return 0;
0577 }
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587 static int core_imc_mem_init(int cpu, int size)
0588 {
0589 int nid, rc = 0, core_id = (cpu / threads_per_core);
0590 struct imc_mem_info *mem_info;
0591 struct page *page;
0592
0593
0594
0595
0596
0597 nid = cpu_to_node(cpu);
0598 mem_info = &core_imc_pmu->mem_info[core_id];
0599 mem_info->id = core_id;
0600
0601
0602 page = alloc_pages_node(nid,
0603 GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE |
0604 __GFP_NOWARN, get_order(size));
0605 if (!page)
0606 return -ENOMEM;
0607 mem_info->vbase = page_address(page);
0608
0609
0610 core_imc_refc[core_id].id = core_id;
0611 mutex_init(&core_imc_refc[core_id].lock);
0612
0613 rc = opal_imc_counters_init(OPAL_IMC_COUNTERS_CORE,
0614 __pa((void *)mem_info->vbase),
0615 get_hard_smp_processor_id(cpu));
0616 if (rc) {
0617 free_pages((u64)mem_info->vbase, get_order(size));
0618 mem_info->vbase = NULL;
0619 }
0620
0621 return rc;
0622 }
0623
0624 static bool is_core_imc_mem_inited(int cpu)
0625 {
0626 struct imc_mem_info *mem_info;
0627 int core_id = (cpu / threads_per_core);
0628
0629 mem_info = &core_imc_pmu->mem_info[core_id];
0630 if (!mem_info->vbase)
0631 return false;
0632
0633 return true;
0634 }
0635
0636 static int ppc_core_imc_cpu_online(unsigned int cpu)
0637 {
0638 const struct cpumask *l_cpumask;
0639 static struct cpumask tmp_mask;
0640 int ret = 0;
0641
0642
0643 l_cpumask = cpu_sibling_mask(cpu);
0644
0645
0646 if (cpumask_and(&tmp_mask, l_cpumask, &core_imc_cpumask))
0647 return 0;
0648
0649 if (!is_core_imc_mem_inited(cpu)) {
0650 ret = core_imc_mem_init(cpu, core_imc_pmu->counter_mem_size);
0651 if (ret) {
0652 pr_info("core_imc memory allocation for cpu %d failed\n", cpu);
0653 return ret;
0654 }
0655 }
0656
0657
0658 cpumask_set_cpu(cpu, &core_imc_cpumask);
0659 return 0;
0660 }
0661
0662 static int ppc_core_imc_cpu_offline(unsigned int cpu)
0663 {
0664 unsigned int core_id;
0665 int ncpu;
0666 struct imc_pmu_ref *ref;
0667
0668
0669
0670
0671
0672 if (!cpumask_test_and_clear_cpu(cpu, &core_imc_cpumask))
0673 return 0;
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686 if (!core_imc_pmu->pmu.event_init)
0687 return 0;
0688
0689
0690 ncpu = cpumask_last(cpu_sibling_mask(cpu));
0691
0692 if (unlikely(ncpu == cpu))
0693 ncpu = cpumask_any_but(cpu_sibling_mask(cpu), cpu);
0694
0695 if (ncpu >= 0 && ncpu < nr_cpu_ids) {
0696 cpumask_set_cpu(ncpu, &core_imc_cpumask);
0697 perf_pmu_migrate_context(&core_imc_pmu->pmu, cpu, ncpu);
0698 } else {
0699
0700
0701
0702
0703
0704 opal_imc_counters_stop(OPAL_IMC_COUNTERS_CORE,
0705 get_hard_smp_processor_id(cpu));
0706 core_id = cpu / threads_per_core;
0707 ref = &core_imc_refc[core_id];
0708 if (!ref)
0709 return -EINVAL;
0710
0711 ref->refc = 0;
0712
0713
0714
0715
0716
0717 mutex_lock(&imc_global_refc.lock);
0718 if (imc_global_refc.id == IMC_DOMAIN_CORE)
0719 imc_global_refc.refc--;
0720
0721 mutex_unlock(&imc_global_refc.lock);
0722 }
0723 return 0;
0724 }
0725
0726 static int core_imc_pmu_cpumask_init(void)
0727 {
0728 return cpuhp_setup_state(CPUHP_AP_PERF_POWERPC_CORE_IMC_ONLINE,
0729 "perf/powerpc/imc_core:online",
0730 ppc_core_imc_cpu_online,
0731 ppc_core_imc_cpu_offline);
0732 }
0733
0734 static void reset_global_refc(struct perf_event *event)
0735 {
0736 mutex_lock(&imc_global_refc.lock);
0737 imc_global_refc.refc--;
0738
0739
0740
0741
0742
0743
0744 if (imc_global_refc.refc <= 0) {
0745 imc_global_refc.refc = 0;
0746 imc_global_refc.id = 0;
0747 }
0748 mutex_unlock(&imc_global_refc.lock);
0749 }
0750
0751 static void core_imc_counters_release(struct perf_event *event)
0752 {
0753 int rc, core_id;
0754 struct imc_pmu_ref *ref;
0755
0756 if (event->cpu < 0)
0757 return;
0758
0759
0760
0761
0762
0763
0764 core_id = event->cpu / threads_per_core;
0765
0766
0767 ref = &core_imc_refc[core_id];
0768 if (!ref)
0769 return;
0770
0771 mutex_lock(&ref->lock);
0772 if (ref->refc == 0) {
0773
0774
0775
0776
0777
0778
0779
0780
0781
0782
0783 mutex_unlock(&ref->lock);
0784 return;
0785 }
0786 ref->refc--;
0787 if (ref->refc == 0) {
0788 rc = opal_imc_counters_stop(OPAL_IMC_COUNTERS_CORE,
0789 get_hard_smp_processor_id(event->cpu));
0790 if (rc) {
0791 mutex_unlock(&ref->lock);
0792 pr_err("IMC: Unable to stop the counters for core %d\n", core_id);
0793 return;
0794 }
0795 } else if (ref->refc < 0) {
0796 WARN(1, "core-imc: Invalid event reference count\n");
0797 ref->refc = 0;
0798 }
0799 mutex_unlock(&ref->lock);
0800
0801 reset_global_refc(event);
0802 }
0803
0804 static int core_imc_event_init(struct perf_event *event)
0805 {
0806 int core_id, rc;
0807 u64 config = event->attr.config;
0808 struct imc_mem_info *pcmi;
0809 struct imc_pmu *pmu;
0810 struct imc_pmu_ref *ref;
0811
0812 if (event->attr.type != event->pmu->type)
0813 return -ENOENT;
0814
0815
0816 if (event->hw.sample_period)
0817 return -EINVAL;
0818
0819 if (event->cpu < 0)
0820 return -EINVAL;
0821
0822 event->hw.idx = -1;
0823 pmu = imc_event_to_pmu(event);
0824
0825
0826 if (((config & IMC_EVENT_OFFSET_MASK) > pmu->counter_mem_size))
0827 return -EINVAL;
0828
0829 if (!is_core_imc_mem_inited(event->cpu))
0830 return -ENODEV;
0831
0832 core_id = event->cpu / threads_per_core;
0833 pcmi = &core_imc_pmu->mem_info[core_id];
0834 if ((!pcmi->vbase))
0835 return -ENODEV;
0836
0837
0838 ref = &core_imc_refc[core_id];
0839 if (!ref)
0840 return -EINVAL;
0841
0842
0843
0844
0845
0846
0847
0848 mutex_lock(&ref->lock);
0849 if (ref->refc == 0) {
0850 rc = opal_imc_counters_start(OPAL_IMC_COUNTERS_CORE,
0851 get_hard_smp_processor_id(event->cpu));
0852 if (rc) {
0853 mutex_unlock(&ref->lock);
0854 pr_err("core-imc: Unable to start the counters for core %d\n",
0855 core_id);
0856 return rc;
0857 }
0858 }
0859 ++ref->refc;
0860 mutex_unlock(&ref->lock);
0861
0862
0863
0864
0865
0866
0867
0868
0869
0870
0871 mutex_lock(&imc_global_refc.lock);
0872 if (imc_global_refc.id == 0 || imc_global_refc.id == IMC_DOMAIN_CORE) {
0873
0874
0875
0876
0877 imc_global_refc.id = IMC_DOMAIN_CORE;
0878 imc_global_refc.refc++;
0879 } else {
0880 mutex_unlock(&imc_global_refc.lock);
0881 return -EBUSY;
0882 }
0883 mutex_unlock(&imc_global_refc.lock);
0884
0885 event->hw.event_base = (u64)pcmi->vbase + (config & IMC_EVENT_OFFSET_MASK);
0886 event->destroy = core_imc_counters_release;
0887 return 0;
0888 }
0889
0890
0891
0892
0893
0894
0895
0896
0897
0898
0899
0900
0901
0902
0903
0904
0905
0906
0907
0908
0909
0910
0911 static int thread_imc_mem_alloc(int cpu_id, int size)
0912 {
0913 u64 *local_mem = per_cpu(thread_imc_mem, cpu_id);
0914 int nid = cpu_to_node(cpu_id);
0915
0916 if (!local_mem) {
0917 struct page *page;
0918
0919
0920
0921
0922 page = alloc_pages_node(nid,
0923 GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE |
0924 __GFP_NOWARN, get_order(size));
0925 if (!page)
0926 return -ENOMEM;
0927 local_mem = page_address(page);
0928
0929 per_cpu(thread_imc_mem, cpu_id) = local_mem;
0930 }
0931
0932 mtspr(SPRN_LDBAR, 0);
0933 return 0;
0934 }
0935
0936 static int ppc_thread_imc_cpu_online(unsigned int cpu)
0937 {
0938 return thread_imc_mem_alloc(cpu, thread_imc_mem_size);
0939 }
0940
0941 static int ppc_thread_imc_cpu_offline(unsigned int cpu)
0942 {
0943
0944
0945
0946
0947
0948
0949
0950
0951
0952 mtspr(SPRN_LDBAR, (mfspr(SPRN_LDBAR) & (~(1UL << 63))));
0953
0954
0955 mutex_lock(&imc_global_refc.lock);
0956 if (imc_global_refc.id == IMC_DOMAIN_THREAD)
0957 imc_global_refc.refc--;
0958 mutex_unlock(&imc_global_refc.lock);
0959
0960 return 0;
0961 }
0962
0963 static int thread_imc_cpu_init(void)
0964 {
0965 return cpuhp_setup_state(CPUHP_AP_PERF_POWERPC_THREAD_IMC_ONLINE,
0966 "perf/powerpc/imc_thread:online",
0967 ppc_thread_imc_cpu_online,
0968 ppc_thread_imc_cpu_offline);
0969 }
0970
0971 static int thread_imc_event_init(struct perf_event *event)
0972 {
0973 u32 config = event->attr.config;
0974 struct task_struct *target;
0975 struct imc_pmu *pmu;
0976
0977 if (event->attr.type != event->pmu->type)
0978 return -ENOENT;
0979
0980 if (!perfmon_capable())
0981 return -EACCES;
0982
0983
0984 if (event->hw.sample_period)
0985 return -EINVAL;
0986
0987 event->hw.idx = -1;
0988 pmu = imc_event_to_pmu(event);
0989
0990
0991 if (((config & IMC_EVENT_OFFSET_MASK) > pmu->counter_mem_size))
0992 return -EINVAL;
0993
0994 target = event->hw.target;
0995 if (!target)
0996 return -EINVAL;
0997
0998 mutex_lock(&imc_global_refc.lock);
0999
1000
1001
1002
1003 if (imc_global_refc.id == 0 || imc_global_refc.id == IMC_DOMAIN_THREAD) {
1004 imc_global_refc.id = IMC_DOMAIN_THREAD;
1005 imc_global_refc.refc++;
1006 } else {
1007 mutex_unlock(&imc_global_refc.lock);
1008 return -EBUSY;
1009 }
1010 mutex_unlock(&imc_global_refc.lock);
1011
1012 event->pmu->task_ctx_nr = perf_sw_context;
1013 event->destroy = reset_global_refc;
1014 return 0;
1015 }
1016
1017 static bool is_thread_imc_pmu(struct perf_event *event)
1018 {
1019 if (!strncmp(event->pmu->name, "thread_imc", strlen("thread_imc")))
1020 return true;
1021
1022 return false;
1023 }
1024
1025 static u64 * get_event_base_addr(struct perf_event *event)
1026 {
1027 u64 addr;
1028
1029 if (is_thread_imc_pmu(event)) {
1030 addr = (u64)per_cpu(thread_imc_mem, smp_processor_id());
1031 return (u64 *)(addr + (event->attr.config & IMC_EVENT_OFFSET_MASK));
1032 }
1033
1034 return (u64 *)event->hw.event_base;
1035 }
1036
1037 static void thread_imc_pmu_start_txn(struct pmu *pmu,
1038 unsigned int txn_flags)
1039 {
1040 if (txn_flags & ~PERF_PMU_TXN_ADD)
1041 return;
1042 perf_pmu_disable(pmu);
1043 }
1044
1045 static void thread_imc_pmu_cancel_txn(struct pmu *pmu)
1046 {
1047 perf_pmu_enable(pmu);
1048 }
1049
1050 static int thread_imc_pmu_commit_txn(struct pmu *pmu)
1051 {
1052 perf_pmu_enable(pmu);
1053 return 0;
1054 }
1055
1056 static u64 imc_read_counter(struct perf_event *event)
1057 {
1058 u64 *addr, data;
1059
1060
1061
1062
1063
1064
1065
1066 addr = get_event_base_addr(event);
1067 data = be64_to_cpu(READ_ONCE(*addr));
1068 local64_set(&event->hw.prev_count, data);
1069
1070 return data;
1071 }
1072
1073 static void imc_event_update(struct perf_event *event)
1074 {
1075 u64 counter_prev, counter_new, final_count;
1076
1077 counter_prev = local64_read(&event->hw.prev_count);
1078 counter_new = imc_read_counter(event);
1079 final_count = counter_new - counter_prev;
1080
1081
1082 local64_add(final_count, &event->count);
1083 }
1084
1085 static void imc_event_start(struct perf_event *event, int flags)
1086 {
1087
1088
1089
1090
1091
1092
1093 imc_read_counter(event);
1094 }
1095
1096 static void imc_event_stop(struct perf_event *event, int flags)
1097 {
1098
1099
1100
1101
1102 imc_event_update(event);
1103 }
1104
1105 static int imc_event_add(struct perf_event *event, int flags)
1106 {
1107 if (flags & PERF_EF_START)
1108 imc_event_start(event, flags);
1109
1110 return 0;
1111 }
1112
1113 static int thread_imc_event_add(struct perf_event *event, int flags)
1114 {
1115 int core_id;
1116 struct imc_pmu_ref *ref;
1117 u64 ldbar_value, *local_mem = per_cpu(thread_imc_mem, smp_processor_id());
1118
1119 if (flags & PERF_EF_START)
1120 imc_event_start(event, flags);
1121
1122 if (!is_core_imc_mem_inited(smp_processor_id()))
1123 return -EINVAL;
1124
1125 core_id = smp_processor_id() / threads_per_core;
1126 ldbar_value = ((u64)local_mem & THREAD_IMC_LDBAR_MASK) | THREAD_IMC_ENABLE;
1127 mtspr(SPRN_LDBAR, ldbar_value);
1128
1129
1130
1131
1132
1133
1134
1135 ref = &core_imc_refc[core_id];
1136 if (!ref)
1137 return -EINVAL;
1138
1139 mutex_lock(&ref->lock);
1140 if (ref->refc == 0) {
1141 if (opal_imc_counters_start(OPAL_IMC_COUNTERS_CORE,
1142 get_hard_smp_processor_id(smp_processor_id()))) {
1143 mutex_unlock(&ref->lock);
1144 pr_err("thread-imc: Unable to start the counter\
1145 for core %d\n", core_id);
1146 return -EINVAL;
1147 }
1148 }
1149 ++ref->refc;
1150 mutex_unlock(&ref->lock);
1151 return 0;
1152 }
1153
1154 static void thread_imc_event_del(struct perf_event *event, int flags)
1155 {
1156
1157 int core_id;
1158 struct imc_pmu_ref *ref;
1159
1160 core_id = smp_processor_id() / threads_per_core;
1161 ref = &core_imc_refc[core_id];
1162 if (!ref) {
1163 pr_debug("imc: Failed to get event reference count\n");
1164 return;
1165 }
1166
1167 mutex_lock(&ref->lock);
1168 ref->refc--;
1169 if (ref->refc == 0) {
1170 if (opal_imc_counters_stop(OPAL_IMC_COUNTERS_CORE,
1171 get_hard_smp_processor_id(smp_processor_id()))) {
1172 mutex_unlock(&ref->lock);
1173 pr_err("thread-imc: Unable to stop the counters\
1174 for core %d\n", core_id);
1175 return;
1176 }
1177 } else if (ref->refc < 0) {
1178 ref->refc = 0;
1179 }
1180 mutex_unlock(&ref->lock);
1181
1182
1183 mtspr(SPRN_LDBAR, (mfspr(SPRN_LDBAR) & (~(1UL << 63))));
1184
1185
1186
1187
1188
1189 imc_event_update(event);
1190 }
1191
1192
1193
1194
1195 static int trace_imc_mem_alloc(int cpu_id, int size)
1196 {
1197 u64 *local_mem = per_cpu(trace_imc_mem, cpu_id);
1198 int phys_id = cpu_to_node(cpu_id), rc = 0;
1199 int core_id = (cpu_id / threads_per_core);
1200
1201 if (!local_mem) {
1202 struct page *page;
1203
1204 page = alloc_pages_node(phys_id,
1205 GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE |
1206 __GFP_NOWARN, get_order(size));
1207 if (!page)
1208 return -ENOMEM;
1209 local_mem = page_address(page);
1210 per_cpu(trace_imc_mem, cpu_id) = local_mem;
1211
1212
1213 rc = opal_imc_counters_init(OPAL_IMC_COUNTERS_TRACE, __pa((void *)local_mem),
1214 get_hard_smp_processor_id(cpu_id));
1215 if (rc) {
1216 pr_info("IMC:opal init failed for trace imc\n");
1217 return rc;
1218 }
1219 }
1220
1221
1222 trace_imc_refc[core_id].id = core_id;
1223 mutex_init(&trace_imc_refc[core_id].lock);
1224
1225 mtspr(SPRN_LDBAR, 0);
1226 return 0;
1227 }
1228
1229 static int ppc_trace_imc_cpu_online(unsigned int cpu)
1230 {
1231 return trace_imc_mem_alloc(cpu, trace_imc_mem_size);
1232 }
1233
1234 static int ppc_trace_imc_cpu_offline(unsigned int cpu)
1235 {
1236
1237
1238
1239
1240
1241
1242
1243 mutex_lock(&imc_global_refc.lock);
1244 if (imc_global_refc.id == IMC_DOMAIN_TRACE)
1245 imc_global_refc.refc--;
1246 mutex_unlock(&imc_global_refc.lock);
1247
1248 return 0;
1249 }
1250
1251 static int trace_imc_cpu_init(void)
1252 {
1253 return cpuhp_setup_state(CPUHP_AP_PERF_POWERPC_TRACE_IMC_ONLINE,
1254 "perf/powerpc/imc_trace:online",
1255 ppc_trace_imc_cpu_online,
1256 ppc_trace_imc_cpu_offline);
1257 }
1258
1259 static u64 get_trace_imc_event_base_addr(void)
1260 {
1261 return (u64)per_cpu(trace_imc_mem, smp_processor_id());
1262 }
1263
1264
1265
1266
1267
1268 static int trace_imc_prepare_sample(struct trace_imc_data *mem,
1269 struct perf_sample_data *data,
1270 u64 *prev_tb,
1271 struct perf_event_header *header,
1272 struct perf_event *event)
1273 {
1274
1275 if (be64_to_cpu(READ_ONCE(mem->tb1)) > *prev_tb)
1276 *prev_tb = be64_to_cpu(READ_ONCE(mem->tb1));
1277 else
1278 return -EINVAL;
1279
1280 if ((be64_to_cpu(READ_ONCE(mem->tb1)) & IMC_TRACE_RECORD_TB1_MASK) !=
1281 be64_to_cpu(READ_ONCE(mem->tb2)))
1282 return -EINVAL;
1283
1284
1285 data->ip = be64_to_cpu(READ_ONCE(mem->ip));
1286 data->period = event->hw.last_period;
1287
1288 header->type = PERF_RECORD_SAMPLE;
1289 header->size = sizeof(*header) + event->header_size;
1290 header->misc = 0;
1291
1292 if (cpu_has_feature(CPU_FTR_ARCH_31)) {
1293 switch (IMC_TRACE_RECORD_VAL_HVPR(be64_to_cpu(READ_ONCE(mem->val)))) {
1294 case 0:
1295 header->misc |= PERF_RECORD_MISC_GUEST_KERNEL;
1296 break;
1297 case 1:
1298 header->misc |= PERF_RECORD_MISC_GUEST_USER;
1299 break;
1300 case 2:
1301 header->misc |= PERF_RECORD_MISC_KERNEL;
1302 break;
1303 case 3:
1304 header->misc |= PERF_RECORD_MISC_USER;
1305 break;
1306 default:
1307 pr_info("IMC: Unable to set the flag based on MSR bits\n");
1308 break;
1309 }
1310 } else {
1311 if (is_kernel_addr(data->ip))
1312 header->misc |= PERF_RECORD_MISC_KERNEL;
1313 else
1314 header->misc |= PERF_RECORD_MISC_USER;
1315 }
1316 perf_event_header__init_id(header, data, event);
1317
1318 return 0;
1319 }
1320
1321 static void dump_trace_imc_data(struct perf_event *event)
1322 {
1323 struct trace_imc_data *mem;
1324 int i, ret;
1325 u64 prev_tb = 0;
1326
1327 mem = (struct trace_imc_data *)get_trace_imc_event_base_addr();
1328 for (i = 0; i < (trace_imc_mem_size / sizeof(struct trace_imc_data));
1329 i++, mem++) {
1330 struct perf_sample_data data;
1331 struct perf_event_header header;
1332
1333 ret = trace_imc_prepare_sample(mem, &data, &prev_tb, &header, event);
1334 if (ret)
1335 break;
1336 else {
1337
1338 struct perf_output_handle handle;
1339
1340 if (perf_output_begin(&handle, &data, event, header.size))
1341 return;
1342
1343 perf_output_sample(&handle, &header, &data, event);
1344 perf_output_end(&handle);
1345 }
1346 }
1347 }
1348
1349 static int trace_imc_event_add(struct perf_event *event, int flags)
1350 {
1351 int core_id = smp_processor_id() / threads_per_core;
1352 struct imc_pmu_ref *ref = NULL;
1353 u64 local_mem, ldbar_value;
1354
1355
1356 local_mem = get_trace_imc_event_base_addr();
1357 ldbar_value = ((u64)local_mem & THREAD_IMC_LDBAR_MASK) | TRACE_IMC_ENABLE;
1358
1359
1360 if (trace_imc_refc)
1361 ref = &trace_imc_refc[core_id];
1362 if (!ref) {
1363 pr_debug("imc: Failed to get the event reference count\n");
1364 return -EINVAL;
1365 }
1366
1367 mtspr(SPRN_LDBAR, ldbar_value);
1368 mutex_lock(&ref->lock);
1369 if (ref->refc == 0) {
1370 if (opal_imc_counters_start(OPAL_IMC_COUNTERS_TRACE,
1371 get_hard_smp_processor_id(smp_processor_id()))) {
1372 mutex_unlock(&ref->lock);
1373 pr_err("trace-imc: Unable to start the counters for core %d\n", core_id);
1374 return -EINVAL;
1375 }
1376 }
1377 ++ref->refc;
1378 mutex_unlock(&ref->lock);
1379 return 0;
1380 }
1381
1382 static void trace_imc_event_read(struct perf_event *event)
1383 {
1384 return;
1385 }
1386
1387 static void trace_imc_event_stop(struct perf_event *event, int flags)
1388 {
1389 u64 local_mem = get_trace_imc_event_base_addr();
1390 dump_trace_imc_data(event);
1391 memset((void *)local_mem, 0, sizeof(u64));
1392 }
1393
1394 static void trace_imc_event_start(struct perf_event *event, int flags)
1395 {
1396 return;
1397 }
1398
1399 static void trace_imc_event_del(struct perf_event *event, int flags)
1400 {
1401 int core_id = smp_processor_id() / threads_per_core;
1402 struct imc_pmu_ref *ref = NULL;
1403
1404 if (trace_imc_refc)
1405 ref = &trace_imc_refc[core_id];
1406 if (!ref) {
1407 pr_debug("imc: Failed to get event reference count\n");
1408 return;
1409 }
1410
1411 mutex_lock(&ref->lock);
1412 ref->refc--;
1413 if (ref->refc == 0) {
1414 if (opal_imc_counters_stop(OPAL_IMC_COUNTERS_TRACE,
1415 get_hard_smp_processor_id(smp_processor_id()))) {
1416 mutex_unlock(&ref->lock);
1417 pr_err("trace-imc: Unable to stop the counters for core %d\n", core_id);
1418 return;
1419 }
1420 } else if (ref->refc < 0) {
1421 ref->refc = 0;
1422 }
1423 mutex_unlock(&ref->lock);
1424
1425 trace_imc_event_stop(event, flags);
1426 }
1427
1428 static int trace_imc_event_init(struct perf_event *event)
1429 {
1430 if (event->attr.type != event->pmu->type)
1431 return -ENOENT;
1432
1433 if (!perfmon_capable())
1434 return -EACCES;
1435
1436
1437 if (event->attr.sample_period == 0)
1438 return -ENOENT;
1439
1440
1441
1442
1443
1444
1445 mutex_lock(&imc_global_refc.lock);
1446 if (imc_global_refc.id == 0 || imc_global_refc.id == IMC_DOMAIN_TRACE) {
1447
1448
1449
1450
1451 imc_global_refc.id = IMC_DOMAIN_TRACE;
1452 imc_global_refc.refc++;
1453 } else {
1454 mutex_unlock(&imc_global_refc.lock);
1455 return -EBUSY;
1456 }
1457 mutex_unlock(&imc_global_refc.lock);
1458
1459 event->hw.idx = -1;
1460
1461
1462
1463
1464
1465 event->pmu->task_ctx_nr = perf_sw_context;
1466 event->destroy = reset_global_refc;
1467 return 0;
1468 }
1469
1470
1471 static int update_pmu_ops(struct imc_pmu *pmu)
1472 {
1473 pmu->pmu.task_ctx_nr = perf_invalid_context;
1474 pmu->pmu.add = imc_event_add;
1475 pmu->pmu.del = imc_event_stop;
1476 pmu->pmu.start = imc_event_start;
1477 pmu->pmu.stop = imc_event_stop;
1478 pmu->pmu.read = imc_event_update;
1479 pmu->pmu.attr_groups = pmu->attr_groups;
1480 pmu->pmu.capabilities = PERF_PMU_CAP_NO_EXCLUDE;
1481 pmu->attr_groups[IMC_FORMAT_ATTR] = &imc_format_group;
1482
1483 switch (pmu->domain) {
1484 case IMC_DOMAIN_NEST:
1485 pmu->pmu.event_init = nest_imc_event_init;
1486 pmu->attr_groups[IMC_CPUMASK_ATTR] = &imc_pmu_cpumask_attr_group;
1487 break;
1488 case IMC_DOMAIN_CORE:
1489 pmu->pmu.event_init = core_imc_event_init;
1490 pmu->attr_groups[IMC_CPUMASK_ATTR] = &imc_pmu_cpumask_attr_group;
1491 break;
1492 case IMC_DOMAIN_THREAD:
1493 pmu->pmu.event_init = thread_imc_event_init;
1494 pmu->pmu.add = thread_imc_event_add;
1495 pmu->pmu.del = thread_imc_event_del;
1496 pmu->pmu.start_txn = thread_imc_pmu_start_txn;
1497 pmu->pmu.cancel_txn = thread_imc_pmu_cancel_txn;
1498 pmu->pmu.commit_txn = thread_imc_pmu_commit_txn;
1499 break;
1500 case IMC_DOMAIN_TRACE:
1501 pmu->pmu.event_init = trace_imc_event_init;
1502 pmu->pmu.add = trace_imc_event_add;
1503 pmu->pmu.del = trace_imc_event_del;
1504 pmu->pmu.start = trace_imc_event_start;
1505 pmu->pmu.stop = trace_imc_event_stop;
1506 pmu->pmu.read = trace_imc_event_read;
1507 pmu->attr_groups[IMC_FORMAT_ATTR] = &trace_imc_format_group;
1508 break;
1509 default:
1510 break;
1511 }
1512
1513 return 0;
1514 }
1515
1516
1517 static int init_nest_pmu_ref(void)
1518 {
1519 int nid, i, cpu;
1520
1521 nest_imc_refc = kcalloc(num_possible_nodes(), sizeof(*nest_imc_refc),
1522 GFP_KERNEL);
1523
1524 if (!nest_imc_refc)
1525 return -ENOMEM;
1526
1527 i = 0;
1528 for_each_node(nid) {
1529
1530
1531
1532
1533 mutex_init(&nest_imc_refc[i].lock);
1534
1535
1536
1537
1538
1539
1540
1541 nest_imc_refc[i++].id = nid;
1542 }
1543
1544
1545
1546
1547
1548 for_each_possible_cpu(cpu) {
1549 nid = cpu_to_node(cpu);
1550 for (i = 0; i < num_possible_nodes(); i++) {
1551 if (nest_imc_refc[i].id == nid) {
1552 per_cpu(local_nest_imc_refc, cpu) = &nest_imc_refc[i];
1553 break;
1554 }
1555 }
1556 }
1557 return 0;
1558 }
1559
1560 static void cleanup_all_core_imc_memory(void)
1561 {
1562 int i, nr_cores = DIV_ROUND_UP(num_possible_cpus(), threads_per_core);
1563 struct imc_mem_info *ptr = core_imc_pmu->mem_info;
1564 int size = core_imc_pmu->counter_mem_size;
1565
1566
1567 for (i = 0; i < nr_cores; i++) {
1568 if (ptr[i].vbase)
1569 free_pages((u64)ptr[i].vbase, get_order(size));
1570 }
1571
1572 kfree(ptr);
1573 kfree(core_imc_refc);
1574 }
1575
1576 static void thread_imc_ldbar_disable(void *dummy)
1577 {
1578
1579
1580
1581
1582 mtspr(SPRN_LDBAR, (mfspr(SPRN_LDBAR) & (~(1UL << 63))));
1583 }
1584
1585 void thread_imc_disable(void)
1586 {
1587 on_each_cpu(thread_imc_ldbar_disable, NULL, 1);
1588 }
1589
1590 static void cleanup_all_thread_imc_memory(void)
1591 {
1592 int i, order = get_order(thread_imc_mem_size);
1593
1594 for_each_online_cpu(i) {
1595 if (per_cpu(thread_imc_mem, i))
1596 free_pages((u64)per_cpu(thread_imc_mem, i), order);
1597
1598 }
1599 }
1600
1601 static void cleanup_all_trace_imc_memory(void)
1602 {
1603 int i, order = get_order(trace_imc_mem_size);
1604
1605 for_each_online_cpu(i) {
1606 if (per_cpu(trace_imc_mem, i))
1607 free_pages((u64)per_cpu(trace_imc_mem, i), order);
1608
1609 }
1610 kfree(trace_imc_refc);
1611 }
1612
1613
1614 static void imc_common_mem_free(struct imc_pmu *pmu_ptr)
1615 {
1616 if (pmu_ptr->attr_groups[IMC_EVENT_ATTR])
1617 kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]->attrs);
1618 kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]);
1619 }
1620
1621
1622
1623
1624
1625
1626
1627 static void imc_common_cpuhp_mem_free(struct imc_pmu *pmu_ptr)
1628 {
1629 if (pmu_ptr->domain == IMC_DOMAIN_NEST) {
1630 mutex_lock(&nest_init_lock);
1631 if (nest_pmus == 1) {
1632 cpuhp_remove_state(CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE);
1633 kfree(nest_imc_refc);
1634 kfree(per_nest_pmu_arr);
1635 per_nest_pmu_arr = NULL;
1636 }
1637
1638 if (nest_pmus > 0)
1639 nest_pmus--;
1640 mutex_unlock(&nest_init_lock);
1641 }
1642
1643
1644 if (pmu_ptr->domain == IMC_DOMAIN_CORE) {
1645 cpuhp_remove_state(CPUHP_AP_PERF_POWERPC_CORE_IMC_ONLINE);
1646 cleanup_all_core_imc_memory();
1647 }
1648
1649
1650 if (pmu_ptr->domain == IMC_DOMAIN_THREAD) {
1651 cpuhp_remove_state(CPUHP_AP_PERF_POWERPC_THREAD_IMC_ONLINE);
1652 cleanup_all_thread_imc_memory();
1653 }
1654
1655 if (pmu_ptr->domain == IMC_DOMAIN_TRACE) {
1656 cpuhp_remove_state(CPUHP_AP_PERF_POWERPC_TRACE_IMC_ONLINE);
1657 cleanup_all_trace_imc_memory();
1658 }
1659 }
1660
1661
1662
1663
1664
1665 void unregister_thread_imc(void)
1666 {
1667 imc_common_cpuhp_mem_free(thread_imc_pmu);
1668 imc_common_mem_free(thread_imc_pmu);
1669 perf_pmu_unregister(&thread_imc_pmu->pmu);
1670 }
1671
1672
1673
1674
1675 static int imc_mem_init(struct imc_pmu *pmu_ptr, struct device_node *parent,
1676 int pmu_index)
1677 {
1678 const char *s;
1679 int nr_cores, cpu, res = -ENOMEM;
1680
1681 if (of_property_read_string(parent, "name", &s))
1682 return -ENODEV;
1683
1684 switch (pmu_ptr->domain) {
1685 case IMC_DOMAIN_NEST:
1686
1687 pmu_ptr->pmu.name = kasprintf(GFP_KERNEL, "%s%s_imc", "nest_", s);
1688 if (!pmu_ptr->pmu.name)
1689 goto err;
1690
1691
1692 if (!per_nest_pmu_arr) {
1693 per_nest_pmu_arr = kcalloc(get_max_nest_dev() + 1,
1694 sizeof(struct imc_pmu *),
1695 GFP_KERNEL);
1696 if (!per_nest_pmu_arr)
1697 goto err;
1698 }
1699 per_nest_pmu_arr[pmu_index] = pmu_ptr;
1700 break;
1701 case IMC_DOMAIN_CORE:
1702
1703 pmu_ptr->pmu.name = kasprintf(GFP_KERNEL, "%s%s", s, "_imc");
1704 if (!pmu_ptr->pmu.name)
1705 goto err;
1706
1707 nr_cores = DIV_ROUND_UP(num_possible_cpus(), threads_per_core);
1708 pmu_ptr->mem_info = kcalloc(nr_cores, sizeof(struct imc_mem_info),
1709 GFP_KERNEL);
1710
1711 if (!pmu_ptr->mem_info)
1712 goto err;
1713
1714 core_imc_refc = kcalloc(nr_cores, sizeof(struct imc_pmu_ref),
1715 GFP_KERNEL);
1716
1717 if (!core_imc_refc) {
1718 kfree(pmu_ptr->mem_info);
1719 goto err;
1720 }
1721
1722 core_imc_pmu = pmu_ptr;
1723 break;
1724 case IMC_DOMAIN_THREAD:
1725
1726 pmu_ptr->pmu.name = kasprintf(GFP_KERNEL, "%s%s", s, "_imc");
1727 if (!pmu_ptr->pmu.name)
1728 goto err;
1729
1730 thread_imc_mem_size = pmu_ptr->counter_mem_size;
1731 for_each_online_cpu(cpu) {
1732 res = thread_imc_mem_alloc(cpu, pmu_ptr->counter_mem_size);
1733 if (res) {
1734 cleanup_all_thread_imc_memory();
1735 goto err;
1736 }
1737 }
1738
1739 thread_imc_pmu = pmu_ptr;
1740 break;
1741 case IMC_DOMAIN_TRACE:
1742
1743 pmu_ptr->pmu.name = kasprintf(GFP_KERNEL, "%s%s", s, "_imc");
1744 if (!pmu_ptr->pmu.name)
1745 return -ENOMEM;
1746
1747 nr_cores = DIV_ROUND_UP(num_possible_cpus(), threads_per_core);
1748 trace_imc_refc = kcalloc(nr_cores, sizeof(struct imc_pmu_ref),
1749 GFP_KERNEL);
1750 if (!trace_imc_refc)
1751 return -ENOMEM;
1752
1753 trace_imc_mem_size = pmu_ptr->counter_mem_size;
1754 for_each_online_cpu(cpu) {
1755 res = trace_imc_mem_alloc(cpu, trace_imc_mem_size);
1756 if (res) {
1757 cleanup_all_trace_imc_memory();
1758 goto err;
1759 }
1760 }
1761 break;
1762 default:
1763 return -EINVAL;
1764 }
1765
1766 return 0;
1767 err:
1768 return res;
1769 }
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781 int init_imc_pmu(struct device_node *parent, struct imc_pmu *pmu_ptr, int pmu_idx)
1782 {
1783 int ret;
1784
1785 ret = imc_mem_init(pmu_ptr, parent, pmu_idx);
1786 if (ret)
1787 goto err_free_mem;
1788
1789 switch (pmu_ptr->domain) {
1790 case IMC_DOMAIN_NEST:
1791
1792
1793
1794
1795
1796
1797 mutex_lock(&nest_init_lock);
1798 if (nest_pmus == 0) {
1799 ret = init_nest_pmu_ref();
1800 if (ret) {
1801 mutex_unlock(&nest_init_lock);
1802 kfree(per_nest_pmu_arr);
1803 per_nest_pmu_arr = NULL;
1804 goto err_free_mem;
1805 }
1806
1807 ret = nest_pmu_cpumask_init();
1808 if (ret) {
1809 mutex_unlock(&nest_init_lock);
1810 kfree(nest_imc_refc);
1811 kfree(per_nest_pmu_arr);
1812 per_nest_pmu_arr = NULL;
1813 goto err_free_mem;
1814 }
1815 }
1816 nest_pmus++;
1817 mutex_unlock(&nest_init_lock);
1818 break;
1819 case IMC_DOMAIN_CORE:
1820 ret = core_imc_pmu_cpumask_init();
1821 if (ret) {
1822 cleanup_all_core_imc_memory();
1823 goto err_free_mem;
1824 }
1825
1826 break;
1827 case IMC_DOMAIN_THREAD:
1828 ret = thread_imc_cpu_init();
1829 if (ret) {
1830 cleanup_all_thread_imc_memory();
1831 goto err_free_mem;
1832 }
1833
1834 break;
1835 case IMC_DOMAIN_TRACE:
1836 ret = trace_imc_cpu_init();
1837 if (ret) {
1838 cleanup_all_trace_imc_memory();
1839 goto err_free_mem;
1840 }
1841
1842 break;
1843 default:
1844 return -EINVAL;
1845 }
1846
1847 ret = update_events_in_group(parent, pmu_ptr);
1848 if (ret)
1849 goto err_free_cpuhp_mem;
1850
1851 ret = update_pmu_ops(pmu_ptr);
1852 if (ret)
1853 goto err_free_cpuhp_mem;
1854
1855 ret = perf_pmu_register(&pmu_ptr->pmu, pmu_ptr->pmu.name, -1);
1856 if (ret)
1857 goto err_free_cpuhp_mem;
1858
1859 pr_debug("%s performance monitor hardware support registered\n",
1860 pmu_ptr->pmu.name);
1861
1862 return 0;
1863
1864 err_free_cpuhp_mem:
1865 imc_common_cpuhp_mem_free(pmu_ptr);
1866 err_free_mem:
1867 imc_common_mem_free(pmu_ptr);
1868 return ret;
1869 }