diff options
Diffstat (limited to 'kernel/sched/core.c')
| -rw-r--r-- | kernel/sched/core.c | 56 | 
1 files changed, 56 insertions, 0 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index f895fdd32c5..8322d73b439 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -6190,10 +6190,65 @@ static void sched_init_numa(void)  	sched_domains_numa_levels = level;  } + +static void sched_domains_numa_masks_set(int cpu) +{ +	int i, j; +	int node = cpu_to_node(cpu); + +	for (i = 0; i < sched_domains_numa_levels; i++) { +		for (j = 0; j < nr_node_ids; j++) { +			if (node_distance(j, node) <= sched_domains_numa_distance[i]) +				cpumask_set_cpu(cpu, sched_domains_numa_masks[i][j]); +		} +	} +} + +static void sched_domains_numa_masks_clear(int cpu) +{ +	int i, j; +	for (i = 0; i < sched_domains_numa_levels; i++) { +		for (j = 0; j < nr_node_ids; j++) +			cpumask_clear_cpu(cpu, sched_domains_numa_masks[i][j]); +	} +} + +/* + * Update sched_domains_numa_masks[level][node] array when new cpus + * are onlined. + */ +static int sched_domains_numa_masks_update(struct notifier_block *nfb, +					   unsigned long action, +					   void *hcpu) +{ +	int cpu = (long)hcpu; + +	switch (action & ~CPU_TASKS_FROZEN) { +	case CPU_ONLINE: +		sched_domains_numa_masks_set(cpu); +		break; + +	case CPU_DEAD: +		sched_domains_numa_masks_clear(cpu); +		break; + +	default: +		return NOTIFY_DONE; +	} + +	return NOTIFY_OK; +}  #else  static inline void sched_init_numa(void)  {  } + +static int sched_domains_numa_masks_update(struct notifier_block *nfb, +					   unsigned long action, +					   void *hcpu) +{ +	return 0; +}  #endif /* CONFIG_NUMA */  static int __sdt_alloc(const struct cpumask *cpu_map) @@ -6642,6 +6697,7 @@ void __init sched_init_smp(void)  	mutex_unlock(&sched_domains_mutex);  	put_online_cpus(); +	hotcpu_notifier(sched_domains_numa_masks_update, CPU_PRI_SCHED_ACTIVE);  	hotcpu_notifier(cpuset_cpu_active, CPU_PRI_CPUSET_ACTIVE);  	hotcpu_notifier(cpuset_cpu_inactive, CPU_PRI_CPUSET_INACTIVE);  |