mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	sched, cpuset: customize sched domains, core
[rebased for sched-devel/latest]
 - Add a new cpuset file, having levels:
     sched_relax_domain_level
 - Modify partition_sched_domains() and build_sched_domains()
   to take attributes parameter passed from cpuset.
 - Fill newidle_idx for node domains which currently unused but
   might be required if sched_relax_domain_level become higher.
 - We can change the default level by boot option 'relax_domain_level='.
Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
			
			
This commit is contained in:
		
							parent
							
								
									4d5f35533f
								
							
						
					
					
						commit
						1d3504fcf5
					
				
					 7 changed files with 161 additions and 11 deletions
				
			
		|  | @ -93,7 +93,7 @@ void build_cpu_to_node_map(void); | |||
| 	.cache_nice_tries	= 2,			\ | ||||
| 	.busy_idx		= 3,			\ | ||||
| 	.idle_idx		= 2,			\ | ||||
| 	.newidle_idx		= 0, /* unused */	\ | ||||
| 	.newidle_idx		= 2,			\ | ||||
| 	.wake_idx		= 1,			\ | ||||
| 	.forkexec_idx		= 1,			\ | ||||
| 	.flags			= SD_LOAD_BALANCE	\ | ||||
|  |  | |||
|  | @ -16,7 +16,7 @@ | |||
| 	.cache_nice_tries	= 2,			\ | ||||
| 	.busy_idx		= 3,			\ | ||||
| 	.idle_idx		= 2,			\ | ||||
| 	.newidle_idx		= 0,			\ | ||||
| 	.newidle_idx		= 2,			\ | ||||
| 	.wake_idx		= 1,			\ | ||||
| 	.forkexec_idx		= 1,			\ | ||||
| 	.flags			= SD_LOAD_BALANCE	\ | ||||
|  |  | |||
|  | @ -147,7 +147,7 @@ extern unsigned long node_remap_size[]; | |||
| 
 | ||||
| # define SD_CACHE_NICE_TRIES	2 | ||||
| # define SD_IDLE_IDX		2 | ||||
| # define SD_NEWIDLE_IDX		0 | ||||
| # define SD_NEWIDLE_IDX		2 | ||||
| # define SD_FORKEXEC_IDX	1 | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -704,6 +704,7 @@ enum cpu_idle_type { | |||
| #define SD_POWERSAVINGS_BALANCE	256	/* Balance for power savings */ | ||||
| #define SD_SHARE_PKG_RESOURCES	512	/* Domain members share cpu pkg resources */ | ||||
| #define SD_SERIALIZE		1024	/* Only a single load balancing instance */ | ||||
| #define SD_WAKE_IDLE_FAR	2048	/* Gain latency sacrificing cache hit */ | ||||
| 
 | ||||
| #define BALANCE_FOR_MC_POWER	\ | ||||
| 	(sched_smt_power_savings ? SD_POWERSAVINGS_BALANCE : 0) | ||||
|  | @ -733,6 +734,24 @@ struct sched_group { | |||
| 	u32 reciprocal_cpu_power; | ||||
| }; | ||||
| 
 | ||||
| enum sched_domain_level { | ||||
| 	SD_LV_NONE = 0, | ||||
| 	SD_LV_SIBLING, | ||||
| 	SD_LV_MC, | ||||
| 	SD_LV_CPU, | ||||
| 	SD_LV_NODE, | ||||
| 	SD_LV_ALLNODES, | ||||
| 	SD_LV_MAX | ||||
| }; | ||||
| 
 | ||||
| struct sched_domain_attr { | ||||
| 	int relax_domain_level; | ||||
| }; | ||||
| 
 | ||||
| #define SD_ATTR_INIT	(struct sched_domain_attr) {	\ | ||||
| 	.relax_domain_level = -1,			\ | ||||
| } | ||||
| 
 | ||||
