diff options
author | Jeremy Kerr <jk@ozlabs.org> | 2015-11-02 16:24:45 +0800 |
---|---|---|
committer | Jeremy Kerr <jk@ozlabs.org> | 2015-11-02 16:24:45 +0800 |
commit | 1e45f7e8722a155886d3f4a2e003d1be630605e9 (patch) | |
tree | 7f0c34f48087f2d1ca468a5b7c41ec800c1db4eb /openpower/custom | |
parent | 0b496754cd287deedf3e98a9ba20903b4357b952 (diff) | |
download | blackbird-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.patch | 110 |
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); + } |