Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1440594 > unrolled thread

[patch 00/66] cpuhotplug: Convert all priority notifiers to the state machine

Started byAnna-Maria Gleixner <anna-maria@linutronix.de>
First post2016-07-11 14:50 +0200
Last post2016-07-11 14:50 +0200
Articles 16 — 4 participants

Back to article view | Back to linux.kernel


Contents

  [patch 00/66] cpuhotplug: Convert all priority notifiers to the state  machine Anna-Maria Gleixner <anna-maria@linutronix.de> - 2016-07-11 14:50 +0200
    [patch 29/66] powerpc: numa: Convert to hotplug state machine Anna-Maria Gleixner <anna-maria@linutronix.de> - 2016-07-11 14:50 +0200
    [patch 27/66] workqueue: Convert to state machine callbacks Anna-Maria Gleixner <anna-maria@linutronix.de> - 2016-07-11 14:50 +0200
      Re: [patch 27/66] workqueue: Convert to state machine callbacks Ingo Molnar <mingo@kernel.org> - 2016-07-11 16:40 +0200
        Re: [patch 27/66] workqueue: Convert to state machine callbacks Anna-Maria Gleixner <anna-maria@linutronix.de> - 2016-07-11 17:00 +0200
      Re: [patch 27/66] workqueue: Convert to state machine callbacks Tejun Heo <tj@kernel.org> - 2016-07-12 16:40 +0200
    [patch 37/66] clocksource/arm_arch_timer: Convert to hotplug state  machine. Anna-Maria Gleixner <anna-maria@linutronix.de> - 2016-07-11 14:50 +0200
    [patch 39/66] clocksource/dummy_timer: Convert to hotplug state  machine Anna-Maria Gleixner <anna-maria@linutronix.de> - 2016-07-11 14:50 +0200
    [patch 32/66] x86/apb_timer: Convert to hotplug state machine Anna-Maria Gleixner <anna-maria@linutronix.de> - 2016-07-11 14:50 +0200
    [patch 20/66] sh: perf: Convert the hotplug notifiers to state  machine callbacks Anna-Maria Gleixner <anna-maria@linutronix.de> - 2016-07-11 14:50 +0200
    [patch 16/66] blackfin: perf: Convert hotplug notifier to state  machine Anna-Maria Gleixner <anna-maria@linutronix.de> - 2016-07-11 14:50 +0200
    [patch 11/66] perf/x86/amd/uncore: Convert to hotplug state machine Anna-Maria Gleixner <anna-maria@linutronix.de> - 2016-07-11 14:50 +0200
    [patch 14/66] perf/x86/intel/cqm: Convert Intel CQM to hotplug state  machine Anna-Maria Gleixner <anna-maria@linutronix.de> - 2016-07-11 14:50 +0200
    [patch 01/66] x86/vdso: Convert to hotplug state machine Anna-Maria Gleixner <anna-maria@linutronix.de> - 2016-07-11 14:50 +0200
      Re: [patch 01/66] x86/vdso: Convert to hotplug state machine Andy Lutomirski <luto@amacapital.net> - 2016-07-11 21:00 +0200
    [patch 08/66] perf: Convert to hotplug state machine Anna-Maria Gleixner <anna-maria@linutronix.de> - 2016-07-11 14:50 +0200

#1440594 — [patch 00/66] cpuhotplug: Convert all priority notifiers to the state machine

FromAnna-Maria Gleixner <anna-maria@linutronix.de>
Date2016-07-11 14:50 +0200
Subject[patch 00/66] cpuhotplug: Convert all priority notifiers to the state machine
Message-ID<rTIFb-70u-3@gated-at.bofh.it>
This series is the next step towards a state machine based hotplug machinery.

It converts all notifiers which have a priority assigned and gets rid of the
CPU_STARTING/DYING notifiers.

Thanks,

	Anna-Maria
---
 arch/arc/kernel/time.c                        |   32 ++--
 arch/arm/kernel/smp_twd.c                     |   31 +---
 arch/arm/mach-mvebu/coherency.c               |   19 --
 arch/arm/mm/cache-l2x0.c                      |   27 +--
 arch/arm/vfp/vfpmodule.c                      |   28 ++--
 arch/arm/xen/enlighten.c                      |   41 +----
 arch/arm64/kernel/armv8_deprecated.c          |   22 ---
 arch/blackfin/kernel/perf_event.c             |   26 ---
 arch/metag/kernel/perf/perf_event.c           |   26 +--
 arch/mips/oprofile/op_model_loongson3.c       |   35 ++---
 arch/powerpc/mm/numa.c                        |   46 ++----
 arch/powerpc/perf/core-book3s.c               |   30 +---
 arch/s390/kernel/perf_cpum_cf.c               |   44 ++----
 arch/s390/kernel/perf_cpum_sf.c               |   43 ++----
 arch/sh/kernel/perf_event.c                   |   23 ---
 arch/sparc/kernel/smp_32.c                    |    2 
 arch/x86/entry/vdso/vma.c                     |   20 --
 arch/x86/events/amd/ibs.c                     |   64 ++++-----
 arch/x86/events/amd/power.c                   |   60 +-------
 arch/x86/events/intel/cqm.c                   |   49 ++-----
 arch/x86/events/intel/cstate.c                |   51 ++-----
 arch/x86/events/intel/rapl.c                  |   84 +++---------
 arch/x86/events/intel/uncore.c                |  133 ++++++-------------
 arch/x86/kernel/apb_timer.c                   |   29 +---
 arch/x86/kernel/apic/x2apic_cluster.c         |   80 ++++-------
 arch/x86/kernel/hpet.c                        |   69 ++++-----
 arch/x86/kernel/tboot.c                       |   25 +--
 arch/x86/kvm/x86.c                            |   35 +----
 arch/xtensa/kernel/perf_event.c               |   26 +--
 b/arch/x86/events/amd/core.c                  |    6 
 b/arch/x86/events/amd/uncore.c                |  122 ++++-------------
 b/arch/x86/events/core.c                      |  103 +++++++++-----
 b/arch/x86/events/intel/core.c                |    4 
 drivers/acpi/processor_driver.c               |   11 -
 drivers/bus/arm-cci.c                         |   54 ++-----
 drivers/bus/arm-ccn.c                         |   47 +++---
 drivers/clocksource/arm_arch_timer.c          |   54 +++----
 drivers/clocksource/arm_global_timer.c        |   41 +----
 drivers/clocksource/dummy_timer.c             |   36 -----
 drivers/clocksource/exynos_mct.c              |   48 +-----
 drivers/clocksource/metag_generic.c           |   33 ----
 drivers/clocksource/mips-gic-timer.c          |   38 +----
 drivers/clocksource/qcom-timer.c              |   41 +----
 drivers/clocksource/time-armada-370-xp.c      |   44 ++----
 drivers/clocksource/timer-atlas7.c            |   41 +----
 drivers/hwtracing/coresight/coresight-etm3x.c |   90 +++++++-----
 drivers/hwtracing/coresight/coresight-etm4x.c |   93 +++++++------
 drivers/irqchip/irq-armada-370-xp.c           |   44 ++----
 drivers/irqchip/irq-bcm2836.c                 |   34 +---
 drivers/irqchip/irq-gic-v3.c                  |   22 +--
 drivers/irqchip/irq-gic.c                     |   23 ---
 drivers/irqchip/irq-hip04.c                   |   25 ---
 drivers/leds/trigger/ledtrig-cpu.c            |   32 ++--
 drivers/perf/arm_pmu.c                        |   36 ++---
 include/linux/cpu.h                           |   23 ---
 include/linux/cpuhotplug.h                    |   78 +++++++++++
 include/linux/hrtimer.h                       |    7 +
 include/linux/perf/arm_pmu.h                  |    1 
 include/linux/perf_event.h                    |   44 +-----
 include/linux/rcutree.h                       |   15 ++
 include/linux/smp.h                           |    5 
 include/linux/timer.h                         |    6 
 include/linux/workqueue.h                     |    6 
 kernel/cpu.c                                  |   83 ++++++++---
 kernel/events/core.c                          |   56 +-------
 kernel/profile.c                              |  181 +++++++++-----------------
 kernel/rcu/tree.c                             |  105 +++++++--------
 kernel/smp.c                                  |   79 ++++-------
 kernel/time/hrtimer.c                         |   40 -----
 kernel/time/timer.c                           |   25 ---
 kernel/workqueue.c                            |  108 ++++++---------
 tools/testing/radix-tree/linux/cpu.h          |   13 -
 virt/kvm/arm/arch_timer.c                     |   35 +----
 virt/kvm/arm/vgic.c                           |   39 +----
 virt/kvm/arm/vgic/vgic-init.c                 |   31 +---
 virt/kvm/kvm_main.c                           |   32 +---
 76 files changed, 1271 insertions(+), 2063 deletions(-)

