Skip to content

Commit 135fb3e

Browse files
committed
sched: Consolidate the notifier maze
We can maintain the ordering of the scheduler cpu hotplug functionality nicely in one notifer. Get rid of the maze. Signed-off-by: Thomas Gleixner <[email protected]> Acked-by: Peter Zijlstra <[email protected]> Cc: [email protected] Signed-off-by: Thomas Gleixner <[email protected]>
1 parent e26fbff commit 135fb3e

File tree

2 files changed

+73
-113
lines changed

2 files changed

+73
-113
lines changed

include/linux/cpu.h

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,19 +61,15 @@ struct notifier_block;
6161
enum {
6262
/*
6363
* SCHED_ACTIVE marks a cpu which is coming up active during
64-
* CPU_ONLINE and CPU_DOWN_FAILED and must be the first
65-
* notifier. CPUSET_ACTIVE adjusts cpuset according to
66-
* cpu_active mask right after SCHED_ACTIVE. During
67-
* CPU_DOWN_PREPARE, SCHED_INACTIVE and CPUSET_INACTIVE are
68-
* ordered in the similar way.
64+
* CPU_ONLINE and CPU_DOWN_FAILED and must be the first notifier. Is
65+
* also cpuset according to cpu_active mask right after activating the
66+
* cpu. During CPU_DOWN_PREPARE, SCHED_INACTIVE reversed the operation.
6967
*
7068
* This ordering guarantees consistent cpu_active mask and
7169
* migration behavior to all cpu notifiers.
7270
*/
7371
CPU_PRI_SCHED_ACTIVE = INT_MAX,
74-
CPU_PRI_CPUSET_ACTIVE = INT_MAX - 1,
75-
CPU_PRI_SCHED_INACTIVE = INT_MIN + 1,
76-
CPU_PRI_CPUSET_INACTIVE = INT_MIN,
72+
CPU_PRI_SCHED_INACTIVE = INT_MIN,
7773

7874
/* migration should happen before other stuff but after perf */
7975
CPU_PRI_PERF = 20,

kernel/sched/core.c

Lines changed: 69 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -5482,39 +5482,6 @@ static void set_cpu_rq_start_time(unsigned int cpu)
54825482
rq->age_stamp = sched_clock_cpu(cpu);
54835483
}
54845484

5485-
static int sched_cpu_active(struct notifier_block *nfb,
5486-
unsigned long action, void *hcpu)
5487-
{
5488-
int cpu = (long)hcpu;
5489-
5490-
switch (action & ~CPU_TASKS_FROZEN) {
5491-
case CPU_DOWN_FAILED:
5492-
set_cpu_active(cpu, true);
5493-
return NOTIFY_OK;
5494-
5495-
default:
5496-
return NOTIFY_DONE;
5497-
}
5498-
}
5499-
5500-
static int sched_cpu_inactive(struct notifier_block *nfb,
5501-
unsigned long action, void *hcpu)
5502-
{
5503-
switch (action & ~CPU_TASKS_FROZEN) {
5504-
case CPU_DOWN_PREPARE:
5505-
set_cpu_active((long)hcpu, false);
5506-
return NOTIFY_OK;
5507-
default:
5508-
return NOTIFY_DONE;
5509-
}
5510-
}
5511-
5512-
int sched_cpu_starting(unsigned int cpu)
5513-
{
5514-
set_cpu_rq_start_time(cpu);
5515-
return 0;
5516-
}
5517-
55185485
static cpumask_var_t sched_domains_tmpmask; /* sched_domains_mutex */
55195486

55205487
#ifdef CONFIG_SCHED_DEBUG
@@ -6662,10 +6629,13 @@ static void sched_init_numa(void)
66626629
init_numa_topology_type();
66636630
}
66646631

