[PATCH 1/2] Error: Fix mmdc compilation errors due to cpu notifier
From: Nitin Chaudhary <hidden>
Date: 2016-08-17 00:59:20
Subsystem:
arm port, cpu hotplug, the rest · Maintainers:
Russell King, Thomas Gleixner, Peter Zijlstra, Linus Torvalds
--- arch/arm/mach-imx/mmdc.c | 89 ++++++++++++++++++++++------------------------ include/linux/cpuhotplug.h | 1 + 2 files changed, 44 insertions(+), 46 deletions(-)
diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c
index 372b59c..95c222d 100644
--- a/arch/arm/mach-imx/mmdc.c
+++ b/arch/arm/mach-imx/mmdc.c@@ -77,13 +77,14 @@ struct mmdc_pmu struct pmu pmu; void __iomem *mmdc_base; cpumask_t cpu; - struct notifier_block cpu_nb; struct hrtimer hrtimer; unsigned int irq; struct device *dev; struct perf_event *mmdc_events[MMDC_NUM_COUNTERS]; }; +static struct mmdc_pmu *pmu_mmdc; + static unsigned int mmdc_poll_period_us = 1000000; module_param_named(pmu_poll_period_us, mmdc_poll_period_us, uint, S_IRUGO | S_IWUSR);
@@ -96,7 +97,6 @@ static ktime_t mmdc_timer_period(void) static ssize_t mmdc_cpumask_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct mmdc_pmu *pmu_mmdc = dev_get_drvdata(dev); return cpumap_print_to_pagebuf(true, buf, &pmu_mmdc->cpu); }
@@ -149,7 +149,7 @@ static const struct attribute_group * attr_groups[] = { NULL, }; -static u32 mmdc_read_counter(struct mmdc_pmu *pmu_mmdc, int cfg, u64 prev_val) +static u32 mmdc_read_counter(int cfg, u64 prev_val) { u32 val; void __iomem *mmdc_base, *reg;
@@ -184,7 +184,6 @@ static u32 mmdc_read_counter(struct mmdc_pmu *pmu_mmdc, int cfg, u64 prev_val) static void mmdc_enable_profiling(struct perf_event *event) { - struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu); void __iomem *mmdc_base, *reg; mmdc_base = pmu_mmdc->mmdc_base;
@@ -193,32 +192,27 @@ static void mmdc_enable_profiling(struct perf_event *event) writel_relaxed(DBG_EN, reg); } -static int mmdc_cpu_notifier(struct notifier_block *nb, - unsigned long action, void *hcpu) +static int mmdc_cpu_offline(unsigned int cpu) { - struct mmdc_pmu *pmu_mmdc = container_of(nb, struct mmdc_pmu, cpu_nb); - unsigned int cpu = (long)hcpu; /* for (long) see kernel/cpu.c */ unsigned int target; - - switch (action & ~CPU_TASKS_FROZEN) { - case CPU_DOWN_PREPARE: - if (!cpumask_test_and_clear_cpu(cpu, &pmu_mmdc->cpu)) - break; - target = cpumask_any_but(cpu_online_mask, cpu); - if (target >= nr_cpu_ids) - break; - perf_pmu_migrate_context(&pmu_mmdc->pmu, cpu, target); - cpumask_set_cpu(target, &pmu_mmdc->cpu); - default: - break; - } - - return NOTIFY_OK; + struct mmdc_pmu *pmu_ptr = pmu_mmdc; + if (!cpumask_test_and_clear_cpu(cpu, &pmu_ptr->cpu)) + return 0; + target = cpumask_any_but(cpu_online_mask, cpu); + if (target >= nr_cpu_ids) + return 0; + + perf_pmu_migrate_context(&pmu_ptr->pmu, cpu, target); + cpumask_set_cpu(target, &pmu_ptr->cpu); + /* + if(pmu_ptr->irq) + WARN_ON(irq_set_affinity_hint(pmu_ptr->irq, &pmu_ptr->cpu) != 0); + */ + return 0; } static int mmdc_event_init(struct perf_event *event) { - struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu); if (event->attr.type != event->pmu->type) return -ENOENT;
@@ -243,17 +237,15 @@ static int mmdc_event_init(struct perf_event *event) static void mmdc_event_update(struct perf_event * event) { - struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu); u32 val; u64 prev_val; prev_val = local64_read(&event->count); - val = mmdc_read_counter(pmu_mmdc, (int) event->attr.config, prev_val); + val = mmdc_read_counter((int)event->attr.config, prev_val); local64_add(val - (u32)(prev_val&0xFFFFFFFF) , &event->count); } static void mmdc_event_start(struct perf_event *event, int flags) { - struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu); void __iomem *mmdc_base, *reg; local64_set(&event->count, 0);
@@ -268,7 +260,6 @@ static void mmdc_event_start(struct perf_event *event, int flags) static int mmdc_event_add(struct perf_event *event, int flags) { - struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu); int cfg = (int)event->attr.config; if (cfg >= 1 && cfg <= MMDC_NUM_COUNTERS) pmu_mmdc->mmdc_events[cfg - 1] = event;
@@ -279,7 +270,6 @@ static int mmdc_event_add(struct perf_event *event, int flags) static void mmdc_event_stop(struct perf_event *event, int flags) { - struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu); void __iomem *mmdc_base, *reg; int cfg = (int)event->attr.config;
@@ -300,7 +290,7 @@ static void mmdc_event_del(struct perf_event *event, int flags) mmdc_event_stop(event, PERF_EF_UPDATE); } -static void mmdc_overflow_handler(struct mmdc_pmu *pmu_mmdc) +static void mmdc_overflow_handler(void) { int i; u32 val;
@@ -312,7 +302,7 @@ static void mmdc_overflow_handler(struct mmdc_pmu *pmu_mmdc) if (event) { prev_val = local64_read(&event->count); - val = mmdc_read_counter(pmu_mmdc, i + 1, prev_val); + val = mmdc_read_counter(i + 1, prev_val); local64_add(val - (u32)(prev_val&0xFFFFFFFF) , &event->count); } }
@@ -320,16 +310,13 @@ static void mmdc_overflow_handler(struct mmdc_pmu *pmu_mmdc) static enum hrtimer_restart mmdc_timer_handler(struct hrtimer *hrtimer) { - struct mmdc_pmu *pmu_mmdc = container_of(hrtimer, struct mmdc_pmu, - hrtimer); - - mmdc_overflow_handler(pmu_mmdc); + mmdc_overflow_handler(); hrtimer_forward_now(hrtimer, mmdc_timer_period()); return HRTIMER_RESTART; } -static int mmdc_pmu_init(struct mmdc_pmu *pmu_mmdc, void __iomem *mmdc_base, struct device *dev) +static int mmdc_pmu_init(void __iomem *mmdc_base, struct device *dev) { int mmdc_num; *pmu_mmdc = (struct mmdc_pmu) {
@@ -347,12 +334,9 @@ static int mmdc_pmu_init(struct mmdc_pmu *pmu_mmdc, void __iomem *mmdc_base, str }; mmdc_num = ida_simple_get(&mmdc_ida, 0, 0, GFP_KERNEL); - + cpumask_set_cpu(smp_processor_id(), &pmu_mmdc->cpu); - pmu_mmdc->cpu_nb.notifier_call = mmdc_cpu_notifier; - pmu_mmdc->cpu_nb.priority = CPU_PRI_PERF + 1; - pmu_mmdc->dev = dev; return mmdc_num; }
@@ -361,11 +345,11 @@ static int imx_mmdc_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; void __iomem *mmdc_base, *reg; - struct mmdc_pmu *pmu_mmdc; char * name; u32 val; - int timeout = 0x400; + int timeout = 0x800; int mmdc_num; + int err; mmdc_base = of_iomap(np, 0); WARN_ON(!mmdc_base);
@@ -390,7 +374,7 @@ static int imx_mmdc_probe(struct platform_device *pdev) if (unlikely(!timeout)) { pr_warn("%s: failed to enable automatic power saving\n", __func__); - return -EBUSY; + //return -EBUSY; } pmu_mmdc = kzalloc(sizeof(*pmu_mmdc), GFP_KERNEL);
@@ -398,12 +382,18 @@ static int imx_mmdc_probe(struct platform_device *pdev) pr_err("failed to allocate PMU device!\n"); return -ENOMEM; } - mmdc_num = mmdc_pmu_init(pmu_mmdc, mmdc_base, &pdev->dev); + mmdc_num = mmdc_pmu_init(mmdc_base, &pdev->dev); dev_info(pmu_mmdc->dev, "No access to interrupts, using timer.\n"); hrtimer_init(&pmu_mmdc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); pmu_mmdc->hrtimer.function = mmdc_timer_handler; - register_cpu_notifier(&pmu_mmdc->cpu_nb); + + err = cpuhp_setup_state(CPUHP_AP_PERF_ARM_MMDC_ONLINE, + "AP_PERF_ARM_MMDC_ONLINE", NULL, + mmdc_cpu_offline); + if(err) + goto error_cpu_notifier; + if (mmdc_num == 0) { name = "mmdc"; } else {
@@ -413,12 +403,19 @@ static int imx_mmdc_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, pmu_mmdc); perf_pmu_register(&(pmu_mmdc->pmu), name, -1); + + dev_info(pmu_mmdc->dev, "%s success\n",__func__); + return 0; + +error_cpu_notifier: + cpuhp_remove_state_nocalls(CPUHP_AP_PERF_ARM_MMDC_ONLINE); + kfree(pmu_mmdc); + return err; } static int imx_mmdc_remove(struct platform_device *pdev) { - struct mmdc_pmu *pmu_mmdc = platform_get_drvdata(pdev); perf_pmu_unregister(&pmu_mmdc->pmu); kfree(pmu_mmdc); return 0;
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 242bf53..c059342 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h@@ -86,6 +86,7 @@ enum cpuhp_state { CPUHP_AP_PERF_S390_SF_ONLINE, CPUHP_AP_PERF_ARM_CCI_ONLINE, CPUHP_AP_PERF_ARM_CCN_ONLINE, + CPUHP_AP_PERF_ARM_MMDC_ONLINE, CPUHP_AP_WORKQUEUE_ONLINE, CPUHP_AP_RCUTREE_ONLINE, CPUHP_AP_NOTIFY_ONLINE,
--
2.7.4