Commit b02d735bf252 ('ppc64 kdump device_tree sort') added code to sort device tree properties, but it had a few issues. A compare routine needs to return -1 and 1. The special case for sorting properties with unit addresses only returned 1 and ignored the opposite case, which screwed up the sorting. We were missing a few more things: - Need to check both basenames are the same length - Need to check both basenames match I noticed this when looking at the NUMA topology after a kexec, and it had shifted. Signed-off-by: Anton Blanchard <anton at samba.org> --- kexec/fs2dt.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/kexec/fs2dt.c b/kexec/fs2dt.c index 1e5f074..304f6cb 100644 --- a/kexec/fs2dt.c +++ b/kexec/fs2dt.c @@ -479,6 +479,8 @@ static int comparefunc(const struct dirent **dentry1, { char *str1 = (*(struct dirent **)dentry1)->d_name; char *str2 = (*(struct dirent **)dentry2)->d_name; + char *sep1 = strchr(str1, '@'); + char *sep2 = strchr(str2, '@'); /* * strcmp scans from left to right and fails to idetify for some @@ -486,9 +488,20 @@ static int comparefunc(const struct dirent **dentry1, * Therefore, we get the wrong sorted order like memory at 10000000 and * memory at f000000. */ - if (strchr(str1, '@') && strchr(str2, '@') && - (strlen(str1) > strlen(str2))) - return 1; + if (sep1 && sep2) { + int baselen1 = sep1 - str1; + int baselen2 = sep2 - str2; + int len1 = strlen(str1); + int len2 = strlen(str2); + + /* + * Check the base name matches, and the properties are + * different lengths. + */ + if ((baselen1 == baselen2) && (len1 != len2) && + !strncmp(str1, str2, baselen2)) + return (len1 > len2) - (len1 < len2); + } return strcmp(str1, str2); } -- 1.9.1