Skip to content

CPU hotplug rework - episode I

Thomas Gleixner lkml 1 version In review

Get series with b4
b4 am [email protected]

Versions newest first

  1. v1 Latest40 patches 26 repliesIn review

Patches in v1 No applies recorded yet

#Subject and filesSizeRepliesApplied
1/40smpboot: Allow selfparking per cpu threadsinclude/linux/smpboot.h kernel/smpboot.c+8 -22 replies
2/40stop_machine: Store task reference in a separate per cpu variablekernel/stop_machine.c+16 -162 replies
3/40stop_machine: Use smpboot threadskernel/cpu.c kernel/stop_machine.c+51 -852 replies
4/40cpu: Restructure FROZEN state handlingkernel/cpu.c+27 -392 replies
5/40cpu: Restructure cpu_down codekernel/cpu.c+47 -222 replies
6/40cpu: hotplug: Split out cpu down functionskernel/cpu.c+53 -301 reply
7/40cpu: hotplug: Convert to a state machine for the control processorinclude/linux/cpu.h include/linux/cpuhotplug.h init/main.c +3 more+173 -521 reply
8/40cpu: hotplug: Convert the hotplugged processor work to a state machineinclude/linux/cpuhotplug.h kernel/cpu.c+59 -151 reply
9/40cpu: hotplug: Implement setup/removal interfaceinclude/linux/cpu.h include/linux/cpuhotplug.h kernel/cpu.c+255 -12 replies
10/40sched: Convert to state machine callbacksinclude/linux/cpu.h include/linux/cpuhotplug.h kernel/cpu.c +1 more+69 -1111 reply
11/40x86: uncore: Move teardown callback to CPU_DEADarch/x86/kernel/cpu/perf_event_intel_uncore.c+3 -30 replies
12/40x86: uncore: Convert to hotplug state machinearch/x86/kernel/cpu/perf_event_intel_uncore.c include/linux/cpuhotplug.h+30 -820 replies
13/40perf: Convert to hotplug state machineinclude/linux/cpuhotplug.h kernel/cpu.c kernel/events/core.c+26 -290 replies
14/40x86: perf: Convert the core to the hotplug state machinearch/x86/kernel/cpu/perf_event.c arch/x86/kernel/cpu/perf_event_amd.c arch/x86/kernel/cpu/perf_event_intel.c +1 more+52 -410 replies
15/40x86: perf: Convert AMD IBS to hotplug state machinearch/x86/kernel/cpu/perf_event_amd_ibs.c include/linux/cpuhotplug.h+21 -340 replies
16/40blackfin: perf: Convert hotplug notifier to state machinearch/blackfin/kernel/perf_event.c include/linux/cpuhotplug.h+5 -210 replies
17/40powerpc: perf: Convert book3s notifier to state machine callbacksarch/powerpc/perf/core-book3s.c include/linux/cpuhotplug.h+7 -230 replies
18/40s390: perf: Convert the hotplug notifier to state machine callbacksarch/s390/kernel/perf_cpum_cf.c include/linux/cpuhotplug.h+16 -220 replies
19/40sh: perf: Convert the hotplug notifiers to state machine callbacksarch/sh/kernel/perf_event.c include/linux/cpuhotplug.h+4 -190 replies
20/40perf: Remove perf cpu notifier codeinclude/linux/cpu.h include/linux/perf_event.h+0 -230 replies
21/40sched: Convert the migration callback to hotplug statesinclude/linux/cpu.h include/linux/cpuhotplug.h kernel/cpu.c +1 more+68 -610 replies
22/40workqueue: Convert to state machine callbacksinclude/linux/cpu.h include/linux/cpuhotplug.h kernel/cpu.c +1 more+44 -590 replies
23/40cpufreq: Convert to hotplug state machinedrivers/cpufreq/cpufreq_stats.c include/linux/cpuhotplug.h+15 -420 replies
24/40arm64: Convert generic timers to hotplug state machinedrivers/clocksource/arm_generic.c include/linux/cpuhotplug.h+13 -280 replies
25/40arm: Convert VFP hotplug notifiers to state machinearch/arm/vfp/vfpmodule.c include/linux/cpuhotplug.h+18 -120 replies
26/40arm: perf: Convert to hotplug state machinearch/arm/kernel/perf_event_cpu.c include/linux/cpuhotplug.h+6 -230 replies
27/40virt: Convert kvm hotplug to state machineinclude/linux/cpuhotplug.h virt/kvm/kvm_main.c+17 -260 replies
28/40cpuhotplug: Remove CPU_STARTING notifierinclude/linux/cpu.h include/linux/cpuhotplug.h kernel/cpu.c+1 -190 replies
29/40s390: Convert vtime to hotplug state machinearch/s390/kernel/vtime.c include/linux/cpuhotplug.h+6 -130 replies
30/40x86: tboot: Convert to hotplug state machinearch/x86/kernel/tboot.c include/linux/cpuhotplug.h+8 -160 replies
31/40sched: Convert fair nohz balancer to hotplug state machineinclude/linux/cpuhotplug.h kernel/cpu.c kernel/sched/fair.c+12 -140 replies
32/40rcu: Convert rcutree to hotplug state machineinclude/linux/cpuhotplug.h kernel/cpu.c kernel/rcutree.c+73 -522 replies
33/40hrtimer: Convert to hotplug state machineinclude/linux/cpuhotplug.h kernel/cpu.c kernel/hrtimer.c +1 more+48 -420 replies
34/40cpuhotplug: Remove CPU_DYING notifierinclude/linux/cpu.h include/linux/cpuhotplug.h kernel/cpu.c+0 -180 replies
35/40timers: Convert to hotplug state machineinclude/linux/cpuhotplug.h kernel/cpu.c kernel/timer.c+13 -380 replies
36/40profile: Convert ot hotplug state machineinclude/linux/cpuhotplug.h kernel/cpu.c kernel/profile.c+63 -490 replies
37/40x86: x2apic: Convert to cpu hotplug state machinearch/x86/kernel/apic/x2apic_cluster.c include/linux/cpuhotplug.h+31 -500 replies
38/40smp: Convert core to hotplug state machineinclude/linux/cpuhotplug.h kernel/cpu.c kernel/smp.c+27 -320 replies
39/40relayfs: Convert to hotplug state machineinclude/linux/cpuhotplug.h kernel/cpu.c kernel/relay.c+25 -450 replies
40/40slab: Convert to hotplug state machineinclude/linux/cpuhotplug.h kernel/cpu.c mm/slab.c+64 -610 replies

