Patchwork MP table multicore patch

login
register
about
Submitter tpearson@raptorengineeringinc.com
Date 2010-02-11 19:10:18
Message ID <47584.192.168.1.70.1265915418.squirrel@vali.starlink.edu>
Download mbox | patch
Permalink /patch/914/
State Superseded
Headers show

Comments

tpearson@raptorengineeringinc.com - 2010-02-11 19:10:18
I have patched src/arch/i386/smp/mpspec.c to write a correct, multi-core
MP table under amdfam10.  The change is mainly to add APIC cluster
scanning support, as the amdfam10 processors place all auxiliary APICs
under one APIC cluster device.

Before this patch on my MSI 9652 board an MP table was written with only
one CPU.  After the patch the MP table contained all 8 installed cores, 4
in each physical socket.

Patch is attached.  If accepted, the ACPI code should also be updated in a
similar manner.

Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>

---

Re-sending as requested.

Timothy Pearson
Raptor Engineering
Peter Stuge - 2010-02-12 09:37:33
tpearson@raptorengineeringinc.com wrote:
> I have patched src/arch/i386/smp/mpspec.c to write a correct, multi-core
> MP table under amdfam10.

I think this is very desirable and a great functionality improvement!


> +	// First, scan the root node for APIC clusters and APICs
> +	for(root_tree_iter=0;root_tree_iter<(all_devices->links);root_tree_iter++) {
> +		for(child_tree_iter=0;child_tree_iter<(all_devices->links);child_tree_iter++) {
> +			for (child=all_devices->link[child_tree_iter].children; child; child=child->sibling) {
> +				// Is this an APIC?
> +				if (child->path.type == DEVICE_PATH_APIC) {
> +					// Found an APIC, add it to the MP table
> +					if (child->enabled) {
> +						unsigned long cpu_flag;
> +						cpu_flag = MPC_CPU_ENABLED;
> +						if (boot_apic_id == child->path.apic.apic_id) {
> +							cpu_flag = MPC_CPU_ENABLED | MPC_CPU_BOOTPROCESSOR;
> +						}
> +						smp_write_processor(mc, 
> +							child->path.apic.apic_id, apic_version,
> +							cpu_flag, cpu_features, cpu_feature_flags
> +						);
> +					}
> +				}
> +				// Or an APIC cluster?
> +				if (child->path.type == DEVICE_PATH_APIC_CLUSTER) {
> +					// Found an APIC cluster, scan it for APICs
> +					for(apicc_child_tree_iter=0;apicc_child_tree_iter<(child->links);apicc_child_tree_iter++) {
> +						for (apicc_child=child->link[apicc_child_tree_iter].children; apicc_child; apicc_child=apicc_child->sibling) {
> +							// Is this an APIC?
> +							if (apicc_child->path.type == DEVICE_PATH_APIC) {
> +								// Found an APIC, add it to the MP table
> +								if (apicc_child->enabled) {
> +									unsigned long cpu_flag;
> +									cpu_flag = MPC_CPU_ENABLED;
> +									if (boot_apic_id == apicc_child->path.apic.apic_id) {
> +										cpu_flag = MPC_CPU_ENABLED | MPC_CPU_BOOTPROCESSOR;
> +									}
> +									smp_write_processor(mc, 
> +										apicc_child->path.apic.apic_id, apic_version,
> +										cpu_flag, cpu_features, cpu_feature_flags
> +									);
> +								}
> +							}
> +						}
> +					}
> +				}
> +			}
>  		}
>  	}

But this code is not nice at all.

Could you shift it around so that it uses continue aggressively, and
has shorter variable names? It looks like that could reduce
indentation two or three levels, and then the code might actually be
visible in my terminal...

Is this romcc code? If not, maybe it could even be recursive..


//Peter

Patch

--- src/arch/i386/smp/mpspec.c
+++ src/arch/i386/smp/mpspec.c
@@ -105,31 +105,63 @@ 
 	unsigned cpu_features;
 	unsigned cpu_feature_flags;
 	struct cpuid_result result;
+	int root_tree_iter;
+	int child_tree_iter;
+	int apicc_child_tree_iter;
+	struct device *child;
+	struct device *apicc_child;
 	
 	boot_apic_id = lapicid();
 	apic_version = lapic_read(LAPIC_LVR) & 0xff;
 	result = cpuid(1);
 	cpu_features = result.eax;
 	cpu_feature_flags = result.edx;
-	for(cpu = all_devices; cpu; cpu = cpu->next) {
-		unsigned long cpu_flag;
-		if ((cpu->path.type != DEVICE_PATH_APIC) || 
-			(cpu->bus->dev->path.type != DEVICE_PATH_APIC_CLUSTER))
-		{
-			continue;
-		}
-		if (!cpu->enabled) {
-			continue;
-		}
-		cpu_flag = MPC_CPU_ENABLED;
-		if (boot_apic_id == cpu->path.apic.apic_id) {
-			cpu_flag = MPC_CPU_ENABLED | MPC_CPU_BOOTPROCESSOR;
+
+	// First, scan the root node for APIC clusters and APICs
+	for(root_tree_iter=0;root_tree_iter<(all_devices->links);root_tree_iter++) {
+		for(child_tree_iter=0;child_tree_iter<(all_devices->links);child_tree_iter++) {
+			for (child=all_devices->link[child_tree_iter].children; child; child=child->sibling) {
+				// Is this an APIC?
+				if (child->path.type == DEVICE_PATH_APIC) {
+					// Found an APIC, add it to the MP table
+					if (child->enabled) {
+						unsigned long cpu_flag;
+						cpu_flag = MPC_CPU_ENABLED;
+						if (boot_apic_id == child->path.apic.apic_id) {
+							cpu_flag = MPC_CPU_ENABLED | MPC_CPU_BOOTPROCESSOR;
+						}
+						smp_write_processor(mc, 
+							child->path.apic.apic_id, apic_version,
+							cpu_flag, cpu_features, cpu_feature_flags
+						);
+					}
+				}
+				// Or an APIC cluster?
+				if (child->path.type == DEVICE_PATH_APIC_CLUSTER) {
+					// Found an APIC cluster, scan it for APICs
+					for(apicc_child_tree_iter=0;apicc_child_tree_iter<(child->links);apicc_child_tree_iter++) {
+						for (apicc_child=child->link[apicc_child_tree_iter].children; apicc_child; apicc_child=apicc_child->sibling) {
+							// Is this an APIC?
+							if (apicc_child->path.type == DEVICE_PATH_APIC) {
+								// Found an APIC, add it to the MP table
+								if (apicc_child->enabled) {
+									unsigned long cpu_flag;
+									cpu_flag = MPC_CPU_ENABLED;
+									if (boot_apic_id == apicc_child->path.apic.apic_id) {
+										cpu_flag = MPC_CPU_ENABLED | MPC_CPU_BOOTPROCESSOR;
+									}
+									smp_write_processor(mc, 
+										apicc_child->path.apic.apic_id, apic_version,
+										cpu_flag, cpu_features, cpu_feature_flags
+									);
+								}
+							}
+						}
+					}
+				}
+			}
 		}
-		smp_write_processor(mc, 
-			cpu->path.apic.apic_id, apic_version,
-			cpu_flag, cpu_features, cpu_feature_flags
-		);
 	}
 }