[toc] | [next] | [standalone]


#1440595 — [patch 29/66] powerpc: numa: Convert to hotplug state machine

FromAnna-Maria Gleixner <anna-maria@linutronix.de>
Date2016-07-11 14:50 +0200
Subject[patch 29/66] powerpc: numa: Convert to hotplug state machine
Message-ID<rTIOT-762-57@gated-at.bofh.it>
In reply to#1440594
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>

Install the callbacks via the state machine and let the core invoke
the callbacks on the already online CPUs.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>
---
 arch/powerpc/mm/numa.c     |   46 +++++++++++++++------------------------------
 include/linux/cpuhotplug.h |    1 
 2 files changed, 17 insertions(+), 30 deletions(-)

--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -581,30 +581,22 @@ static void verify_cpu_node_mapping(int
 	}
 }
 
-static int cpu_numa_callback(struct notifier_block *nfb, unsigned long action,
-			     void *hcpu)
+/* Must run before sched domains notifier. */
+static int ppc_numa_cpu_prepare(unsigned int cpu)
 {
-	unsigned long lcpu = (unsigned long)hcpu;
-	int ret = NOTIFY_DONE, nid;
+	int nid;
+
+	nid = numa_setup_cpu(cpu);
+	verify_cpu_node_mapping(cpu, nid);
+	return 0;
+}
 