Reviews trailers per patch

9 of 40 patches have a Reviewed-by or Acked-by.

PatchPaul E. McKenney
1/40R-b
2/40R-b
3/40R-b
4/40R-b
5/40R-b
6/40R-b
7/40R-b
8/40R-b
9/40
10/40R-b
11/40
12/40
13/40
14/40
15/40
16/40
17/40
18/40
19/40
20/40
21/40
22/40
23/40
24/40
25/40
26/40
27/40
28/40
29/40
30/40
31/40
32/40
33/40
34/40
35/40
36/40
37/40
38/40
39/40
40/40

Trailers given in replies are filled; those carried in the patches from earlier versions are outlined with dashes.

Read the v1 thread

Cover letter [patch 00/40] CPU hotplug rework - episode I

The current CPU hotplug implementation has become an increasing nightmare full of races and undocumented behaviour. The main issue of the current hotplug scheme is the completely asymetric startup/teardown process. The hotplug notifiers are mostly undocumented and the CPU_* actions in lots of implementations seem to be randomly chosen.

We had a long discussion in San Diego last year about reworking the hotplug core into a fully symetric state machine. After a few doomed attempts to convert the existing code into a state machine, I finally found a workable solution.

The following patch series implements a trivial array based state machine, which replaces the existing steps in cpu_up/down and also the notifiers which must run on the hotplugged cpu are converted to a callback array. This documents clearly the ordering of the callbacks and also makes the asymetric behaviour very obvious.

This series converts the stop_machine thread to the smpboot infrastructure, implements the core state machine and converts all notifiers which have ordering constraints plus a randomly chosen bunch of other notifiers to the state machine.

The runtime installed callbacks are immediately executed by the core code on or on behalf of all cpus which have already reached the corresponding state. A non executing installer function is there as well to allow simple migration of the existing notifier maze.

The diffstat of the complete series is appended below.

 36 files changed, 1300 insertions(+), 1179 deletions(-)

We add slightly more code at this stage (225 lines alone in a header file), but most of the conversions are removing code and we have only tackled about 30 of 130+ instances. Even with the current conversion state, the resulting text size shrinks already.

