Skip to contentSkip to conversation

sched: group CPU power setup cleanup

PATCH In review Siddha, Suresh B 6 participants 18 messages Aug 16, 2006 – Aug 21, 2006 Scheduler

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 sched: group CPU power setup cleanup

Resending the new patch. Before patch had some issues for Andy and hence dropped.

Andrew, Please add this to -mm. This patch is against 2.6.18-rc4. There might be a small conflict while applying to -mm. Let me know if you want a patch on top of -mm.

thanks,
suresh

--

Cleanup the sched group cpu_power setup code, by introducing child field and new domain flag in sched_domain.

include/asm-i386/topology.h +1 -0
diff -pNru linux-2.6.18-rc4/include/asm-i386/topology.h linux/include/asm-i386/topology.h
@@ -74,6 +74,7 @@ static inline int node_to_first_cpu(int 
 #define SD_NODE_INIT (struct sched_domain) {		\
 	.span			= CPU_MASK_NONE,	\
 	.parent			= NULL,			\
+	.child			= NULL,			\
 	.groups			= NULL,			\
 	.min_interval		= 8,			\
 	.max_interval		= 32,			\
include/asm-ia64/topology.h +2 -0
diff -pNru linux-2.6.18-rc4/include/asm-ia64/topology.h linux/include/asm-ia64/topology.h
@@ -59,6 +59,7 @@ void build_cpu_to_node_map(void);
 #define SD_CPU_INIT (struct sched_domain) {		\
 	.span			= CPU_MASK_NONE,	\
 	.parent			= NULL,			\
+	.child			= NULL,			\
 	.groups			= NULL,			\
 	.min_interval		= 1,			\
 	.max_interval		= 4,			\
@@ -84,6 +85,7 @@ void build_cpu_to_node_map(void);
 #define SD_NODE_INIT (struct sched_domain) {		\
 	.span			= CPU_MASK_NONE,	\
 	.parent			= NULL,			\
+	.child			= NULL,			\
 	.groups			= NULL,			\
 	.min_interval		= 8,			\
 	.max_interval		= 8*(min(num_online_cpus(), 32)), \
include/asm-mips/mach-ip27/topology.h +1 -0
diff -pNru linux-2.6.18-rc4/include/asm-mips/mach-ip27/topology.h linux/include/asm-mips/mach-ip27/topology.h
@@ -22,6 +22,7 @@ extern unsigned char __node_distances[MA
 #define SD_NODE_INIT (struct sched_domain) {		\
 	.span			= CPU_MASK_NONE,	\
 	.parent			= NULL,			\
+	.child			= NULL,			\
 	.groups			= NULL,			\
 	.min_interval		= 8,			\
 	.max_interval		= 32,			\
include/asm-powerpc/topology.h +1 -0
diff -pNru linux-2.6.18-rc4/include/asm-powerpc/topology.h linux/include/asm-powerpc/topology.h
@@ -43,6 +43,7 @@ extern int pcibus_to_node(struct pci_bus
 #define SD_NODE_INIT (struct sched_domain) {		\
 	.span			= CPU_MASK_NONE,	\
 	.parent			= NULL,			\
+	.child			= NULL,			\
 	.groups			= NULL,			\
 	.min_interval		= 8,			\
 	.max_interval		= 32,			\
include/asm-x86_64/topology.h +1 -0
diff -pNru linux-2.6.18-rc4/include/asm-x86_64/topology.h linux/include/asm-x86_64/topology.h
@@ -31,6 +31,7 @@ extern int __node_distance(int, int);
 #define SD_NODE_INIT (struct sched_domain) {		\
 	.span			= CPU_MASK_NONE,	\
 	.parent			= NULL,			\
+	.child			= NULL,			\
 	.groups			= NULL,			\
 	.min_interval		= 8,			\
 	.max_interval		= 32,			\
include/linux/sched.h +10 -2
diff -pNru linux-2.6.18-rc4/include/linux/sched.h linux/include/linux/sched.h
@@ -623,9 +623,16 @@ enum idle_type
 #define SD_WAKE_BALANCE		64	/* Perform balancing at task wakeup */
 #define SD_SHARE_CPUPOWER	128	/* Domain members share cpu power */
 #define SD_POWERSAVINGS_BALANCE	256	/* Balance for power savings */
+#define SD_SHARE_PKG_RESOURCES	512	/* Domain members share cpu pkg resources */
 
-#define BALANCE_FOR_POWER	((sched_mc_power_savings || sched_smt_power_savings) \
-				 ? SD_POWERSAVINGS_BALANCE : 0)
+#define BALANCE_FOR_MC_POWER	\
+	(sched_smt_power_savings ? SD_POWERSAVINGS_BALANCE : 0)
+
+#define BALANCE_FOR_PKG_POWER	\
+	((sched_mc_power_savings || sched_smt_power_savings) ?	\
+	 SD_POWERSAVINGS_BALANCE : 0)
+
+#define test_sd_flag(sd, flag)	((sd && (sd->flags & flag)) ? 1 : 0)
 
 
 struct sched_group {
@@ -642,6 +649,7 @@ struct sched_group {
 struct sched_domain {
 	/* These fields must be setup */
 	struct sched_domain *parent;	/* top domain must be null terminated */
+	struct sched_domain *child;	/* bottom domain must be null terminated */
 	struct sched_group *groups;	/* the balancing groups of the domain */
 	cpumask_t span;			/* span of all CPUs in this domain */
 	unsigned long min_interval;	/* Minimum balance interval ms */
include/linux/topology.h +36 -10

81 lines not on this page · raw message

kernel/sched.c +99 -74

297 lines not on this page · raw message

#1 lore raw

Thanks for the cleanup patch resend, Suresh.

Quoted 11 lines

Resending the new patch. Before patch had some issues for Andy and hence dropped.

Andrew, Please add this to -mm. This patch is against 2.6.18-rc4. There might be a small conflict while applying to -mm. Let me know if you want a patch on top of -mm.

thanks,
suresh

--

I found the above patch commentary frustrating to read, as it told me very little, and teased me with reference to details that are left unsaid.

Can we work on this patch's opening text a bit more?

Take a look at Andrew's "The perfect patch"
http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt

The above quoted material doesn't follow the recommendations in the (4) Changelog section of Andrew's recommendations, especially (4a), (4b), (4c) and (4d).

The above quoted material is stuff that will mean little to someone looking at this changelog in the source history a year from now. Heck, it means little to me, now, and I supposedly have been trying to track your sched domain cleanup work more closely than most people.

Just now I ran a grep over my lkml email archives for the last few months, and apparently the "issue for Andy" refers to a thread that includes a message dated "Mon, 03 Jul 2006" from Andy Whitcroft under the generic Subject of "Re: 2.6.17-mm5", noticing a problem with a panic on NUMA-Q due to a zero cpu_power. Anyone besides Andy and Suresh who knew that without poking around old lkml messages has way too good a memory ;).

Quoted 2 lines

Cleanup the sched group cpu_power setup code, by introducing child field and new domain flag in sched_domain.

I guess you meant the above two lines to be the actual Changelog text, to be read by all who examine this change to Linux in the source control history hereafteer.

But as explained in Andrew's recommendations, the recommended changelog text should come first (after a possible "From:" line) in the patch email, followed by "---" a line with just three dashes, followed by the transient text that will mean little in the future.

That is, you had:

transient text

--

permanent changelog text (just the above 2 lines)

Signed-off-by ...

diff ...

Andrew's recommendations would instead have:

permanent changelog text (more than 2 lines, I hope, in this case)

Signed-off-by ...

---

transient text

diff ...

Quoted 3 lines

+ * cpu_power indicates the computing power of each sched group. This is
+ * used for distributing the load between different sched groups
+ * in a sched domain.

Thanks for explaining what cpu_power means.

Quoted 2 lines

... Typically cpu_power for all the groups in a
+ * sched domain will be same unless there are asymmetries in the topology.

Does the above mean that all groups in a domain have the same number of CPUs? Or perhaps my newbie ignorance of what 'group' means is showing through, and my question makes no sense - sorry if so.

+static void init_sched_groups_power(int cpu, struct sched_domain *sd) +{
+ ...
+
+ if (cpu != first_cpu(sd->groups->cpumask))
+ return;

I am a tad surprised that the above always works. Is it ever possible that init_sched_groups_power() is never called for the first cpu in a group, and that hence the cpu_power of that group is not uninitialized?

If there is some explanation as to how this is not possible, and it is guaranteed that init_sched_groups_power() is always called for the first cpu in a group, then that might be worthy of a comment.

Is it possible to get the partition1 or partition2 in the calls:

    int partition_sched_domains(cpumask_t *partition1, cpumask_t *partition2)
    {
	    ...
	    if (!cpus_empty(*partition1))
		    err = build_sched_domains(partition1);
	    if (!err && !cpus_empty(*partition2))
		    err = build_sched_domains(partition2);

so some group had some CPUs, but not the first CPU of groups->cpumask in one of these partitions?

+ /*
+ * For perf policy, if the groups in child domain share resources
+ * (for example cores sharing some portions of the cache hierarchy
+ * or SMT), then set this domain groups cpu_power such that each group
+ * can handle only one task, when there are other idle groups in the
+ * same sched domain.
+ */

I am clearly still missing proper understanding here. How is it that the cpu_power of a group can be set so that it "can handle only one task?"

kernel/sched.c next_sg: · line 6240

Quoted 3 lines
kernel/sched.c +3 -0
+	if (!child || (!(sd->flags & SD_POWERSAVINGS_BALANCE) &&
+		       (child->flags & SD_SHARE_CPUPOWER ||
+			child->flags & SD_SHARE_PKG_RESOURCES))) {

Would this be equivalent to the following, which saves a few machine instructions and a conditional jump as well:

	if (!child || (!(sd->flags & SD_POWERSAVINGS_BALANCE) &&
		       (child->flags &
				(SD_SHARE_CPUPOWER | SD_SHARE_PKG_RESOURCES)
			)) {
Signature · 3 lines
                  I won't rest till it's the best ...
                  Programmer, Linux Scalability
                  Paul Jackson <[email protected]> 1.925.600.0401
#2 lore raw
Quoted 12 lines · On Tue, 15 Aug 2006 21:24:55 -0700 Paul Jackson <[email protected]> wrote:

Thanks for the cleanup patch resend, Suresh.

Quoted 10 lines

Resending the new patch. Before patch had some issues for Andy and hence dropped.

Andrew, Please add this to -mm. This patch is against 2.6.18-rc4. There might be a small conflict while applying to -mm. Let me know if you want a patch on top of -mm.

thanks,
suresh

Quoted 7 lines
Quoted 1 line

--

I found the above patch commentary frustrating to read, as it told me very little, and teased me with reference to details that are left unsaid.

Can we work on this patch's opening text a bit more?

Believe it or not, I usually suffer in silence.

Quoted 9 lines

..

Quoted 3 lines

+ * cpu_power indicates the computing power of each sched group. This is
+ * used for distributing the load between different sched groups
+ * in a sched domain.

Thanks for explaining what cpu_power means.

Hope not. To me, "computing power" means megaflops/sec, or Dhrystones (don't ask) or whatever. If that's what "cpu_power" is referring to then the name is hopelessly ambiguous with peak joules/sec and a big renaming is due.

#3 lore raw
Quoted 1 line

Believe it or not, I usually suffer in silence.

I do too (though I look at 0.001% of the patches you do ;).

This time, I was motivated to actually figure this code out a bit, as a common way to get to this code is via a cpuset cpu_exclusive setting, and of late a couple of bugs in earlier versions of this code had caused me grief.

So I was hoping for more useful patch changelog comments, in my quest to rise above my newbie ranking in kernel/sched.c code.

Signature · 3 lines
                  I won't rest till it's the best ...
                  Programmer, Linux Scalability
                  Paul Jackson <[email protected]> 1.925.600.0401
#4 lore raw
In reply to Andrew Morton
Quoted 11 lines · Andrew Morton
Quoted 6 lines
Quoted 3 lines

+ * cpu_power indicates the computing power of each sched group. This is
+ * used for distributing the load between different sched groups
+ * in a sched domain.

Thanks for explaining what cpu_power means.

Hope not. To me, "computing power" means megaflops/sec, or Dhrystones (don't ask) or whatever. If that's what "cpu_power" is referring to then the name is hopelessly ambiguous with peak joules/sec and a big renaming is due.

It refers to group's processing power. Perhaps "horsepower" is better term.

thanks,
suresh

#5 lore raw
Quoted 6 lines
Quoted 4 lines

Hope not. To me, "computing power" means megaflops/sec, or Dhrystones (don't ask) or whatever. If that's what "cpu_power" is referring to then the name is hopelessly ambiguous with peak joules/sec and a big renaming is due.

It refers to group's processing power. Perhaps "horsepower" is better term.

Well ... I don't think "horsepower" is a step in the right direction.

Andrew's point was over the word "power", not "cpu". The term "cpu_power" suggested to him we were concerned with the power supply watts consumed by a group of CPUs. Indeed, both those concerned with laptop battery lifetimes, and the air conditioning tonnage needed for big honkin NUMA iron might have reason to be concerned with the power consumed by CPUs.

Changing the word "cpu" to "horse", but keeping the word "power", does nothing to address Andrew's point. Rather it just adds more confusion. We are obviously dealing with CPUs here, not horses.

My understanding is that the "cpu_power" of the cpus in a sched group is rougly proportional to the BogoMIPS of the CPUs in that group.

Signature · 3 lines
                  I won't rest till it's the best ...
                  Programmer, Linux Scalability
                  Paul Jackson <[email protected]> 1.925.600.0401
#6 lore raw
Quoted 11 lines · Paul Jackson
Quoted 1 line

It refers to group's processing power. Perhaps "horsepower" is better term.

Well ... I don't think "horsepower" is a step in the right direction.

Andrew's point was over the word "power", not "cpu". The term "cpu_power" suggested to him we were concerned with the power supply watts consumed by a group of CPUs. Indeed, both those concerned with laptop battery lifetimes, and the air conditioning tonnage needed for big honkin NUMA iron might have reason to be concerned with the power consumed by CPUs.

Quoted 3 lines

Changing the word "cpu" to "horse", but keeping the word "power", does nothing to address Andrew's point. Rather it just adds more confusion. We are obviously dealing with CPUs here, not horses.

Let me resist the temptation and not go into the definition of horsepower here. You can refer any dictionary.

Quoted 2 lines

My understanding is that the "cpu_power" of the cpus in a sched group is rougly proportional to the BogoMIPS of the CPUs in that group.

This variable represents how many tasks(multiplied by scaling factor SCHED_LOAD_SCALE)the group can handle before it starts distributing the load to other idle or less lightly loaded groups. For example, group with two HT threads will have it as < 2 * SCHED_LOAD_SCALE. group with N physical cpus in a NUMA node will have it as N * SCHED_LOAD_SCALE. When power savings policy is enabled, some of the domains group values will increase making each group pickup more load and save some watt power.

"group_capacity" or "load_capacity" might be good term considering all this..

thanks,
suresh

#7 lore raw
Quoted 2 lines · Suresh

Let me resist the temptation and not go into the definition of horsepower here. You can refer any dictionary.

Good point <grin>.

Horsepower is a measure of power, of energy over time, such as the rate of providing or using electrical or mechanical energy.

So, with your suggestion of 'horsepower', are you saying that cpu_power is a metric of such electrical or mechanical energy -- the peak or average watts of the electricity consumed by the CPUs in a group?

Or is 'cpu_power' a metric of the computational capacity, such as BogoMIPS provided by the CPUs in a group, such as I had presumed?

Hmmm ... apparently from your latest explanation, it's neither of these.

Rather it's a metric of how many tasks to place in a group, due to various capacities and constraints, such as computational power (BogoMIPS) and electrical power (watts or horsepower).

Should 'cpu_power' be renamed to 'task_load' ?

Signature · 3 lines
                  I won't rest till it's the best ...
                  Programmer, Linux Scalability
                  Paul Jackson <[email protected]> 1.925.600.0401
#8 lore raw
Quoted 4 lines · Paul Jackson
Quoted 2 lines · Suresh

Let me resist the temptation and not go into the definition of horsepower here. You can refer any dictionary.

Quoted 8 lines

Good point <grin>.

Horsepower is a measure of power, of energy over time, such as the rate of providing or using electrical or mechanical energy.

So, with your suggestion of 'horsepower', are you saying that cpu_power is a metric of such electrical or mechanical energy -- the peak or average watts of the electricity consumed by the CPUs in a group?

And is white_power, the energy output of a redneck on a step machine?

Power has assorted meanings over and above the J/s one.

I'd suggest 'computing_power' might be less ambiguous.

#9 lore raw
Quoted 1 line · Ian

I'd suggest 'computing_power' might be less ambiguous.

Eh ... I should quit suggesting names, until I figure out more accurately what it means.

Signature · 3 lines
                  I won't rest till it's the best ...
                  Programmer, Linux Scalability
                  Paul Jackson <[email protected]> 1.925.600.0401
#10 lore raw
In reply to Paul Jackson
Quoted 15 lines · Paul Jackson
Quoted 5 lines
Quoted 4 lines

Hope not. To me, "computing power" means megaflops/sec, or Dhrystones (don't ask) or whatever. If that's what "cpu_power" is referring to then the name is hopelessly ambiguous with peak joules/sec and a big renaming is due.

It refers to group's processing power. Perhaps "horsepower" is better term.

Well ... I don't think "horsepower" is a step in the right direction.

Andrew's point was over the word "power", not "cpu". The term "cpu_power" suggested to him we were concerned with the power supply watts consumed by a group of CPUs. Indeed, both those concerned with laptop battery lifetimes, and the air conditioning tonnage needed for big honkin NUMA iron might have reason to be concerned with the power consumed by CPUs.

Quoted 7 lines

Changing the word "cpu" to "horse", but keeping the word "power", does nothing to address Andrew's point. Rather it just adds more confusion. We are obviously dealing with CPUs here, not horses.

My understanding is that the "cpu_power" of the cpus in a sched group is rougly proportional to the BogoMIPS of the CPUs in that group.

How about energy instead of power? I.e. the CPU's capacity to do work.

Peter

Signature · 4 lines
Peter Williams                                   [email protected]

"Learning, n. The kind of ignorance distinguishing the studious."
 -- Ambrose Bierce
#11 lore raw
In reply to Paul Jackson
Quoted 2 lines · Paul Jackson

My understanding is that the "cpu_power" of the cpus in a sched group is rougly proportional to the BogoMIPS of the CPUs in that group.

Uh oh, on powerpc the bogomips has nothing at all to do with the speed of the cpu, but relates instead to the frequency at which the timebase register counts...

Paul.

#12 lore raw
In reply to Paul Jackson
Quoted 20 lines · Paul Jackson

That is, you had:

transient text

--

permanent changelog text (just the above 2 lines)

Signed-off-by ...

diff ...

Andrew's recommendations would instead have:

permanent changelog text (more than 2 lines, I hope, in this case)

Quoted 7 lines
Signed-off-by ...

---

transient text

diff ...

Andrew, is it possible for changing your tpp format such that transient text comes on the top followed by the change log and signed-off-by... Transient text will have more info about the patch in the context of an ongoing lkml thread conversation. Hence it makes sense to be on top rather than somewhere in between the changelog and the patch.

I will def add more appropriate changelog text..

Quoted 5 lines
Quoted 2 lines

... Typically cpu_power for all the groups in a
+ * sched domain will be same unless there are asymmetries in the topology.

Does the above mean that all groups in a domain have the same number of CPUs?

typically yes. cpuhotplug or exclusive cpusets can change it..

Quoted 9 lines
kernel/sched.c +6 -0
+static void init_sched_groups_power(int cpu, struct sched_domain *sd)
+{
+	...
+
+	if (cpu != first_cpu(sd->groups->cpumask))
+		return;
Quoted 3 lines

I am a tad surprised that the above always works. Is it ever possible that init_sched_groups_power() is never called for the first cpu in a group, and that hence the cpu_power of that group is not uninitialized?

No. This is not possible.

Quoted 3 lines

If there is some explanation as to how this is not possible, and it is guaranteed that init_sched_groups_power() is always called for the first cpu in a group, then that might be worthy of a comment.

init_sched_groups_power is called for each cpu in the cpu_map and hence for all the cpus in a group.

Quoted 11 lines

Is it possible to get the partition1 or partition2 in the calls:

    int partition_sched_domains(cpumask_t *partition1, cpumask_t *partition2)
    {
	    ...
	    if (!cpus_empty(*partition1))
		    err = build_sched_domains(partition1);
	    if (!err && !cpus_empty(*partition2))
		    err = build_sched_domains(partition2);
Quoted 2 lines

so some group had some CPUs, but not the first CPU of groups->cpumask in one of these partitions?

Question doesn't make sense... each domain has it own specific groups..

Quoted 10 lines
kernel/sched.c +7 -0
+	/*
+	 * For perf policy, if the groups in child domain share resources
+	 * (for example cores sharing some portions of the cache hierarchy
+	 * or SMT), then set this domain groups cpu_power such that each group
+	 * can handle only one task, when there are other idle groups in the
+	 * same sched domain.
+	 */

I am clearly still missing proper understanding here. How is it that the cpu_power of a group can be set so that it "can handle only one task?"

Please see the find_busiest_group() code and how its uses cpu_power. For example if a group has two tasks and if its cpu_power is
1 * SCHED_LOAD_SCALE, then any other idle group in the domain will pickup the extra task. I have explained the significance of the 'multiple' in the comments.

Quoted 9 lines

kernel/sched.c next_sg: · line 6240

Quoted 5 lines
kernel/sched.c +3 -0
+	if (!child || (!(sd->flags & SD_POWERSAVINGS_BALANCE) &&
+		       (child->flags & SD_SHARE_CPUPOWER ||
+			child->flags & SD_SHARE_PKG_RESOURCES))) {

Would this be equivalent to the following, which saves a few machine instructions and a conditional jump as well:

Quoted 4 lines
	if (!child || (!(sd->flags & SD_POWERSAVINGS_BALANCE) &&
		       (child->flags &
				(SD_SHARE_CPUPOWER | SD_SHARE_PKG_RESOURCES)
			)) {

compiler will be doing it. Anyhow I will include this change, as it is cleaner.

thanks,
suresh

#13 lore raw

PATCH 1/1 sched: generic sched_group cpu power setup

Andrew, Please apply this patch to -mm. I will post a 'cpu_power' renaming patch shortly.

thanks,
suresh
---

Up to now sched group's cpu_power for each sched domain is initialized independently. This made the setup code ugly as the new sched domains are getting added.

Make the sched group cpu_power setup code generic, by introducing domain child field and new domain flag in sched_domain. For most of the sched domains(except NUMA), sched group's cpu_power is now computed generically using the domain properties of itself and of the child domain.

sched groups in NUMA domains are setup little differently and hence they don't use this generic mechanism.

Cc Ingo Molnar <[email protected]>
Cc Nick Piggin <[email protected]>

---

include/asm-i386/topology.h +1 -0
diff -pNru linux-2.6.18-rc4/include/asm-i386/topology.h linux/include/asm-i386/topology.h
@@ -74,6 +74,7 @@ static inline int node_to_first_cpu(int 
 #define SD_NODE_INIT (struct sched_domain) {		\
 	.span			= CPU_MASK_NONE,	\
 	.parent			= NULL,			\
+	.child			= NULL,			\
 	.groups			= NULL,			\
 	.min_interval		= 8,			\
 	.max_interval		= 32,			\
include/asm-ia64/topology.h +2 -0
diff -pNru linux-2.6.18-rc4/include/asm-ia64/topology.h linux/include/asm-ia64/topology.h
@@ -59,6 +59,7 @@ void build_cpu_to_node_map(void);
 #define SD_CPU_INIT (struct sched_domain) {		\
 	.span			= CPU_MASK_NONE,	\
 	.parent			= NULL,			\
+	.child			= NULL,			\
 	.groups			= NULL,			\
 	.min_interval		= 1,			\
 	.max_interval		= 4,			\
@@ -84,6 +85,7 @@ void build_cpu_to_node_map(void);
 #define SD_NODE_INIT (struct sched_domain) {		\
 	.span			= CPU_MASK_NONE,	\
 	.parent			= NULL,			\
+	.child			= NULL,			\
 	.groups			= NULL,			\
 	.min_interval		= 8,			\
 	.max_interval		= 8*(min(num_online_cpus(), 32)), \
include/asm-mips/mach-ip27/topology.h +1 -0
diff -pNru linux-2.6.18-rc4/include/asm-mips/mach-ip27/topology.h linux/include/asm-mips/mach-ip27/topology.h
@@ -22,6 +22,7 @@ extern unsigned char __node_distances[MA
 #define SD_NODE_INIT (struct sched_domain) {		\
 	.span			= CPU_MASK_NONE,	\
 	.parent			= NULL,			\
+	.child			= NULL,			\
 	.groups			= NULL,			\
 	.min_interval		= 8,			\
 	.max_interval		= 32,			\
include/asm-powerpc/topology.h +1 -0
diff -pNru linux-2.6.18-rc4/include/asm-powerpc/topology.h linux/include/asm-powerpc/topology.h
@@ -43,6 +43,7 @@ extern int pcibus_to_node(struct pci_bus
 #define SD_NODE_INIT (struct sched_domain) {		\
 	.span			= CPU_MASK_NONE,	\
 	.parent			= NULL,			\
+	.child			= NULL,			\
 	.groups			= NULL,			\
 	.min_interval		= 8,			\
 	.max_interval		= 32,			\
include/asm-x86_64/topology.h +1 -0
diff -pNru linux-2.6.18-rc4/include/asm-x86_64/topology.h linux/include/asm-x86_64/topology.h
@@ -31,6 +31,7 @@ extern int __node_distance(int, int);
 #define SD_NODE_INIT (struct sched_domain) {		\
 	.span			= CPU_MASK_NONE,	\
 	.parent			= NULL,			\
+	.child			= NULL,			\
 	.groups			= NULL,			\
 	.min_interval		= 8,			\
 	.max_interval		= 32,			\
include/linux/sched.h +10 -2
diff -pNru linux-2.6.18-rc4/include/linux/sched.h linux/include/linux/sched.h
@@ -623,9 +623,16 @@ enum idle_type
 #define SD_WAKE_BALANCE		64	/* Perform balancing at task wakeup */
 #define SD_SHARE_CPUPOWER	128	/* Domain members share cpu power */
 #define SD_POWERSAVINGS_BALANCE	256	/* Balance for power savings */
+#define SD_SHARE_PKG_RESOURCES	512	/* Domain members share cpu pkg resources */
 
-#define BALANCE_FOR_POWER	((sched_mc_power_savings || sched_smt_power_savings) \
-				 ? SD_POWERSAVINGS_BALANCE : 0)
+#define BALANCE_FOR_MC_POWER	\
+	(sched_smt_power_savings ? SD_POWERSAVINGS_BALANCE : 0)
+
+#define BALANCE_FOR_PKG_POWER	\
+	((sched_mc_power_savings || sched_smt_power_savings) ?	\
+	 SD_POWERSAVINGS_BALANCE : 0)
+
+#define test_sd_flag(sd, flag)	((sd && (sd->flags & flag)) ? 1 : 0)
 
 
 struct sched_group {
@@ -642,6 +649,7 @@ struct sched_group {
 struct sched_domain {
 	/* These fields must be setup */
 	struct sched_domain *parent;	/* top domain must be null terminated */
+	struct sched_domain *child;	/* bottom domain must be null terminated */
 	struct sched_group *groups;	/* the balancing groups of the domain */
 	cpumask_t span;			/* span of all CPUs in this domain */
 	unsigned long min_interval;	/* Minimum balance interval ms */
include/linux/topology.h +36 -10

81 lines not on this page · raw message

kernel/sched.c +99 -74

297 lines not on this page · raw message

#14 lore raw

Re: [patch] sched: generic sched_group cpu power setup

Quoted 1 line · Suresh

I will post a 'cpu_power' renaming patch shortly.

Rename to what?

Signature · 3 lines
                  I won't rest till it's the best ...
                  Programmer, Linux Scalability
                  Paul Jackson <[email protected]> 1.925.600.0401
#15 lore raw

Re: [patch] sched: generic sched_group cpu power setup

Quoted 4 lines · Paul Jackson
Quoted 1 line · Suresh

I will post a 'cpu_power' renaming patch shortly.

Rename to what?

Not yet decided. But both the words "cpu" and "power" will disappear :) sched group can have one or more cpus.. so having 'cpu' is confusing and 'power/energy' seems to be confusing too..

I don't like 'task_load' as it kind of refers to current task load in a sched_group. Currently I favor for 'load_capacity'. Anyone reading sched code know what 'load' is.

If any one has a better suggestion, I am open.

thanks,
suresh

#16 lore raw

Re: [patch] sched: generic sched_group cpu power setup

Quoted 1 line

If any one has a better suggestion, I am open.

I'm still trying to figure out what the hell it is ;).

Sorry ... as my teenage son would gladly tell you, I can be dense at times.

If all the CPUs in a system have the same computational capacity, then is it just the number of CPUs in a group (times a scale factor of 128, to simulate fixed point arithmetic with integers)?

I presume "yes", from such code lines as:

  power = SCHED_LOAD_SCALE * cpus_weight(sd->groups->cpumask);

If two CPUs, side by side, have the same computational capacity, but one consumes more electrical power (watts) than the other, do they have different cpu_power?

I presume "no" - electrical power consumption does not affect this value (though some effort might be made to minimize electrical power consumption in these calculations, by letting some CPUs go idle if the job mix allows for that.)

If I presumed correctly, then apparently what we're talking about here is computational capacity, as is typically measured in such units as MIPS, megaflops/sec or Drystones. In other words, what Andrew termed "computing power" when he fired the starter's pistol on this scrum.

Is that what this is -- computational capacity, aka computing power (appropriately scaled for the convenience of the arithmetic)?

And is the unit of measure just the number of CPUs in the group (times 128)?

If the above is accurate, then the group structure member could almost be called "ncpus" (number of cpus in group), unscaled. Perhaps you only need to scale the value for fixed point arithmetic while calculating what balancing to attempt.

One more detail, as you likely already noticed, if you rename "cpu_power" to not mention "power", then consider also the routine init_numa_sched_groups_power(), the variables pwr_now, pwr_move and power, and the mentions of "power" in the comments.

Signature · 3 lines
                  I won't rest till it's the best ...
                  Programmer, Linux Scalability
                  Paul Jackson <[email protected]> 1.925.600.0401
#17 lore raw

Re: [patch] sched: generic sched_group cpu power setup

Quoted 1 line · Paul Jackson

I'm still trying to figure out what the hell it is ;).

Please refer to the code comments in my recent patch. And also the recent conversations between us about this. My OLS 2005 paper(CMP aware kernel scheduler) might also help and finally the source code kernel/sched.c

Quoted 2 lines

If all the CPUs in a system have the same computational capacity, then is it just the number of CPUs in a group (times a scale factor

No. It depends on the sched domain, its characteristics and depends on performance/power-savings policy.

Quoted 3 lines

If two CPUs, side by side, have the same computational capacity, but one consumes more electrical power (watts) than the other, do they have different cpu_power?

No.

Quoted 10 lines

If I presumed correctly, then apparently what we're talking about here is computational capacity, as is typically measured in such units as MIPS, megaflops/sec or Drystones. In other words, what Andrew termed "computing power" when he fired the starter's pistol on this scrum.

Is that what this is -- computational capacity, aka computing power (appropriately scaled for the convenience of the arithmetic)?

And is the unit of measure just the number of CPUs in the group (times 128)?

No. That is the case only for some scenarios(for example when power savings is enabled..). In the default performance policy mode, domain characteristics will determine this value.

thanks,
suresh