-	switch (action) {
-	case CPU_UP_PREPARE:
-	case CPU_UP_PREPARE_FROZEN:
-		nid = numa_setup_cpu(lcpu);
-		verify_cpu_node_mapping((int)lcpu, nid);
-		ret = NOTIFY_OK;
-		break;
+static int ppc_numa_cpu_dead(unsigned int cpu)
+{
 #ifdef CONFIG_HOTPLUG_CPU
-	case CPU_DEAD:
-	case CPU_DEAD_FROZEN:
-	case CPU_UP_CANCELED:
-	case CPU_UP_CANCELED_FROZEN:
-		unmap_cpu_from_node(lcpu);
-		ret = NOTIFY_OK;
-		break;
+	unmap_cpu_from_node(cpu);
 #endif
-	}
-	return ret;
+	return 0;
 }
 
 /*
@@ -913,11 +905,6 @@ static void __init dump_numa_memory_topo
 	}
 }
 
-static struct notifier_block ppc64_numa_nb = {
-	.notifier_call = cpu_numa_callback,
-	.priority = 1 /* Must run before sched domains notifier. */
-};
-
 /* Initialize NODE_DATA for a node on the local memory */
 static void __init setup_node_data(int nid, u64 start_pfn, u64 end_pfn)
 {
@@ -953,7 +940,7 @@ static void __init setup_node_data(int n
 
 void __init initmem_init(void)
 {
-	int nid, cpu;
+	int nid;
 
 	max_low_pfn = memblock_end_of_DRAM() >> PAGE_SHIFT;
 	max_pfn = max_low_pfn;
@@ -985,15 +972,14 @@ void __init initmem_init(void)
 	setup_node_to_cpumask_map();
 
 	reset_numa_cpu_lookup_table();
-	register_cpu_notifier(&ppc64_numa_nb);
+
 	/*
 	 * We need the numa_cpu_lookup_table to be accurate for all CPUs,
 	 * even before we online them, so that we can use cpu_to_{node,mem}
 	 * early in boot, cf. smp_prepare_cpus().
 	 */
-	for_each_present_cpu(cpu) {
-		numa_setup_cpu((unsigned long)cpu);
-	}
+	cpuhp_setup_state(CPUHP_POWER_NUMA_PREPARE, "POWER_NUMA_PREPARE",
+			  ppc_numa_cpu_prepare, ppc_numa_cpu_dead);
 }
 
 static int __init early_numa(char *p)
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -14,6 +14,7 @@ enum cpuhp_state {
 	CPUHP_PERF_SUPERH,
 	CPUHP_X86_HPET_DEAD,
 	CPUHP_WORKQUEUE_PREP,
+	CPUHP_POWER_NUMA_PREPARE,
 	CPUHP_NOTIFY_PREPARE,
 	CPUHP_BRINGUP_CPU,
 	CPUHP_AP_IDLE_DEAD,

[toc] | [prev] | [next] | [standalone]


#1440596 — [patch 27/66] workqueue: Convert to state machine callbacks

FromAnna-Maria Gleixner <anna-maria@linutronix.de>
Date2016-07-11 14:50 +0200
Subject[patch 27/66] workqueue: Convert to state machine callbacks
Message-ID<rTIOT-762-61@gated-at.bofh.it>
In reply to#1440594
Get rid of the prio ordering of the separate notifiers and use a proper state
callback pair.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Tejun Heo <tj@kernel.org>
Cc: Lai Jiangshan <jiangshanlai@gmail.com>
Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>
---
 include/linux/cpu.h        |    9 ---
 include/linux/cpuhotplug.h |    2 
 include/linux/workqueue.h  |    6 ++
 kernel/cpu.c               |   10 ++++
 kernel/workqueue.c         |  108 +++++++++++++++++----------------------------
 5 files changed, 61 insertions(+), 74 deletions(-)

--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -55,15 +55,6 @@ extern ssize_t arch_cpu_release(const ch
 #endif
 struct notifier_block;
 
-/*
- * CPU notifier priorities.
- */
-enum {
-	/* bring up workqueues before normal notifiers and down after */
-	CPU_PRI_WORKQUEUE_UP	= 5,
-	CPU_PRI_WORKQUEUE_DOWN	= -5,
-};
-
 #define CPU_ONLINE		0x0002 /* CPU (unsigned)v is up */
 #define CPU_UP_PREPARE		0x0003 /* CPU (unsigned)v coming up */
 #define CPU_UP_CANCELED		0x0004 /* CPU (unsigned)v NOT coming up */
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -12,6 +12,7 @@ enum cpuhp_state {
 	CPUHP_PERF_BFIN,
 	CPUHP_PERF_POWER,
 	CPUHP_PERF_SUPERH,
+	CPUHP_WORKQUEUE_PREP,
 	CPUHP_NOTIFY_PREPARE,
 	CPUHP_BRINGUP_CPU,
 	CPUHP_AP_IDLE_DEAD,
@@ -48,6 +49,7 @@ enum cpuhp_state {
 	CPUHP_AP_PERF_S390_SF_ONLINE,
 	CPUHP_AP_PERF_ARM_CCI_ONLINE,
 	CPUHP_AP_PERF_ARM_CCN_ONLINE,
+	CPUHP_AP_WORKQUEUE_ONLINE,
 	CPUHP_AP_NOTIFY_ONLINE,
 	CPUHP_AP_ONLINE_DYN,
 	CPUHP_AP_ONLINE_DYN_END		= CPUHP_AP_ONLINE_DYN + 30,
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -625,4 +625,10 @@ void wq_watchdog_touch(int cpu);
 static inline void wq_watchdog_touch(int cpu) { }
 #endif	/* CONFIG_WQ_WATCHDOG */
 
+#ifdef CONFIG_SMP
+int workqueue_prepare_cpu(unsigned int cpu);
+int workqueue_online_cpu(unsigned int cpu);
+int workqueue_offline_cpu(unsigned int cpu);
+#endif
+
 #endif
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1178,6 +1178,11 @@ static struct cpuhp_step cpuhp_bp_states
 		.startup = perf_event_init_cpu,
 		.teardown = perf_event_exit_cpu,
 	},
+	[CPUHP_WORKQUEUE_PREP] = {
+		.name = "workqueue prepare",
+		.startup = workqueue_prepare_cpu,
+		.teardown = NULL,
+	},
 	/*
 	 * Preparatory and dead notifiers. Will be replaced once the notifiers
 	 * are converted to states.
@@ -1258,6 +1263,11 @@ static struct cpuhp_step cpuhp_ap_states
 		.startup = perf_event_init_cpu,
 		.teardown = perf_event_exit_cpu,
 	},
+	[CPUHP_AP_WORKQUEUE_ONLINE] = {
+		.name = "workqueue online",
+		.startup = workqueue_online_cpu,
+		.teardown = workqueue_offline_cpu,
+	},
 
 	/*
 	 * Online/down_prepare notifiers. Will be removed once the notifiers
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -4611,84 +4611,65 @@ static void restore_unbound_workers_cpum
 						  pool->attrs->cpumask) < 0);
 }
 
-/*
- * Workqueues should be brought up before normal priority CPU notifiers.
- * This will be registered high priority CPU notifier.
- */
-static int workqueue_cpu_up_callback(struct notifier_block *nfb,
-					       unsigned long action,
-					       void *hcpu)
+int workqueue_prepare_cpu(unsigned int cpu)
+{
+	struct worker_pool *pool;
+
+	for_each_cpu_worker_pool(pool, cpu) {
+		if (pool->nr_workers)
+			continue;
+		if (!create_worker(pool))
+			return -ENOMEM;
+	}
+	return 0;
+}
+
+int workqueue_online_cpu(unsigned int cpu)
 {
-	int cpu = (unsigned long)hcpu;
 	struct worker_pool *pool;
 	struct workqueue_struct *wq;
 	int pi;
 
-	switch (action & ~CPU_TASKS_FROZEN) {
-	case CPU_UP_PREPARE:
-		for_each_cpu_worker_pool(pool, cpu) {
-			if (pool->nr_workers)
-				continue;
-			if (!create_worker(pool))
-				return NOTIFY_BAD;
-		}
-		break;
-
-	case CPU_DOWN_FAILED:
-	case CPU_ONLINE:
-		mutex_lock(&wq_pool_mutex);
+	mutex_lock(&wq_pool_mutex);
 
-		for_each_pool(pool, pi) {
-			mutex_lock(&pool->attach_mutex);
+	for_each_pool(pool, pi) {
+		mutex_lock(&pool->attach_mutex);
 
-			if (pool->cpu == cpu)
-				rebind_workers(pool);
-			else if (pool->cpu < 0)
-				restore_unbound_workers_cpumask(pool, cpu);
+		if (pool->cpu == cpu)
+			rebind_workers(pool);
+		else if (pool->cpu < 0)
+			restore_unbound_workers_cpumask(pool, cpu);
 
-			mutex_unlock(&pool->attach_mutex);
-		}
+		mutex_unlock(&pool->attach_mutex);
+	}
 
-		/* update NUMA affinity of unbound workqueues */
-		list_for_each_entry(wq, &workqueues, list)
-			wq_update_unbound_numa(wq, cpu, true);
+	/* update NUMA affinity of unbound workqueues */
+	list_for_each_entry(wq, &workqueues, list)
+		wq_update_unbound_numa(wq, cpu, true);
 
-		mutex_unlock(&wq_pool_mutex);
-		break;
-	}
-	return NOTIFY_OK;
+	mutex_unlock(&wq_pool_mutex);
+	return 0;
 }
 
-/*
- * Workqueues should be brought down after normal priority CPU notifiers.
- * This will be registered as low priority CPU notifier.
- */
-static int workqueue_cpu_down_callback(struct notifier_block *nfb,
-						 unsigned long action,
-						 void *hcpu)
+int workqueue_offline_cpu(unsigned int cpu)
 {
-	int cpu = (unsigned long)hcpu;
 	struct work_struct unbind_work;
 	struct workqueue_struct *wq;
 
-	switch (action & ~CPU_TASKS_FROZEN) {
-	case CPU_DOWN_PREPARE:
-		/* unbinding per-cpu workers should happen on the local CPU */
-		INIT_WORK_ONSTACK(&unbind_work, wq_unbind_fn);
-		queue_work_on(cpu, system_highpri_wq, &unbind_work);
-
-		/* update NUMA affinity of unbound workqueues */
-		mutex_lock(&wq_pool_mutex);
-		list_for_each_entry(wq, &workqueues, list)
-			wq_update_unbound_numa(wq, cpu, false);
-		mutex_unlock(&wq_pool_mutex);
-
-		/* wait for per-cpu unbinding to finish */
-		flush_work(&unbind_work);
-		destroy_work_on_stack(&unbind_work);
-		break;
-	}
-	return NOTIFY_OK;
+	/* unbinding per-cpu workers should happen on the local CPU */
+	INIT_WORK_ONSTACK(&unbind_work, wq_unbind_fn);
+	queue_work_on(cpu, system_highpri_wq, &unbind_work);
+
+	/* update NUMA affinity of unbound workqueues */
+	mutex_lock(&wq_pool_mutex);
+	list_for_each_entry(wq, &workqueues, list)
+		wq_update_unbound_numa(wq, cpu, false);
+	mutex_unlock(&wq_pool_mutex);
+
+	/* wait for per-cpu unbinding to finish */
+	flush_work(&unbind_work);
+	destroy_work_on_stack(&unbind_work);
+	return 0;
 }
 
 #ifdef CONFIG_SMP
@@ -5490,9 +5471,6 @@ static int __init init_workqueues(void)
 
 	pwq_cache = KMEM_CACHE(pool_workqueue, SLAB_PANIC);
 
-	cpu_notifier(workqueue_cpu_up_callback, CPU_PRI_WORKQUEUE_UP);
-	hotcpu_notifier(workqueue_cpu_down_callback, CPU_PRI_WORKQUEUE_DOWN);
-
 	wq_numa_init();
 
 	/* initialize CPU pools */

[toc] | [prev] | [next] | [standalone]


#1440653 — Re: [patch 27/66] workqueue: Convert to state machine callbacks

FromIngo Molnar <mingo@kernel.org>
Date2016-07-11 16:40 +0200
SubjectRe: [patch 27/66] workqueue: Convert to state machine callbacks
Message-ID<rTKxj-8gc-1@gated-at.bofh.it>
In reply to#1440596
* Anna-Maria Gleixner <anna-maria@linutronix.de> wrote:

> Get rid of the prio ordering of the separate notifiers and use a proper state
> callback pair.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Cc: Tejun Heo <tj@kernel.org>
> Cc: Lai Jiangshan <jiangshanlai@gmail.com>
> Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>

Same question - should I add:

  From: Thomas Gleixner <tglx@linutronix.de>

or:

  Acked-by: Thomas Gleixner <tglx@linutronix.de>

?

Thanks,

	Ingo

[toc] | [prev] | [next] | [standalone]


#1440690 — Re: [patch 27/66] workqueue: Convert to state machine callbacks

FromAnna-Maria Gleixner <anna-maria@linutronix.de>
Date2016-07-11 17:00 +0200
SubjectRe: [patch 27/66] workqueue: Convert to state machine callbacks
Message-ID<rTKQG-8n2-3@gated-at.bofh.it>
In reply to#1440653
On Mon, 11 Jul 2016, Ingo Molnar wrote:

> 
> * Anna-Maria Gleixner <anna-maria@linutronix.de> wrote:
> 
> > Get rid of the prio ordering of the separate notifiers and use a proper state
> > callback pair.
> > 
> > Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> > Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> > Cc: Tejun Heo <tj@kernel.org>
> > Cc: Lai Jiangshan <jiangshanlai@gmail.com>
> > Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>
> 
> Same question - should I add:
> 
>   From: Thomas Gleixner <tglx@linutronix.de>
> 

This is the right one. I'm sorry, the script failed...

Thanks,
	Anna-Maria

[toc] | [prev] | [next] | [standalone]


#1441454 — Re: [patch 27/66] workqueue: Convert to state machine callbacks

FromTejun Heo <tj@kernel.org>
Date2016-07-12 16:40 +0200
SubjectRe: [patch 27/66] workqueue: Convert to state machine callbacks
Message-ID<rU70T-6aC-63@gated-at.bofh.it>
In reply to#1440596
Hello,

On Mon, Jul 11, 2016 at 12:28:41PM -0000, Anna-Maria Gleixner wrote:
> Get rid of the prio ordering of the separate notifiers and use a proper state
> callback pair.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Cc: Tejun Heo <tj@kernel.org>
> Cc: Lai Jiangshan <jiangshanlai@gmail.com>
> Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>

Acked-by: Tejun Heo <tj@kernel.org>

Thanks.

-- 
tejun

[toc] | [prev] | [next] | [standalone]


#1440597 — [patch 37/66] clocksource/arm_arch_timer: Convert to hotplug state machine.

FromAnna-Maria Gleixner <anna-maria@linutronix.de>
Date2016-07-11 14:50 +0200
Subject[patch 37/66] clocksource/arm_arch_timer: Convert to hotplug state machine.
Message-ID<rTIOT-762-51@gated-at.bofh.it>
In reply to#1440594
From: Richard Cochran <rcochran@linutronix.de>

Install the callbacks via the state machine and let the core invoke
the callbacks on the already online CPUs.

Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 drivers/clocksource/arm_arch_timer.c |   54 ++++++++++++++++-------------------
 include/linux/cpuhotplug.h           |    1 
 2 files changed, 27 insertions(+), 28 deletions(-)

--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -362,8 +362,10 @@ static bool arch_timer_has_nonsecure_ppi
 		arch_timer_ppi[PHYS_NONSECURE_PPI]);
 }
 
-static int arch_timer_setup(struct clock_event_device *clk)
+static int arch_timer_starting_cpu(unsigned int cpu)
 {
+	struct clock_event_device *clk = this_cpu_ptr(arch_timer_evt);
+
 	__arch_timer_setup(ARCH_CP15_TIMER, clk);
 
 	enable_percpu_irq(arch_timer_ppi[arch_timer_uses_ppi], 0);
@@ -519,29 +521,14 @@ static void arch_timer_stop(struct clock
 	clk->set_state_shutdown(clk);
 }
 
-static int arch_timer_cpu_notify(struct notifier_block *self,
-					   unsigned long action, void *hcpu)
+static int arch_timer_dying_cpu(unsigned int cpu)
 {
-	/*
-	 * Grab cpu pointer in each case to avoid spurious
-	 * preemptible warnings
-	 */
-	switch (action & ~CPU_TASKS_FROZEN) {
-	case CPU_STARTING:
-		arch_timer_setup(this_cpu_ptr(arch_timer_evt));
-		break;
-	case CPU_DYING:
-		arch_timer_stop(this_cpu_ptr(arch_timer_evt));
-		break;
-	}
+	struct clock_event_device *clk = this_cpu_ptr(arch_timer_evt);
 
-	return NOTIFY_OK;
+	arch_timer_stop(clk);
+	return 0;
 }
 
-static struct notifier_block arch_timer_cpu_nb = {
-	.notifier_call = arch_timer_cpu_notify,
-};
-
 #ifdef CONFIG_CPU_PM
 static unsigned int saved_cntkctl;
 static int arch_timer_cpu_pm_notify(struct notifier_block *self,
@@ -562,11 +549,21 @@ static int __init arch_timer_cpu_pm_init
 {
 	return cpu_pm_register_notifier(&arch_timer_cpu_pm_notifier);
 }
+
+static void __init arch_timer_cpu_pm_deinit(void)
+{
+	WARN_ON(cpu_pm_unregister_notifier(&arch_timer_cpu_pm_notifier));
+}
+
 #else
 static int __init arch_timer_cpu_pm_init(void)
 {
 	return 0;
 }
+
+static void __init arch_timer_cpu_pm_deinit(void)
+{
+}
 #endif
 
 static int __init arch_timer_register(void)
@@ -613,22 +610,23 @@ static int __init arch_timer_register(vo
 		goto out_free;
 	}
 
-	err = register_cpu_notifier(&arch_timer_cpu_nb);
-	if (err)
-		goto out_free_irq;
-
 	err = arch_timer_cpu_pm_init();
 	if (err)
 		goto out_unreg_notify;
 
-	/* Immediately configure the timer on the boot CPU */
-	arch_timer_setup(this_cpu_ptr(arch_timer_evt));
 
+	/* Register and immediately configure the timer on the boot CPU */
+	err = cpuhp_setup_state(CPUHP_AP_ARM_ARCH_TIMER_STARTING,
+				"AP_ARM_ARCH_TIMER_STARTING",
+				arch_timer_starting_cpu, arch_timer_dying_cpu);
+	if (err)
+		goto out_unreg_cpupm;
 	return 0;
 
+out_unreg_cpupm:
+	arch_timer_cpu_pm_deinit();
+
 out_unreg_notify:
-	unregister_cpu_notifier(&arch_timer_cpu_nb);
-out_free_irq:
 	free_percpu_irq(arch_timer_ppi[arch_timer_uses_ppi], arch_timer_evt);
 	if (arch_timer_has_nonsecure_ppi())
 		free_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI],
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -37,6 +37,7 @@ enum cpuhp_state {
 	CPUHP_AP_PERF_XTENSA_STARTING,
 	CPUHP_AP_ARM_VFP_STARTING,
 	CPUHP_AP_PERF_ARM_STARTING,
+	CPUHP_AP_ARM_ARCH_TIMER_STARTING,
 	CPUHP_AP_KVM_STARTING,
 	CPUHP_AP_NOTIFY_STARTING,
 	CPUHP_AP_ONLINE,

[toc] | [prev] | [next] | [standalone]


#1440598 — [patch 39/66] clocksource/dummy_timer: Convert to hotplug state machine

FromAnna-Maria Gleixner <anna-maria@linutronix.de>
Date2016-07-11 14:50 +0200
Subject[patch 39/66] clocksource/dummy_timer: Convert to hotplug state machine
Message-ID<rTIOU-762-63@gated-at.bofh.it>
In reply to#1440594
Install the callbacks via the state machine and let the core invoke
the callbacks on the already online CPUs.

Signed-off-by: Richard Cochran <rcochran@linutronix.de>
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>
---
 drivers/clocksource/dummy_timer.c |   36 ++++++------------------------------
 include/linux/cpuhotplug.h        |    1 +
 2 files changed, 7 insertions(+), 30 deletions(-)

--- a/drivers/clocksource/dummy_timer.c
+++ b/drivers/clocksource/dummy_timer.c
@@ -16,10 +16,9 @@
 
 static DEFINE_PER_CPU(struct clock_event_device, dummy_timer_evt);
 
-static void dummy_timer_setup(void)
+static int dummy_timer_starting_cpu(unsigned int cpu)
 {
-	int cpu = smp_processor_id();
-	struct clock_event_device *evt = raw_cpu_ptr(&dummy_timer_evt);
+	struct clock_event_device *evt = per_cpu_ptr(&dummy_timer_evt, cpu);
 
 	evt->name	= "dummy_timer";
 	evt->features	= CLOCK_EVT_FEAT_PERIODIC |
@@ -29,36 +28,13 @@ static void dummy_timer_setup(void)
 	evt->cpumask	= cpumask_of(cpu);
 
 	clockevents_register_device(evt);
+	return 0;
 }
 
-static int dummy_timer_cpu_notify(struct notifier_block *self,
-				      unsigned long action, void *hcpu)
-{
-	if ((action & ~CPU_TASKS_FROZEN) == CPU_STARTING)
-		dummy_timer_setup();
-
-	return NOTIFY_OK;
-}
-
-static struct notifier_block dummy_timer_cpu_nb = {
-	.notifier_call = dummy_timer_cpu_notify,
-};
-
 static int __init dummy_timer_register(void)
 {
-	int err = 0;
-
-	cpu_notifier_register_begin();
-	err = __register_cpu_notifier(&dummy_timer_cpu_nb);
-	if (err)
-		goto out;
-
-	/* We won't get a call on the boot CPU, so register immediately */
-	if (num_possible_cpus() > 1)
-		dummy_timer_setup();
-
-out:
-	cpu_notifier_register_done();
-	return err;
+	return cpuhp_setup_state(CPUHP_AP_DUMMY_TIMER_STARTING,
+				 "AP_DUMMY_TIMER_STARTING",
+				 dummy_timer_starting_cpu, NULL);
 }
 early_initcall(dummy_timer_register);
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -39,6 +39,7 @@ enum cpuhp_state {
 	CPUHP_AP_PERF_ARM_STARTING,
 	CPUHP_AP_ARM_ARCH_TIMER_STARTING,
 	CPUHP_AP_ARM_GLOBAL_TIMER_STARTING,
+	CPUHP_AP_DUMMY_TIMER_STARTING,
 	CPUHP_AP_KVM_STARTING,
 	CPUHP_AP_NOTIFY_STARTING,
 	CPUHP_AP_ONLINE,

[toc] | [prev] | [next] | [standalone]


#1440599 — [patch 32/66] x86/apb_timer: Convert to hotplug state machine

FromAnna-Maria Gleixner <anna-maria@linutronix.de>
Date2016-07-11 14:50 +0200
Subject[patch 32/66] x86/apb_timer: Convert to hotplug state machine
Message-ID<rTIOU-762-71@gated-at.bofh.it>
In reply to#1440594
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>

Install the callbacks via the state machine. There is no setup just one
teardown callback. Remove the silly comment about the workqueue up dependency.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>
---
 arch/x86/kernel/apb_timer.c |   29 ++++++++++-------------------
 include/linux/cpuhotplug.h  |    1 +
 2 files changed, 11 insertions(+), 19 deletions(-)

--- a/arch/x86/kernel/apb_timer.c
+++ b/arch/x86/kernel/apb_timer.c
@@ -215,26 +215,18 @@ void apbt_setup_secondary_clock(void)
  * cpu timers during the offline process due to the ordering of notification.
  * the extra interrupt is harmless.
  */
-static int apbt_cpuhp_notify(struct notifier_block *n,
-			     unsigned long action, void *hcpu)
+static int apbt_cpu_dead(unsigned int cpu)
 {
-	unsigned long cpu = (unsigned long)hcpu;
 	struct apbt_dev *adev = &per_cpu(cpu_apbt_dev, cpu);
 
-	switch (action & ~CPU_TASKS_FROZEN) {
-	case CPU_DEAD:
-		dw_apb_clockevent_pause(adev->timer);
-		if (system_state == SYSTEM_RUNNING) {
-			pr_debug("skipping APBT CPU %lu offline\n", cpu);
-		} else {
-			pr_debug("APBT clockevent for cpu %lu offline\n", cpu);
-			dw_apb_clockevent_stop(adev->timer);
-		}
-		break;
-	default:
-		pr_debug("APBT notified %lu, no action\n", action);
+	dw_apb_clockevent_pause(adev->timer);
+	if (system_state == SYSTEM_RUNNING) {
+		pr_debug("skipping APBT CPU %u offline\n", cpu);
+	} else {
+		pr_debug("APBT clockevent for cpu %u offline\n", cpu);
+		dw_apb_clockevent_stop(adev->timer);
 	}
-	return NOTIFY_OK;
+	return 0;
 }
 
 static __init int apbt_late_init(void)
@@ -242,9 +234,8 @@ static __init int apbt_late_init(void)
 	if (intel_mid_timer_options == INTEL_MID_TIMER_LAPIC_APBT ||
 		!apb_timer_block_enabled)
 		return 0;
-	/* This notifier should be called after workqueue is ready */
-	hotcpu_notifier(apbt_cpuhp_notify, -20);
-	return 0;
+	return cpuhp_setup_state(CPUHP_X86_APB_DEAD, "X86_APB_DEAD", NULL,
+				 apbt_cpu_dead);
 }
 fs_initcall(apbt_late_init);
 #else
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -13,6 +13,7 @@ enum cpuhp_state {
 	CPUHP_PERF_POWER,
 	CPUHP_PERF_SUPERH,
 	CPUHP_X86_HPET_DEAD,
+	CPUHP_X86_APB_DEAD,
 	CPUHP_WORKQUEUE_PREP,
 	CPUHP_POWER_NUMA_PREPARE,
 	CPUHP_NOTIFY_PREPARE,

[toc] | [prev] | [next] | [standalone]


#1440600 — [patch 20/66] sh: perf: Convert the hotplug notifiers to state machine callbacks

FromAnna-Maria Gleixner <anna-maria@linutronix.de>
Date2016-07-11 14:50 +0200
Subject[patch 20/66] sh: perf: Convert the hotplug notifiers to state machine callbacks
Message-ID<rTIOU-762-65@gated-at.bofh.it>
In reply to#1440594
From: Thomas Gleixner <tglx@linutronix.de>

Install the callbacks via the state machine and let the core invoke
the callbacks on the already online CPUs.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-sh@vger.kernel.org
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>

---
 arch/sh/kernel/perf_event.c |   23 ++++-------------------
 include/linux/cpuhotplug.h  |    1 +
 2 files changed, 5 insertions(+), 19 deletions(-)

--- a/arch/sh/kernel/perf_event.c
+++ b/arch/sh/kernel/perf_event.c
@@ -352,28 +352,12 @@ static struct pmu pmu = {
 	.read		= sh_pmu_read,
 };
 
-static void sh_pmu_setup(int cpu)
+static int sh_pmu_prepare_cpu(unsigned int cpu)
 {
 	struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu);
 
 	memset(cpuhw, 0, sizeof(struct cpu_hw_events));
-}
-
-static int
-sh_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
-{
-	unsigned int cpu = (long)hcpu;
-
-	switch (action & ~CPU_TASKS_FROZEN) {
-	case CPU_UP_PREPARE:
-		sh_pmu_setup(cpu);
-		break;
-
-	default:
-		break;
-	}
-
-	return NOTIFY_OK;
+	return 0;
 }
 
 int register_sh_pmu(struct sh_pmu *_pmu)
@@ -394,6 +378,7 @@ int register_sh_pmu(struct sh_pmu *_pmu)
 	WARN_ON(_pmu->num_events > MAX_HWEVENTS);
 
 	perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW);
-	perf_cpu_notifier(sh_pmu_notifier);
+	cpuhp_setup_state(CPUHP_PERF_SUPERH, "PERF_SUPERH", sh_pmu_prepare_cpu,
+			  NULL);
 	return 0;
 }
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -11,6 +11,7 @@ enum cpuhp_state {
 	CPUHP_PERF_X86_RAPL_PREP,
 	CPUHP_PERF_BFIN,
 	CPUHP_PERF_POWER,
+	CPUHP_PERF_SUPERH,
 	CPUHP_NOTIFY_PREPARE,
 	CPUHP_BRINGUP_CPU,
 	CPUHP_AP_IDLE_DEAD,

[toc] | [prev] | [next] | [standalone]


#1440601 — [patch 16/66] blackfin: perf: Convert hotplug notifier to state machine

FromAnna-Maria Gleixner <anna-maria@linutronix.de>
Date2016-07-11 14:50 +0200
Subject[patch 16/66] blackfin: perf: Convert hotplug notifier to state machine
Message-ID<rTIOU-762-69@gated-at.bofh.it>
In reply to#1440594
From: Thomas Gleixner <tglx@linutronix.de>

Install the callback via the state machine and let the core invoke
the callbacks on the already online CPUs.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Steven Miao <realmz6@gmail.com>
Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>
---
 arch/blackfin/kernel/perf_event.c |   26 +++++---------------------
 include/linux/cpuhotplug.h        |    1 +
 2 files changed, 6 insertions(+), 21 deletions(-)

--- a/arch/blackfin/kernel/perf_event.c
+++ b/arch/blackfin/kernel/perf_event.c
@@ -453,29 +453,13 @@ static struct pmu pmu = {
 	.read        = bfin_pmu_read,
 };
 
-static void bfin_pmu_setup(int cpu)
+static int bfin_pmu_prepare_cpu(unsigned int cpu)
 {
 	struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu);
 
+	bfin_write_PFCTL(0);
 	memset(cpuhw, 0, sizeof(struct cpu_hw_events));
-}
-
-static int
-bfin_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
-{
-	unsigned int cpu = (long)hcpu;
-
-	switch (action & ~CPU_TASKS_FROZEN) {
-	case CPU_UP_PREPARE:
-		bfin_write_PFCTL(0);
-		bfin_pmu_setup(cpu);
-		break;
-
-	default:
-		break;
-	}
-
-	return NOTIFY_OK;
+	return 0;
 }
 
 static int __init bfin_pmu_init(void)
@@ -491,8 +475,8 @@ static int __init bfin_pmu_init(void)
 
 	ret = perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW);
 	if (!ret)
-		perf_cpu_notifier(bfin_pmu_notifier);
-
+		cpuhp_setup_state(CPUHP_PERF_BFIN, "PERF_BFIN",
+				  bfin_pmu_prepare_cpu, NULL);
 	return ret;
 }
 early_initcall(bfin_pmu_init);
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -9,6 +9,7 @@ enum cpuhp_state {
 	CPUHP_PERF_X86_UNCORE_PREP,
 	CPUHP_PERF_X86_AMD_UNCORE_PREP,
 	CPUHP_PERF_X86_RAPL_PREP,
+	CPUHP_PERF_BFIN,
 	CPUHP_NOTIFY_PREPARE,
 	CPUHP_BRINGUP_CPU,
 	CPUHP_AP_IDLE_DEAD,

[toc] | [prev] | [next] | [standalone]


#1440602 — [patch 11/66] perf/x86/amd/uncore: Convert to hotplug state machine

FromAnna-Maria Gleixner <anna-maria@linutronix.de>
Date2016-07-11 14:50 +0200
Subject[patch 11/66] perf/x86/amd/uncore: Convert to hotplug state machine
Message-ID<rTIOU-762-75@gated-at.bofh.it>
In reply to#1440594
From: Richard Cochran <rcochran@linutronix.de>

Install the callbacks via the state machine and let the core invoke
the callbacks on the already online CPUs.

Signed-off-by: Richard Cochran <rcochran@linutronix.de>
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>
---

 arch/x86/events/amd/uncore.c |  122 +++++++++++--------------------------------
 include/linux/cpuhotplug.h   |    3 +
 2 files changed, 35 insertions(+), 90 deletions(-)

--- a/arch/x86/events/amd/uncore.c
+++ b/arch/x86/events/amd/uncore.c
@@ -358,7 +358,7 @@ amd_uncore_find_online_sibling(struct am
 	return this;
 }
 
-static void amd_uncore_cpu_starting(unsigned int cpu)
+static int amd_uncore_cpu_starting(unsigned int cpu)
 {
 	unsigned int eax, ebx, ecx, edx;
 	struct amd_uncore *uncore;
@@ -384,6 +384,8 @@ static void amd_uncore_cpu_starting(unsi
 		uncore = amd_uncore_find_online_sibling(uncore, amd_uncore_l2);
 		*per_cpu_ptr(amd_uncore_l2, cpu) = uncore;
 	}
+
+	return 0;
 }
 
 static void uncore_online(unsigned int cpu,
@@ -398,13 +400,15 @@ static void uncore_online(unsigned int c
 		cpumask_set_cpu(cpu, uncore->active_mask);
 }
 
-static void amd_uncore_cpu_online(unsigned int cpu)
+static int amd_uncore_cpu_online(unsigned int cpu)
 {
 	if (amd_uncore_nb)
 		uncore_online(cpu, amd_uncore_nb);
 
 	if (amd_uncore_l2)
 		uncore_online(cpu, amd_uncore_l2);
+
+	return 0;
 }
 
 static void uncore_down_prepare(unsigned int cpu,
@@ -433,13 +437,15 @@ static void uncore_down_prepare(unsigned
 	}
 }
 
-static void amd_uncore_cpu_down_prepare(unsigned int cpu)
+static int amd_uncore_cpu_down_prepare(unsigned int cpu)
 {
 	if (amd_uncore_nb)
 		uncore_down_prepare(cpu, amd_uncore_nb);
 
 	if (amd_uncore_l2)
 		uncore_down_prepare(cpu, amd_uncore_l2);
+
+	return 0;
 }
 
 static void uncore_dead(unsigned int cpu, struct amd_uncore * __percpu *uncores)
@@ -454,74 +460,19 @@ static void uncore_dead(unsigned int cpu
 	*per_cpu_ptr(uncores, cpu) = NULL;
 }
 
-static void amd_uncore_cpu_dead(unsigned int cpu)
+static int amd_uncore_cpu_dead(unsigned int cpu)
 {
 	if (amd_uncore_nb)
 		uncore_dead(cpu, amd_uncore_nb);
 
 	if (amd_uncore_l2)
 		uncore_dead(cpu, amd_uncore_l2);
-}
-
-static int
-amd_uncore_cpu_notifier(struct notifier_block *self, unsigned long action,
-			void *hcpu)
-{
-	unsigned int cpu = (long)hcpu;
-
-	switch (action & ~CPU_TASKS_FROZEN) {
-	case CPU_UP_PREPARE:
-		if (amd_uncore_cpu_up_prepare(cpu))
-			return notifier_from_errno(-ENOMEM);
-		break;
-
-	case CPU_STARTING:
-		amd_uncore_cpu_starting(cpu);
-		break;
-
-	case CPU_ONLINE:
-		amd_uncore_cpu_online(cpu);
-		break;
-
-	case CPU_DOWN_PREPARE:
-		amd_uncore_cpu_down_prepare(cpu);
-		break;
-
-	case CPU_UP_CANCELED:
-	case CPU_DEAD:
-		amd_uncore_cpu_dead(cpu);
-		break;
-
-	default:
-		break;
-	}
-
-	return NOTIFY_OK;
-}
-
-static struct notifier_block amd_uncore_cpu_notifier_block = {
-	.notifier_call	= amd_uncore_cpu_notifier,
-	.priority	= CPU_PRI_PERF + 1,
-};
-
-static void __init init_cpu_already_online(void *dummy)
-{
-	unsigned int cpu = smp_processor_id();
-
-	amd_uncore_cpu_starting(cpu);
-	amd_uncore_cpu_online(cpu);
-}
-
-static void cleanup_cpu_online(void *dummy)
-{
-	unsigned int cpu = smp_processor_id();
 
-	amd_uncore_cpu_dead(cpu);
+	return 0;
 }
 
 static int __init amd_uncore_init(void)
 {
-	unsigned int cpu, cpu2;
 	int ret = -ENODEV;
 
 	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
@@ -558,38 +509,29 @@ static int __init amd_uncore_init(void)
 		ret = 0;
 	}
 
-	if (ret)
-		goto fail_nodev;
-
-	cpu_notifier_register_begin();
-
-	/* init cpus already online before registering for hotplug notifier */
-	for_each_online_cpu(cpu) {
-		ret = amd_uncore_cpu_up_prepare(cpu);
-		if (ret)
-			goto fail_online;
-		smp_call_function_single(cpu, init_cpu_already_online, NULL, 1);
-	}
-
-	__register_cpu_notifier(&amd_uncore_cpu_notifier_block);
-	cpu_notifier_register_done();
-
+	/*
+	 * Install callbacks. Core will call them for each online cpu.
+	 */
+	if (cpuhp_setup_state(CPUHP_PERF_X86_AMD_UNCORE_PREP,
+			      "PERF_X86_AMD_UNCORE_PREP",
+			      amd_uncore_cpu_up_prepare, amd_uncore_cpu_dead))
+		goto fail_l2;
+
+	if (cpuhp_setup_state(CPUHP_AP_PERF_X86_AMD_UNCORE_STARTING,
+			      "AP_PERF_X86_AMD_UNCORE_STARTING",
+			      amd_uncore_cpu_starting, NULL))
+		goto fail_prep;
+	if (cpuhp_setup_state(CPUHP_AP_PERF_X86_AMD_UNCORE_ONLINE,
+			      "AP_PERF_X86_AMD_UNCORE_ONLINE",
+			      amd_uncore_cpu_online,
+			      amd_uncore_cpu_down_prepare))
+		goto fail_start;
 	return 0;
 
-
-fail_online:
-	for_each_online_cpu(cpu2) {
-		if (cpu2 == cpu)
-			break;
-		smp_call_function_single(cpu, cleanup_cpu_online, NULL, 1);
-	}
-	cpu_notifier_register_done();
-
-	/* amd_uncore_nb/l2 should have been freed by cleanup_cpu_online */
-	amd_uncore_nb = amd_uncore_l2 = NULL;
-
-	if (boot_cpu_has(X86_FEATURE_PERFCTR_L2))
-		perf_pmu_unregister(&amd_l2_pmu);
+fail_start:
+	cpuhp_remove_state(CPUHP_AP_PERF_X86_AMD_UNCORE_STARTING);
+fail_prep:
+	cpuhp_remove_state(CPUHP_PERF_X86_AMD_UNCORE_PREP);
 fail_l2:
 	if (boot_cpu_has(X86_FEATURE_PERFCTR_NB))
 		perf_pmu_unregister(&amd_nb_pmu);
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -7,6 +7,7 @@ enum cpuhp_state {
 	CPUHP_PERF_PREPARE,
 	CPUHP_PERF_X86_PREPARE,
 	CPUHP_PERF_X86_UNCORE_PREP,
+	CPUHP_PERF_X86_AMD_UNCORE_PREP,
 	CPUHP_NOTIFY_PREPARE,
 	CPUHP_BRINGUP_CPU,
 	CPUHP_AP_IDLE_DEAD,
@@ -20,6 +21,7 @@ enum cpuhp_state {
 	CPUHP_AP_IRQ_BCM2836_STARTING,
 	CPUHP_AP_ARM_MVEBU_COHERENCY,
 	CPUHP_AP_PERF_X86_UNCORE_STARTING,
+	CPUHP_AP_PERF_X86_AMD_UNCORE_STARTING,
 	CPUHP_AP_PERF_X86_STARTING,
 	CPUHP_AP_NOTIFY_STARTING,
 	CPUHP_AP_ONLINE,
@@ -30,6 +32,7 @@ enum cpuhp_state {
 	CPUHP_AP_PERF_ONLINE,
 	CPUHP_AP_PERF_X86_ONLINE,
 	CPUHP_AP_PERF_X86_UNCORE_ONLINE,
+	CPUHP_AP_PERF_X86_AMD_UNCORE_ONLINE,
 	CPUHP_AP_NOTIFY_ONLINE,
 	CPUHP_AP_ONLINE_DYN,
 	CPUHP_AP_ONLINE_DYN_END		= CPUHP_AP_ONLINE_DYN + 30,

[toc] | [prev] | [next] | [standalone]


#1440603 — [patch 14/66] perf/x86/intel/cqm: Convert Intel CQM to hotplug state machine

FromAnna-Maria Gleixner <anna-maria@linutronix.de>
Date2016-07-11 14:50 +0200
Subject[patch 14/66] perf/x86/intel/cqm: Convert Intel CQM to hotplug state machine
Message-ID<rTIOU-762-77@gated-at.bofh.it>
In reply to#1440594
From: Richard Cochran <rcochran@linutronix.de>

Install the callbacks via the state machine and let the core invoke
the callbacks on the already online CPUs.

Signed-off-by: Richard Cochran <rcochran@linutronix.de>
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>
---
 arch/x86/events/intel/cqm.c |   49 ++++++++++++++++----------------------------
 include/linux/cpuhotplug.h  |    2 +
 2 files changed, 20 insertions(+), 31 deletions(-)

--- a/arch/x86/events/intel/cqm.c
+++ b/arch/x86/events/intel/cqm.c
@@ -1577,7 +1577,7 @@ static inline void cqm_pick_event_reader
 		cpumask_set_cpu(cpu, &cqm_cpumask);
 }
 
-static void intel_cqm_cpu_starting(unsigned int cpu)
+static int intel_cqm_cpu_starting(unsigned int cpu)
 {
 	struct intel_pqr_state *state = &per_cpu(pqr_state, cpu);
 	struct cpuinfo_x86 *c = &cpu_data(cpu);
@@ -1588,39 +1588,26 @@ static void intel_cqm_cpu_starting(unsig
 
 	WARN_ON(c->x86_cache_max_rmid != cqm_max_rmid);
 	WARN_ON(c->x86_cache_occ_scale != cqm_l3_scale);
+
+	cqm_pick_event_reader(cpu);
+	return 0;
 }
 
-static void intel_cqm_cpu_exit(unsigned int cpu)
+static int intel_cqm_cpu_exit(unsigned int cpu)
 {
 	int target;
 
 	/* Is @cpu the current cqm reader for this package ? */
 	if (!cpumask_test_and_clear_cpu(cpu, &cqm_cpumask))
-		return;
+		return 0;
 
 	/* Find another online reader in this package */
 	target = cpumask_any_but(topology_core_cpumask(cpu), cpu);
 
 	if (target < nr_cpu_ids)
 		cpumask_set_cpu(target, &cqm_cpumask);
-}
-
-static int intel_cqm_cpu_notifier(struct notifier_block *nb,
-				  unsigned long action, void *hcpu)
-{
-	unsigned int cpu  = (unsigned long)hcpu;
-
-	switch (action & ~CPU_TASKS_FROZEN) {
-	case CPU_DOWN_PREPARE:
-		intel_cqm_cpu_exit(cpu);
-		break;
-	case CPU_STARTING:
-		intel_cqm_cpu_starting(cpu);
-		cqm_pick_event_reader(cpu);
-		break;
-	}
 
-	return NOTIFY_OK;
+	return 0;
 }
 
 static const struct x86_cpu_id intel_cqm_match[] = {
@@ -1682,7 +1669,7 @@ static int intel_mbm_init(void)
 static int __init intel_cqm_init(void)
 {
 	char *str = NULL, scale[20];
-	int i, cpu, ret;
+	int cpu, ret;
 
 	if (x86_match_cpu(intel_cqm_match))
 		cqm_enabled = true;
@@ -1705,8 +1692,7 @@ static int __init intel_cqm_init(void)
 	 *
 	 * Also, check that the scales match on all cpus.
 	 */
-	cpu_notifier_register_begin();
-
+	get_online_cpus();
 	for_each_online_cpu(cpu) {
 		struct cpuinfo_x86 *c = &cpu_data(cpu);
 
@@ -1743,11 +1729,6 @@ static int __init intel_cqm_init(void)
 	if (ret)
 		goto out;
 
-	for_each_online_cpu(i) {
-		intel_cqm_cpu_starting(i);
-		cqm_pick_event_reader(i);
-	}
-
 	if (mbm_enabled)
 		ret = intel_mbm_init();
 	if (ret && !cqm_enabled)
@@ -1772,12 +1753,18 @@ static int __init intel_cqm_init(void)
 		pr_info("Intel MBM enabled\n");
 
 	/*
-	 * Register the hot cpu notifier once we are sure cqm
+	 * Setup the hot cpu notifier once we are sure cqm
 	 * is enabled to avoid notifier leak.
 	 */
-	__perf_cpu_notifier(intel_cqm_cpu_notifier);
+	cpuhp_setup_state(CPUHP_AP_PERF_X86_CQM_STARTING,
+			  "AP_PERF_X86_CQM_STARTING",
+			  intel_cqm_cpu_starting, NULL);
+	cpuhp_setup_state(CPUHP_AP_PERF_X86_CQM_ONLINE, "AP_PERF_X86_CQM_ONLINE",
+			  NULL, intel_cqm_cpu_exit);
+
 out:
-	cpu_notifier_register_done();
+	put_online_cpus();
+
 	if (ret) {
 		kfree(str);
 		cqm_cleanup();
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -25,6 +25,7 @@ enum cpuhp_state {
 	CPUHP_AP_PERF_X86_AMD_UNCORE_STARTING,
 	CPUHP_AP_PERF_X86_STARTING,
 	CPUHP_AP_PERF_X86_AMD_IBS_STARTING,
+	CPUHP_AP_PERF_X86_CQM_STARTING,
 	CPUHP_AP_NOTIFY_STARTING,
 	CPUHP_AP_ONLINE,
 	CPUHP_TEARDOWN_CPU,
@@ -36,6 +37,7 @@ enum cpuhp_state {
 	CPUHP_AP_PERF_X86_UNCORE_ONLINE,
 	CPUHP_AP_PERF_X86_AMD_UNCORE_ONLINE,
 	CPUHP_AP_PERF_X86_RAPL_ONLINE,
+	CPUHP_AP_PERF_X86_CQM_ONLINE,
 	CPUHP_AP_NOTIFY_ONLINE,
 	CPUHP_AP_ONLINE_DYN,
 	CPUHP_AP_ONLINE_DYN_END		= CPUHP_AP_ONLINE_DYN + 30,

[toc] | [prev] | [next] | [standalone]


#1440604 — [patch 01/66] x86/vdso: Convert to hotplug state machine

FromAnna-Maria Gleixner <anna-maria@linutronix.de>
Date2016-07-11 14:50 +0200
Subject[patch 01/66] x86/vdso: Convert to hotplug state machine
Message-ID<rTIOU-762-73@gated-at.bofh.it>
In reply to#1440594
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>

Install the callbacks via the state machine and let the core invoke
the callbacks on the already online CPUs.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: x86@kernel.org
Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>
---
 arch/x86/entry/vdso/vma.c  |   20 ++++----------------
 include/linux/cpuhotplug.h |    1 +
 2 files changed, 5 insertions(+), 16 deletions(-)

--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -294,15 +294,9 @@ static void vgetcpu_cpu_init(void *arg)
 	write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_PER_CPU, &d, DESCTYPE_S);
 }
 
-static int
-vgetcpu_cpu_notifier(struct notifier_block *n, unsigned long action, void *arg)
+static int vgetcpu_online(unsigned int cpu)
 {
-	long cpu = (long)arg;
-
-	if (action == CPU_ONLINE || action == CPU_ONLINE_FROZEN)
-		smp_call_function_single(cpu, vgetcpu_cpu_init, NULL, 1);
-
-	return NOTIFY_DONE;
+	return smp_call_function_single(cpu, vgetcpu_cpu_init, NULL, 1);
 }
 
 static int __init init_vdso(void)
@@ -313,15 +307,9 @@ static int __init init_vdso(void)
 	init_vdso_image(&vdso_image_x32);
 #endif
 
-	cpu_notifier_register_begin();
-
-	on_each_cpu(vgetcpu_cpu_init, NULL, 1);
 	/* notifier priority > KVM */
-	__hotcpu_notifier(vgetcpu_cpu_notifier, 30);
-
-	cpu_notifier_register_done();
-
-	return 0;
+	return cpuhp_setup_state(CPUHP_AP_X86_VDSO_VMA_ONLINE,
+				 "AP_X86_VDSO_VMA_ONLINE", vgetcpu_online, NULL);
 }
 subsys_initcall(init_vdso);
 #endif /* CONFIG_X86_64 */
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -14,6 +14,7 @@ enum cpuhp_state {
 	CPUHP_TEARDOWN_CPU,
 	CPUHP_AP_ONLINE_IDLE,
 	CPUHP_AP_SMPBOOT_THREADS,
+	CPUHP_AP_X86_VDSO_VMA_ONLINE,
 	CPUHP_AP_NOTIFY_ONLINE,
 	CPUHP_AP_ONLINE_DYN,
 	CPUHP_AP_ONLINE_DYN_END		= CPUHP_AP_ONLINE_DYN + 30,

[toc] | [prev] | [next] | [standalone]


#1440822 — Re: [patch 01/66] x86/vdso: Convert to hotplug state machine

FromAndy Lutomirski <luto@amacapital.net>
Date2016-07-11 21:00 +0200
SubjectRe: [patch 01/66] x86/vdso: Convert to hotplug state machine
Message-ID<rTOAW-2pF-25@gated-at.bofh.it>
In reply to#1440604
On Mon, Jul 11, 2016 at 5:28 AM, Anna-Maria Gleixner
<anna-maria@linutronix.de> wrote:
> From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
>
> Install the callbacks via the state machine and let the core invoke
> the callbacks on the already online CPUs.

Acked-by: Andy Lutomirski <luto@kernel.org>

[toc] | [prev] | [next] | [standalone]


#1440605 — [patch 08/66] perf: Convert to hotplug state machine

FromAnna-Maria Gleixner <anna-maria@linutronix.de>
Date2016-07-11 14:50 +0200
Subject[patch 08/66] perf: Convert to hotplug state machine
Message-ID<rTIOU-762-79@gated-at.bofh.it>
In reply to#1440594
From: Thomas Gleixner <tglx@linutronix.de>

Actually a nice symmetric startup/teardown pair which fits proper in
the state machine concept. In the long run we should be able to invoke
the startup callback for the boot CPU via the state machine and get
rid of the init function which invokes it on the boot CPU.

Note: This comes actually before the perf hardware callbacks. In the notifier
model the hardware callbacks have a higher priority than the core
callback. But that's solely for cpu offline so that hardware migration of
events happens before the core is notified about the outgoing cpu.

With the symetric state array model we have the ordering

UP:     core -> hardware 
DOWN:	hardware -> core

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Sebastian Siewior <bigeasy@linutronix.de>
Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>

---
 include/linux/cpuhotplug.h |    2 +
 include/linux/perf_event.h |    9 +++++++
 kernel/cpu.c               |   11 ++++++++
 kernel/events/core.c       |   56 ++++++++-------------------------------------
 4 files changed, 32 insertions(+), 46 deletions(-)

--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -4,6 +4,7 @@
 enum cpuhp_state {
 	CPUHP_OFFLINE,
 	CPUHP_CREATE_THREADS,
+	CPUHP_PERF_PREPARE,
 	CPUHP_NOTIFY_PREPARE,
 	CPUHP_BRINGUP_CPU,
 	CPUHP_AP_IDLE_DEAD,
@@ -22,6 +23,7 @@ enum cpuhp_state {
 	CPUHP_AP_ONLINE_IDLE,
 	CPUHP_AP_SMPBOOT_THREADS,
 	CPUHP_AP_X86_VDSO_VMA_ONLINE,
+	CPUHP_AP_PERF_ONLINE,
 	CPUHP_AP_NOTIFY_ONLINE,
 	CPUHP_AP_ONLINE_DYN,
 	CPUHP_AP_ONLINE_DYN_END		= CPUHP_AP_ONLINE_DYN + 30,
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1354,4 +1354,13 @@ static ssize_t								\
 									\
 static struct device_attribute format_attr_##_name = __ATTR_RO(_name)
 
+/* Performance counter hotplug functions */
+#ifdef CONFIG_PERF_EVENTS
+int perf_event_init_cpu(unsigned int cpu);
+int perf_event_exit_cpu(unsigned int cpu);
+#else
+#define perf_event_init_cpu	NULL
+#define perf_event_exit_cpu	NULL
+#endif
+
 #endif /* _LINUX_PERF_EVENT_H */
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1173,6 +1173,11 @@ static struct cpuhp_step cpuhp_bp_states
 		.teardown		= NULL,
 		.cant_stop		= true,
 	},
+	[CPUHP_PERF_PREPARE] = {
+		.name = "perf prepare",
+		.startup = perf_event_init_cpu,
+		.teardown = perf_event_exit_cpu,
+	},
 	/*
 	 * Preparatory and dead notifiers. Will be replaced once the notifiers
 	 * are converted to states.
@@ -1248,6 +1253,12 @@ static struct cpuhp_step cpuhp_ap_states
 		.startup		= smpboot_unpark_threads,
 		.teardown		= NULL,
 	},
+	[CPUHP_AP_PERF_ONLINE] = {
+		.name = "perf online",
+		.startup = perf_event_init_cpu,
+		.teardown = perf_event_exit_cpu,
+	},
+
 	/*
 	 * Online/down_prepare notifiers. Will be removed once the notifiers
 	 * are converted to states.
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -10255,7 +10255,7 @@ static void __init perf_event_init_all_c
 	}
 }
 
-static void perf_event_init_cpu(int cpu)
+int perf_event_init_cpu(unsigned int cpu)
 {
 	struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu);
 
@@ -10268,6 +10268,7 @@ static void perf_event_init_cpu(int cpu)
 		rcu_assign_pointer(swhash->swevent_hlist, hlist);
 	}
 	mutex_unlock(&swhash->hlist_mutex);
+	return 0;
 }
 
 #if defined CONFIG_HOTPLUG_CPU || defined CONFIG_KEXEC_CORE
@@ -10299,14 +10300,17 @@ static void perf_event_exit_cpu_context(
 	}
 	srcu_read_unlock(&pmus_srcu, idx);
 }
+#else
+
+static void perf_event_exit_cpu_context(int cpu) { }
+
+#endif
 
-static void perf_event_exit_cpu(int cpu)
+int perf_event_exit_cpu(unsigned int cpu)
 {
 	perf_event_exit_cpu_context(cpu);
+	return 0;
 }
-#else
-static inline void perf_event_exit_cpu(int cpu) { }
-#endif
 
 static int
 perf_reboot(struct notifier_block *notifier, unsigned long val, void *v)
@@ -10328,46 +10332,6 @@ static struct notifier_block perf_reboot
 	.priority = INT_MIN,
 };
 
-static int
-perf_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu)
-{
-	unsigned int cpu = (long)hcpu;
-
-	switch (action & ~CPU_TASKS_FROZEN) {
-
-	case CPU_UP_PREPARE:
-		/*
-		 * This must be done before the CPU comes alive, because the
-		 * moment we can run tasks we can encounter (software) events.
-		 *
-		 * Specifically, someone can have inherited events on kthreadd
-		 * or a pre-existing worker thread that gets re-bound.
-		 */
-		perf_event_init_cpu(cpu);
-		break;
-
-	case CPU_DOWN_PREPARE:
-		/*
-		 * This must be done before the CPU dies because after that an
-		 * active event might want to IPI the CPU and that'll not work
-		 * so great for dead CPUs.
-		 *
-		 * XXX smp_call_function_single() return -ENXIO without a warn
-		 * so we could possibly deal with this.
-		 *
-		 * This is safe against new events arriving because
-		 * sys_perf_event_open() serializes against hotplug using
-		 * get_online_cpus().
-		 */
-		perf_event_exit_cpu(cpu);
-		break;
-	default:
-		break;
-	}
-
-	return NOTIFY_OK;
-}
-
 void __init perf_event_init(void)
 {
 	int ret;
@@ -10380,7 +10344,7 @@ void __init perf_event_init(void)
 	perf_pmu_register(&perf_cpu_clock, NULL, -1);
 	perf_pmu_register(&perf_task_clock, NULL, -1);
 	perf_tp_register();
-	perf_cpu_notifier(perf_cpu_notify);
+	perf_event_init_cpu(smp_processor_id());
 	register_reboot_notifier(&perf_reboot_notifier);
 
 	ret = init_hw_breakpoint();

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web