| struct sched_domain { | ||||
| 	/* These fields must be setup */ | ||||
| 	struct sched_domain *parent;	/* top domain must be null terminated */ | ||||
|  | @ -750,6 +769,7 @@ struct sched_domain { | |||
| 	unsigned int wake_idx; | ||||
| 	unsigned int forkexec_idx; | ||||
| 	int flags;			/* See SD_* */ | ||||
| 	enum sched_domain_level level; | ||||
| 
 | ||||
| 	/* Runtime fields. */ | ||||
| 	unsigned long last_balance;	/* init to jiffies. units in jiffies */ | ||||
|  | @ -789,7 +809,8 @@ struct sched_domain { | |||
| #endif | ||||
| }; | ||||
| 
 | ||||
| extern void partition_sched_domains(int ndoms_new, cpumask_t *doms_new); | ||||
| extern void partition_sched_domains(int ndoms_new, cpumask_t *doms_new, | ||||
| 				    struct sched_domain_attr *dattr_new); | ||||
| extern int arch_reinit_sched_domains(void); | ||||
| 
 | ||||
| #endif	/* CONFIG_SMP */ | ||||
|  |  | |||
|  | @ -98,6 +98,9 @@ struct cpuset { | |||
| 	/* partition number for rebuild_sched_domains() */ | ||||
| 	int pn; | ||||
| 
 | ||||
| 	/* for custom sched domain */ | ||||
| 	int relax_domain_level; | ||||
| 
 | ||||
| 	/* used for walking a cpuset heirarchy */ | ||||
| 	struct list_head stack_list; | ||||
| }; | ||||
|  | @ -478,6 +481,16 @@ static int cpusets_overlap(struct cpuset *a, struct cpuset *b) | |||
| 	return cpus_intersects(a->cpus_allowed, b->cpus_allowed); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| update_domain_attr(struct sched_domain_attr *dattr, struct cpuset *c) | ||||
| { | ||||
| 	if (!dattr) | ||||
| 		return; | ||||
| 	if (dattr->relax_domain_level < c->relax_domain_level) | ||||
| 		dattr->relax_domain_level = c->relax_domain_level; | ||||
| 	return; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * rebuild_sched_domains() | ||||
|  * | ||||
|  | @ -553,12 +566,14 @@ static void rebuild_sched_domains(void) | |||
| 	int csn;		/* how many cpuset ptrs in csa so far */ | ||||
| 	int i, j, k;		/* indices for partition finding loops */ | ||||
| 	cpumask_t *doms;	/* resulting partition; i.e. sched domains */ | ||||
| 	struct sched_domain_attr *dattr;  /* attributes for custom domains */ | ||||
| 	int ndoms;		/* number of sched domains in result */ | ||||
| 	int nslot;		/* next empty doms[] cpumask_t slot */ | ||||
| 
 | ||||
| 	q = NULL; | ||||
| 	csa = NULL; | ||||
| 	doms = NULL; | ||||
| 	dattr = NULL; | ||||
| 
 | ||||
| 	/* Special case for the 99% of systems with one, full, sched domain */ | ||||
| 	if (is_sched_load_balance(&top_cpuset)) { | ||||
|  | @ -566,6 +581,11 @@ static void rebuild_sched_domains(void) | |||
| 		doms = kmalloc(sizeof(cpumask_t), GFP_KERNEL); | ||||
| 		if (!doms) | ||||
| 			goto rebuild; | ||||
| 		dattr = kmalloc(sizeof(struct sched_domain_attr), GFP_KERNEL); | ||||
| 		if (dattr) { | ||||
| 			*dattr = SD_ATTR_INIT; | ||||
| 			update_domain_attr(dattr, &top_cpuset); | ||||
| 		} | ||||
| 		*doms = top_cpuset.cpus_allowed; | ||||
| 		goto rebuild; | ||||
| 	} | ||||
|  | @ -622,6 +642,7 @@ static void rebuild_sched_domains(void) | |||
| 	doms = kmalloc(ndoms * sizeof(cpumask_t), GFP_KERNEL); | ||||
| 	if (!doms) | ||||
| 		goto rebuild; | ||||
| 	dattr = kmalloc(ndoms * sizeof(struct sched_domain_attr), GFP_KERNEL); | ||||
| 
 | ||||
| 	for (nslot = 0, i = 0; i < csn; i++) { | ||||
| 		struct cpuset *a = csa[i]; | ||||
|  | @ -644,12 +665,15 @@ static void rebuild_sched_domains(void) | |||
| 			} | ||||
| 
 | ||||
| 			cpus_clear(*dp); | ||||
| 			if (dattr) | ||||
| 				*(dattr + nslot) = SD_ATTR_INIT; | ||||
| 			for (j = i; j < csn; j++) { | ||||
| 				struct cpuset *b = csa[j]; | ||||
| 
 | ||||
| 				if (apn == b->pn) { | ||||
| 					cpus_or(*dp, *dp, b->cpus_allowed); | ||||
| 					b->pn = -1; | ||||
| 					update_domain_attr(dattr, b); | ||||
| 				} | ||||
| 			} | ||||
| 			nslot++; | ||||
|  | @ -660,7 +684,7 @@ static void rebuild_sched_domains(void) | |||
| rebuild: | ||||
| 	/* Have scheduler rebuild sched domains */ | ||||
| 	get_online_cpus(); | ||||
| 	partition_sched_domains(ndoms, doms); | ||||
| 	partition_sched_domains(ndoms, doms, dattr); | ||||
| 	put_online_cpus(); | ||||
| 
 | ||||
| done: | ||||
|  | @ -668,6 +692,7 @@ static void rebuild_sched_domains(void) | |||
| 		kfifo_free(q); | ||||
| 	kfree(csa); | ||||
| 	/* Don't kfree(doms) -- partition_sched_domains() does that. */ | ||||
| 	/* Don't kfree(dattr) -- partition_sched_domains() does that. */ | ||||
| } | ||||
| 
 | ||||
| static inline int started_after_time(struct task_struct *t1, | ||||
|  | @ -1011,6 +1036,21 @@ static int update_memory_pressure_enabled(struct cpuset *cs, char *buf) | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int update_relax_domain_level(struct cpuset *cs, char *buf) | ||||
| { | ||||
| 	int val = simple_strtol(buf, NULL, 10); | ||||
| 
 | ||||
| 	if (val < 0) | ||||
| 		val = -1; | ||||
| 
 | ||||
| 	if (val != cs->relax_domain_level) { | ||||
| 		cs->relax_domain_level = val; | ||||
| 		rebuild_sched_domains(); | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * update_flag - read a 0 or a 1 in a file and update associated flag | ||||
|  * bit:	the bit to update (CS_CPU_EXCLUSIVE, CS_MEM_EXCLUSIVE, | ||||
|  | @ -1202,6 +1242,7 @@ typedef enum { | |||
| 	FILE_CPU_EXCLUSIVE, | ||||
| 	FILE_MEM_EXCLUSIVE, | ||||
| 	FILE_SCHED_LOAD_BALANCE, | ||||
| 	FILE_SCHED_RELAX_DOMAIN_LEVEL, | ||||
| 	FILE_MEMORY_PRESSURE_ENABLED, | ||||
| 	FILE_MEMORY_PRESSURE, | ||||
| 	FILE_SPREAD_PAGE, | ||||
|  | @ -1256,6 +1297,9 @@ static ssize_t cpuset_common_file_write(struct cgroup *cont, | |||
| 	case FILE_SCHED_LOAD_BALANCE: | ||||
| 		retval = update_flag(CS_SCHED_LOAD_BALANCE, cs, buffer); | ||||
| 		break; | ||||
| 	case FILE_SCHED_RELAX_DOMAIN_LEVEL: | ||||
| 		retval = update_relax_domain_level(cs, buffer); | ||||
| 		break; | ||||
| 	case FILE_MEMORY_MIGRATE: | ||||
| 		retval = update_flag(CS_MEMORY_MIGRATE, cs, buffer); | ||||
| 		break; | ||||
|  | @ -1354,6 +1398,9 @@ static ssize_t cpuset_common_file_read(struct cgroup *cont, | |||
| 	case FILE_SCHED_LOAD_BALANCE: | ||||
| 		*s++ = is_sched_load_balance(cs) ? '1' : '0'; | ||||
| 		break; | ||||
| 	case FILE_SCHED_RELAX_DOMAIN_LEVEL: | ||||
| 		s += sprintf(s, "%d", cs->relax_domain_level); | ||||
| 		break; | ||||
| 	case FILE_MEMORY_MIGRATE: | ||||
| 		*s++ = is_memory_migrate(cs) ? '1' : '0'; | ||||
| 		break; | ||||
|  | @ -1424,6 +1471,13 @@ static struct cftype cft_sched_load_balance = { | |||
| 	.private = FILE_SCHED_LOAD_BALANCE, | ||||
| }; | ||||
| 
 | ||||
| static struct cftype cft_sched_relax_domain_level = { | ||||
| 	.name = "sched_relax_domain_level", | ||||
| 	.read = cpuset_common_file_read, | ||||
| 	.write = cpuset_common_file_write, | ||||
| 	.private = FILE_SCHED_RELAX_DOMAIN_LEVEL, | ||||
| }; | ||||
| 
 | ||||
| static struct cftype cft_memory_migrate = { | ||||
| 	.name = "memory_migrate", | ||||
| 	.read = cpuset_common_file_read, | ||||
|  | @ -1475,6 +1529,9 @@ static int cpuset_populate(struct cgroup_subsys *ss, struct cgroup *cont) | |||
| 		return err; | ||||
| 	if ((err = cgroup_add_file(cont, ss, &cft_sched_load_balance)) < 0) | ||||
| 		return err; | ||||
| 	if ((err = cgroup_add_file(cont, ss, | ||||
| 					&cft_sched_relax_domain_level)) < 0) | ||||
| 		return err; | ||||
| 	if ((err = cgroup_add_file(cont, ss, &cft_memory_pressure)) < 0) | ||||
| 		return err; | ||||
| 	if ((err = cgroup_add_file(cont, ss, &cft_spread_page)) < 0) | ||||
|  | @ -1559,6 +1616,7 @@ static struct cgroup_subsys_state *cpuset_create( | |||
| 	nodes_clear(cs->mems_allowed); | ||||
| 	cs->mems_generation = cpuset_mems_generation++; | ||||
| 	fmeter_init(&cs->fmeter); | ||||
| 	cs->relax_domain_level = -1; | ||||
| 
 | ||||
| 	cs->parent = parent; | ||||
| 	number_of_cpusets++; | ||||
|  | @ -1631,6 +1689,7 @@ int __init cpuset_init(void) | |||
| 	fmeter_init(&top_cpuset.fmeter); | ||||
| 	top_cpuset.mems_generation = cpuset_mems_generation++; | ||||
| 	set_bit(CS_SCHED_LOAD_BALANCE, &top_cpuset.flags); | ||||
| 	top_cpuset.relax_domain_level = -1; | ||||
| 
 | ||||
| 	err = register_filesystem(&cpuset_fs_type); | ||||
| 	if (err < 0) | ||||
|  |  | |||
|  | @ -6771,6 +6771,7 @@ static noinline void sd_init_##type(struct sched_domain *sd)	\ | |||
| {								\ | ||||
| 	memset(sd, 0, sizeof(*sd));				\ | ||||
| 	*sd = SD_##type##_INIT;					\ | ||||
| 	sd->level = SD_LV_##type;				\ | ||||
| } | ||||
| 
 | ||||
| SD_INIT_FUNC(CPU) | ||||
|  | @ -6819,11 +6820,42 @@ struct allmasks { | |||
| #define	SCHED_CPUMASK_VAR(v, a) 	cpumask_t *v = (cpumask_t *) \ | ||||
| 			((unsigned long)(a) + offsetof(struct allmasks, v)) | ||||
| 
 | ||||
| static int default_relax_domain_level = -1; | ||||
| 
 | ||||
| static int __init setup_relax_domain_level(char *str) | ||||
| { | ||||
| 	default_relax_domain_level = simple_strtoul(str, NULL, 0); | ||||
| 	return 1; | ||||
| } | ||||
| __setup("relax_domain_level=", setup_relax_domain_level); | ||||
| 
 | ||||
| static void set_domain_attribute(struct sched_domain *sd, | ||||
| 				 struct sched_domain_attr *attr) | ||||
| { | ||||
| 	int request; | ||||
| 
 | ||||
| 	if (!attr || attr->relax_domain_level < 0) { | ||||
| 		if (default_relax_domain_level < 0) | ||||
| 			return; | ||||
| 		else | ||||
| 			request = default_relax_domain_level; | ||||
| 	} else | ||||
| 		request = attr->relax_domain_level; | ||||
| 	if (request < sd->level) { | ||||
| 		/* turn off idle balance on this domain */ | ||||
| 		sd->flags &= ~(SD_WAKE_IDLE|SD_BALANCE_NEWIDLE); | ||||
| 	} else { | ||||
| 		/* turn on idle balance on this domain */ | ||||
| 		sd->flags |= (SD_WAKE_IDLE_FAR|SD_BALANCE_NEWIDLE); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Build sched domains for a given set of cpus and attach the sched domains | ||||
|  * to the individual cpus | ||||
|  */ | ||||
| static int build_sched_domains(const cpumask_t *cpu_map) | ||||
| static int __build_sched_domains(const cpumask_t *cpu_map, | ||||
| 				 struct sched_domain_attr *attr) | ||||
| { | ||||
| 	int i; | ||||
| 	struct root_domain *rd; | ||||
|  | @ -6887,6 +6919,7 @@ static int build_sched_domains(const cpumask_t *cpu_map) | |||
| 				SD_NODES_PER_DOMAIN*cpus_weight(*nodemask)) { | ||||
| 			sd = &per_cpu(allnodes_domains, i); | ||||
| 			SD_INIT(sd, ALLNODES); | ||||
| 			set_domain_attribute(sd, attr); | ||||
| 			sd->span = *cpu_map; | ||||
| 			cpu_to_allnodes_group(i, cpu_map, &sd->groups, tmpmask); | ||||
| 			p = sd; | ||||
|  | @ -6896,6 +6929,7 @@ static int build_sched_domains(const cpumask_t *cpu_map) | |||
| 
 | ||||
| 		sd = &per_cpu(node_domains, i); | ||||
| 		SD_INIT(sd, NODE); | ||||
| 		set_domain_attribute(sd, attr); | ||||
| 		sched_domain_node_span(cpu_to_node(i), &sd->span); | ||||
| 		sd->parent = p; | ||||
| 		if (p) | ||||
|  | @ -6906,6 +6940,7 @@ static int build_sched_domains(const cpumask_t *cpu_map) | |||
| 		p = sd; | ||||
| 		sd = &per_cpu(phys_domains, i); | ||||
| 		SD_INIT(sd, CPU); | ||||
| 		set_domain_attribute(sd, attr); | ||||
| 		sd->span = *nodemask; | ||||
| 		sd->parent = p; | ||||
| 		if (p) | ||||
|  | @ -6916,6 +6951,7 @@ static int build_sched_domains(const cpumask_t *cpu_map) | |||
| 		p = sd; | ||||
| 		sd = &per_cpu(core_domains, i); | ||||
| 		SD_INIT(sd, MC); | ||||
| 		set_domain_attribute(sd, attr); | ||||
| 		sd->span = cpu_coregroup_map(i); | ||||
| 		cpus_and(sd->span, sd->span, *cpu_map); | ||||
| 		sd->parent = p; | ||||
|  | @ -6927,6 +6963,7 @@ static int build_sched_domains(const cpumask_t *cpu_map) | |||
| 		p = sd; | ||||
| 		sd = &per_cpu(cpu_domains, i); | ||||
| 		SD_INIT(sd, SIBLING); | ||||
| 		set_domain_attribute(sd, attr); | ||||
| 		sd->span = per_cpu(cpu_sibling_map, i); | ||||
| 		cpus_and(sd->span, sd->span, *cpu_map); | ||||
| 		sd->parent = p; | ||||
|  | @ -7124,8 +7161,15 @@ static int build_sched_domains(const cpumask_t *cpu_map) | |||
| #endif | ||||
| } | ||||
| 
 | ||||
| static int build_sched_domains(const cpumask_t *cpu_map) | ||||
| { | ||||
| 	return __build_sched_domains(cpu_map, NULL); | ||||
| } | ||||
| 
 | ||||
| static cpumask_t *doms_cur;	/* current sched domains */ | ||||
| static int ndoms_cur;		/* number of sched domains in 'doms_cur' */ | ||||
| static struct sched_domain_attr *dattr_cur;	/* attribues of custom domains
 | ||||
| 						   in 'doms_cur' */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Special case: If a kmalloc of a doms_cur partition (array of | ||||
|  | @ -7153,6 +7197,7 @@ static int arch_init_sched_domains(const cpumask_t *cpu_map) | |||
| 	if (!doms_cur) | ||||
| 		doms_cur = &fallback_doms; | ||||
| 	cpus_andnot(*doms_cur, *cpu_map, cpu_isolated_map); | ||||
| 	dattr_cur = NULL; | ||||
| 	err = build_sched_domains(doms_cur); | ||||
| 	register_sched_domain_sysctl(); | ||||
| 
 | ||||
|  | @ -7182,6 +7227,22 @@ static void detach_destroy_domains(const cpumask_t *cpu_map) | |||
| 	arch_destroy_sched_domains(cpu_map, &tmpmask); | ||||
| } | ||||
| 
 | ||||
| /* handle null as "default" */ | ||||
| static int dattrs_equal(struct sched_domain_attr *cur, int idx_cur, | ||||
| 			struct sched_domain_attr *new, int idx_new) | ||||
| { | ||||
| 	struct sched_domain_attr tmp; | ||||
| 
 | ||||
| 	/* fast path */ | ||||
| 	if (!new && !cur) | ||||
| 		return 1; | ||||
| 
 | ||||
| 	tmp = SD_ATTR_INIT; | ||||
| 	return !memcmp(cur ? (cur + idx_cur) : &tmp, | ||||
| 			new ? (new + idx_new) : &tmp, | ||||
| 			sizeof(struct sched_domain_attr)); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Partition sched domains as specified by the 'ndoms_new' | ||||
|  * cpumasks in the array doms_new[] of cpumasks. This compares | ||||
|  | @ -7203,7 +7264,8 @@ static void detach_destroy_domains(const cpumask_t *cpu_map) | |||
|  * | ||||
|  * Call with hotplug lock held | ||||
|  */ | ||||
| void partition_sched_domains(int ndoms_new, cpumask_t *doms_new) | ||||
| void partition_sched_domains(int ndoms_new, cpumask_t *doms_new, | ||||
| 			     struct sched_domain_attr *dattr_new) | ||||
| { | ||||
| 	int i, j; | ||||
| 
 | ||||
|  | @ -7216,12 +7278,14 @@ void partition_sched_domains(int ndoms_new, cpumask_t *doms_new) | |||
| 		ndoms_new = 1; | ||||
| 		doms_new = &fallback_doms; | ||||
| 		cpus_andnot(doms_new[0], cpu_online_map, cpu_isolated_map); | ||||
| 		dattr_new = NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Destroy deleted domains */ | ||||
| 	for (i = 0; i < ndoms_cur; i++) { | ||||
| 		for (j = 0; j < ndoms_new; j++) { | ||||
| 			if (cpus_equal(doms_cur[i], doms_new[j])) | ||||
| 			if (cpus_equal(doms_cur[i], doms_new[j]) | ||||
| 			    && dattrs_equal(dattr_cur, i, dattr_new, j)) | ||||
| 				goto match1; | ||||
| 		} | ||||
| 		/* no match - a current sched domain not in new doms_new[] */ | ||||
|  | @ -7233,11 +7297,13 @@ void partition_sched_domains(int ndoms_new, cpumask_t *doms_new) | |||
| 	/* Build new domains */ | ||||
| 	for (i = 0; i < ndoms_new; i++) { | ||||
| 		for (j = 0; j < ndoms_cur; j++) { | ||||
| 			if (cpus_equal(doms_new[i], doms_cur[j])) | ||||
| 			if (cpus_equal(doms_new[i], doms_cur[j]) | ||||
| 			    && dattrs_equal(dattr_new, i, dattr_cur, j)) | ||||
| 				goto match2; | ||||
| 		} | ||||
| 		/* no match - add a new doms_new */ | ||||
| 		build_sched_domains(doms_new + i); | ||||
| 		__build_sched_domains(doms_new + i, | ||||
| 					dattr_new ? dattr_new + i : NULL); | ||||
| match2: | ||||
| 		; | ||||
| 	} | ||||
|  | @ -7245,7 +7311,9 @@ void partition_sched_domains(int ndoms_new, cpumask_t *doms_new) | |||
| 	/* Remember the new sched domains */ | ||||
| 	if (doms_cur != &fallback_doms) | ||||
| 		kfree(doms_cur); | ||||
| 	kfree(dattr_cur);	/* kfree(NULL) is safe */ | ||||
| 	doms_cur = doms_new; | ||||
| 	dattr_cur = dattr_new; | ||||
| 	ndoms_cur = ndoms_new; | ||||
| 
 | ||||
| 	register_sched_domain_sysctl(); | ||||
|  |  | |||
|  | @ -940,7 +940,9 @@ static int wake_idle(int cpu, struct task_struct *p) | |||
| 		return cpu; | ||||
| 
 | ||||
| 	for_each_domain(cpu, sd) { | ||||
| 		if (sd->flags & SD_WAKE_IDLE) { | ||||
| 		if ((sd->flags & SD_WAKE_IDLE) | ||||
| 		    || ((sd->flags & SD_WAKE_IDLE_FAR) | ||||
| 			&& !task_hot(p, task_rq(p)->clock, sd))) { | ||||
| 			cpus_and(tmp, sd->span, p->cpus_allowed); | ||||
| 			for_each_cpu_mask(i, tmp) { | ||||
| 				if (idle_cpu(i)) { | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Hidetoshi Seto
						Hidetoshi Seto