summaryrefslogtreecommitdiffstats
path: root/openpower/custom
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2015-11-02 16:24:45 +0800
committerJeremy Kerr <jk@ozlabs.org>2015-11-02 16:24:45 +0800
commit1e45f7e8722a155886d3f4a2e003d1be630605e9 (patch)
tree7f0c34f48087f2d1ca468a5b7c41ec800c1db4eb /openpower/custom
parent0b496754cd287deedf3e98a9ba20903b4357b952 (diff)
downloadblackbird-op-build-1e45f7e8722a155886d3f4a2e003d1be630605e9.tar.gz
blackbird-op-build-1e45f7e8722a155886d3f4a2e003d1be630605e9.zip
dtc,petitboot: Sort device tree properties by unit number
Currently, dtc will output nodes unordered, which may cause issues when assigning CPU numbers to NUMA nodes. This change incorporates a pre-kexec hook to sort the device tree, and a fix for dtc to order nodes by their unit number, to get a proper sort ordering. Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Diffstat (limited to 'openpower/custom')
-rw-r--r--openpower/custom/patches/dtc/dtc-0001-sort-unit-addresses-by-number.patch110
1 files changed, 110 insertions, 0 deletions
diff --git a/openpower/custom/patches/dtc/dtc-0001-sort-unit-addresses-by-number.patch b/openpower/custom/patches/dtc/dtc-0001-sort-unit-addresses-by-number.patch
new file mode 100644
index 00000000..6f49dbc4
--- /dev/null
+++ b/openpower/custom/patches/dtc/dtc-0001-sort-unit-addresses-by-number.patch
@@ -0,0 +1,110 @@
+Date: Tue, 21 Jan 2014 13:49:35 +1100
+From: Anton Blanchard <anton@samba.org>
+Subject: [PATCH] dtc: Sort unit addresses by number
+
+The sort option in dtc treats unit addresses as strings. This causes
+cpu nodes to end up out of order:
+
+# dtc -s -I fs -O dts /proc/device-tree | grep PowerPC,POWER7
+
+ PowerPC,POWER7@30 {
+ PowerPC,POWER7@68 {
+ PowerPC,POWER7@70 {
+ PowerPC,POWER7@828 {
+ PowerPC,POWER7@860 {
+ PowerPC,POWER7@868 {
+ PowerPC,POWER7@8a0 {
+ PowerPC,POWER7@8b0 {
+ PowerPC,POWER7@8f0 {
+ PowerPC,POWER7@a0 {
+ PowerPC,POWER7@a8 {
+ PowerPC,POWER7@e0 {
+
+If we use this device tree for a kexec boot we end up with a confusing
+layout of logical CPUs:
+
+node 0 cpus: 0-23 72-95
+node 0 size: 32633 MB
+
+node 1 cpus: 24-71
+node 1 size: 32631 MB
+
+The reason for this is that we allocate logical CPU ids as we walk
+through the device tree.
+
+In cmp_subnode, if both nodes have a hex unit address and the
+basenames match, then compare by number.
+
+This fixes the issue:
+
+# dtc -s -I fs -O dts /proc/device-tree | grep PowerPC,POWER7
+ PowerPC,POWER7@30 {
+ PowerPC,POWER7@68 {
+ PowerPC,POWER7@70 {
+ PowerPC,POWER7@a0 {
+ PowerPC,POWER7@a8 {
+ PowerPC,POWER7@e0 {
+ PowerPC,POWER7@828 {
+ PowerPC,POWER7@860 {
+ PowerPC,POWER7@868 {
+ PowerPC,POWER7@8a0 {
+ PowerPC,POWER7@8b0 {
+ PowerPC,POWER7@8f0 {
+
+And the CPU layout is as expected:
+
+node 0 cpus: 0-47
+node 0 size: 32633 MB
+
+node 1 cpus: 48-95
+node 1 size: 32631 MB
+
+Signed-off-by: Anton Blanchard <anton@samba.org>
+--
+
+Index: b/livetree.c
+===================================================================
+--- a/livetree.c
++++ b/livetree.c
+@@ -656,12 +656,38 @@ static void sort_properties(struct node
+ free(tbl);
+ }
+
++static bool is_hex(const char *str)
++{
++ while (*str) {
++ if (!isxdigit(*str++))
++ return false;
++ }
++
++ return true;
++}
++
+ static int cmp_subnode(const void *ax, const void *bx)
+ {
+- const struct node *a, *b;
++ struct node *a, *b;
++ const char *a_unit, *b_unit;
++
++ a = *((struct node * const *)ax);
++ b = *((struct node * const *)bx);
++
++ a_unit = get_unitname(a);
++ b_unit = get_unitname(b);
++
++ /* Sort hex unit addresses by number */
++ if (a_unit && b_unit && (a->basenamelen == b->basenamelen) &&
++ !strncmp(a->name, b->name, a->basenamelen) &&
++ is_hex(a_unit) && is_hex(b_unit)) {
++ unsigned long long a_num, b_num;
++
++ a_num = strtoull(a_unit, NULL, 16);
++ b_num = strtoull(b_unit, NULL, 16);
+
+- a = *((const struct node * const *)ax);
+- b = *((const struct node * const *)bx);
++ return (a_num > b_num) - (a_num < b_num);
++ }
+
+ return strcmp(a->name, b->name);
+ }
OpenPOWER on IntegriCloud