Known issues:
The current series has a not yet solved section mismatch issue versus the array callbacks which are already installed at compile time.

There is more work in the pipeline:

- Convert all notifiers to the state machine callbacks

- Analyze the asymetric callbacks and fix them if possible or at least document why they need to be asymetric.

- Unify the low level bringup across the architectures (e.g. synchronization between boot and hotplugged cpus, common setups, scheduler exposure, etc.)

At the end hotplug should run through an array of callbacks on both sides with explicit core synchronization points. The ordering should look like this:

CPUHP_OFFLINE                   // Start state.
CPUHP_PREP_<hardware>           // Kick CPU into life / let it die
CPUHP_PREP_<datastructures>     // Get datastructures set up / freed.
CPUHP_PREP_<threads>            // Create threads for cpu

CPUHP_SYNC // Synchronization point
CPUHP_INIT_<hardware> // Startup/teardown on the CPU (interrupts, timers ...)
CPUHP_SCHED_<stuff on CPU> // Unpark/park per cpu local threads on the CPU.
CPUHP_ENABLE_<stuff_on_CPU> // Enable/disable facilities
CPUHP_SYNC // Synchronization point
CPUHP_SCHED // Expose/remove CPU from general scheduler.
CPUHP_ONLINE // Final state

All PREP states can fail and the corresponding teardown callbacks are invoked in the same way as they are invoked on offlining.

The existing DOWN_PREPARE notifier has only two instances which actually might prevent the CPU from going down: rcu_tree and padata. We might need to keep them, but these can be explicitly documented asymetric states.

Quite some of the ONLINE/DOWN_PREPARE notifiers are racy and need a proper inspection. All other valid users of ONLINE/DOWN_PREPARE notifiers should be put into the CPUHP_ENABLE state block and be executed on the hotplugged CPU. I have not seen a single instance (except scheduler) which needs to be executed before we remove the CPU from the general scheduler itself.

This final design needs quite some massaging of the current scheduler code, but last time I discussed this with scheduler folks it seemed to be doable with a reasonable effort. Other than that I don't see any (un)real showstoppers on the horizon.

Thanks,

tglx

---
 arch/arm/kernel/perf_event_cpu.c              |   28 -
 arch/arm/vfp/vfpmodule.c                      |   29 -
 arch/blackfin/kernel/perf_event.c             |   25 -
 arch/powerpc/perf/core-book3s.c               |   29 -
 arch/s390/kernel/perf_cpum_cf.c               |   37 -
 arch/s390/kernel/vtime.c                      |   18 
 arch/sh/kernel/perf_event.c                   |   22 
 arch/x86/kernel/apic/x2apic_cluster.c         |   80 +--
 arch/x86/kernel/cpu/perf_event.c              |   78 +--
 arch/x86/kernel/cpu/perf_event_amd.c          |    6 
 arch/x86/kernel/cpu/perf_event_amd_ibs.c      |   54 --
 arch/x86/kernel/cpu/perf_event_intel.c        |    6 
 arch/x86/kernel/cpu/perf_event_intel_uncore.c |  109 +---
 arch/x86/kernel/tboot.c                       |   23 
 drivers/clocksource/arm_generic.c             |   40 -
 drivers/cpufreq/cpufreq_stats.c               |   55 --
 include/linux/cpu.h                           |   45 -
 include/linux/cpuhotplug.h                    |  207 ++++++++
 include/linux/perf_event.h                    |   21 
 include/linux/smpboot.h                       |    5 
 init/main.c                                   |   15 
 kernel/cpu.c                                  |  613 ++++++++++++++++++++++----
 kernel/events/core.c                          |   36 -
 kernel/hrtimer.c                              |   47 -
 kernel/profile.c                              |   92 +--
 kernel/rcutree.c                              |   95 +---
 kernel/sched/core.c                           |  251 ++++------
 kernel/sched/fair.c                           |   16 
 kernel/smp.c                                  |   50 --
 kernel/smpboot.c                              |   11 
 kernel/smpboot.h                              |    4 
 kernel/stop_machine.c                         |  154 ++----
 kernel/time/clockevents.c                     |   13 
 kernel/timer.c                                |   43 -
 kernel/workqueue.c                            |   80 +--
 virt/kvm/kvm_main.c                           |   42 -
 36 files changed, 1300 insertions(+), 1179 deletions(-)