6665-
static void sched_domains_numa_masks_set(int cpu)
6632+
static void sched_domains_numa_masks_set(unsigned int cpu)
66666633
{
6667-
int i, j;
66686634
int node = cpu_to_node(cpu);
6635+
int i, j;
6636+
6637+
if (!sched_smp_initialized)
6638+
return;
66696639

66706640
for (i = 0; i < sched_domains_numa_levels; i++) {
66716641
for (j = 0; j < nr_node_ids; j++) {
@@ -6675,54 +6645,23 @@ static void sched_domains_numa_masks_set(int cpu)
66756645
}
66766646
}
66776647

6678-
static void sched_domains_numa_masks_clear(int cpu)
6648+
static void sched_domains_numa_masks_clear(unsigned int cpu)
66796649
{
66806650
int i, j;
6651+
6652+
if (!sched_smp_initialized)
6653+
return;
6654+
66816655
for (i = 0; i < sched_domains_numa_levels; i++) {
66826656
for (j = 0; j < nr_node_ids; j++)
66836657
cpumask_clear_cpu(cpu, sched_domains_numa_masks[i][j]);
66846658
}
66856659
}
66866660

6687-
/*
6688-
* Update sched_domains_numa_masks[level][node] array when new cpus
6689-
* are onlined.
6690-
*/
6691-
static int sched_domains_numa_masks_update(struct notifier_block *nfb,
6692-
unsigned long action,
6693-
void *hcpu)
6694-
{
6695-
int cpu = (long)hcpu;
6696-
6697-
if (!sched_smp_initialized)
6698-
return NOTIFY_DONE;
6699-
6700-
switch (action & ~CPU_TASKS_FROZEN) {
6701-
case CPU_ONLINE:
6702-
sched_domains_numa_masks_set(cpu);
6703-
break;
6704-
6705-
case CPU_DEAD:
6706-
sched_domains_numa_masks_clear(cpu);
6707-
break;
6708-
6709-
default:
6710-
return NOTIFY_DONE;
6711-
}
6712-
6713-
return NOTIFY_OK;
6714-
}
67156661
#else
6716-
static inline void sched_init_numa(void)
6717-
{
6718-
}
6719-
6720-
static int sched_domains_numa_masks_update(struct notifier_block *nfb,
6721-
unsigned long action,
6722-
void *hcpu)
6723-
{
6724-
return 0;
6725-
}
6662+
static inline void sched_init_numa(void) { }
6663+
static void sched_domains_numa_masks_set(unsigned int cpu) { }
6664+
static void sched_domains_numa_masks_clear(unsigned int cpu) { }
67266665
#endif /* CONFIG_NUMA */
67276666

67286667
static int __sdt_alloc(const struct cpumask *cpu_map)
@@ -7112,16 +7051,12 @@ static int num_cpus_frozen; /* used to mark begin/end of suspend/resume */
71127051
* If we come here as part of a suspend/resume, don't touch cpusets because we
71137052
* want to restore it back to its original state upon resume anyway.
71147053
*/
7115-
static int cpuset_cpu_active(struct notifier_block *nfb, unsigned long action,
7116-
void *hcpu)
7054+
static void cpuset_cpu_active(bool frozen)
71177055
{
71187056
if (!sched_smp_initialized)
7119-
return NOTIFY_DONE;
7120-
7121-
switch (action) {
7122-
case CPU_ONLINE_FROZEN:
7123-
case CPU_DOWN_FAILED_FROZEN:
7057+
return;
71247058

7059+
if (frozen) {
71257060
/*
71267061
* num_cpus_frozen tracks how many CPUs are involved in suspend
71277062
* resume sequence. As long as this is not the last online
@@ -7131,38 +7066,28 @@ static int cpuset_cpu_active(struct notifier_block *nfb, unsigned long action,
71317066
num_cpus_frozen--;
71327067
if (likely(num_cpus_frozen)) {
71337068
partition_sched_domains(1, NULL, NULL);
7134-
break;
7069+
return;
71357070
}
7136-
71377071
/*
71387072
* This is the last CPU online operation. So fall through and
71397073
* restore the original sched domains by considering the
71407074
* cpuset configurations.
71417075
*/
7142-
7143-
case CPU_ONLINE:
7144-
cpuset_update_active_cpus(true);
7145-
break;
7146-
default:
7147-
return NOTIFY_DONE;
71487076
}
7149-
return NOTIFY_OK;
7077+
cpuset_update_active_cpus(true);
71507078
}
71517079

7152-
static int cpuset_cpu_inactive(struct notifier_block *nfb, unsigned long action,
7153-
void *hcpu)
7080+
static int cpuset_cpu_inactive(unsigned int cpu, bool frozen)
71547081
{
71557082
unsigned long flags;
7156-
long cpu = (long)hcpu;
71577083
struct dl_bw *dl_b;
71587084
bool overflow;
71597085
int cpus;
71607086

71617087
if (!sched_smp_initialized)
7162-
return NOTIFY_DONE;
7088+
return 0;
71637089

7164-
switch (action) {
7165-
case CPU_DOWN_PREPARE:
7090+
if (!frozen) {
71667091
rcu_read_lock_sched();
71677092
dl_b = dl_bw_of(cpu);
71687093

@@ -7174,17 +7099,60 @@ static int cpuset_cpu_inactive(struct notifier_block *nfb, unsigned long action,
71747099
rcu_read_unlock_sched();
71757100

71767101
if (overflow)
7177-
return notifier_from_errno(-EBUSY);
7102+
return -EBUSY;
71787103
cpuset_update_active_cpus(false);
7179-
break;
7180-
case CPU_DOWN_PREPARE_FROZEN:
7104+
} else {
71817105
num_cpus_frozen++;
71827106
partition_sched_domains(1, NULL, NULL);
7183-
break;
7107+
}
7108+
return 0;
7109+
}
7110+
7111+
static int sched_cpu_active(struct notifier_block *nfb, unsigned long action,
7112+
void *hcpu)
7113+
{
7114+
unsigned int cpu = (unsigned long)hcpu;
7115+
7116+
switch (action & ~CPU_TASKS_FROZEN) {
7117+
case CPU_DOWN_FAILED:
7118+
case CPU_ONLINE:
7119+
set_cpu_active(cpu, true);
7120+
sched_domains_numa_masks_set(cpu);
7121+
cpuset_cpu_active(action & CPU_TASKS_FROZEN);
7122+
return NOTIFY_OK;
71847123
default:
71857124
return NOTIFY_DONE;
71867125
}
7187-
return NOTIFY_OK;
7126+
}
7127+
7128+
static int sched_cpu_inactive(struct notifier_block *nfb,
7129+
unsigned long action, void *hcpu)
7130+
{
7131+
unsigned int cpu = (unsigned long)hcpu;
7132+
int ret;
7133+
7134+
switch (action & ~CPU_TASKS_FROZEN) {
7135+
case CPU_DOWN_PREPARE:
7136+
set_cpu_active(cpu, false);
7137+
ret = cpuset_cpu_inactive(cpu, action & CPU_TASKS_FROZEN);
7138+
if (ret) {
7139+
set_cpu_active(cpu, true);
7140+
return notifier_from_errno(ret);
7141+
}
7142+
return NOTIFY_OK;
7143+
7144+
case CPU_DEAD:
7145+
sched_domains_numa_masks_clear(cpu);
7146+
return NOTIFY_OK;
7147+
default:
7148+
return NOTIFY_DONE;
7149+
}
7150+
}
7151+
7152+
int sched_cpu_starting(unsigned int cpu)
7153+
{
7154+
set_cpu_rq_start_time(cpu);
7155+
return 0;
71887156
}
71897157

71907158
void __init sched_init_smp(void)
@@ -7236,10 +7204,6 @@ static int __init migration_init(void)
72367204
cpu_notifier(sched_cpu_active, CPU_PRI_SCHED_ACTIVE);
72377205
cpu_notifier(sched_cpu_inactive, CPU_PRI_SCHED_INACTIVE);
72387206

7239-
hotcpu_notifier(sched_domains_numa_masks_update, CPU_PRI_SCHED_ACTIVE);
7240-
hotcpu_notifier(cpuset_cpu_active, CPU_PRI_CPUSET_ACTIVE);
7241-
hotcpu_notifier(cpuset_cpu_inactive, CPU_PRI_CPUSET_INACTIVE);
7242-
72437207
return 0;
72447208
}
72457209
early_initcall(migration_init);

0 commit comments

Comments
 (0)