From 326867616fb55d6808aa927b9bb5ec22c46b869c Mon Sep 17 00:00:00 2001
From: Emmanuel Vadot <manu@FreeBSD.org>
Date: Thu, 19 Jul 2018 11:28:14 +0000
Subject: [PATCH] kern_cpu: When adding abs frequency allow for unordered
 insertion

Keep the list ordered as some code assume that it is but allow for
unordered cf_settings sets.
---
 sys/kern/kern_cpu.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/sys/kern/kern_cpu.c b/sys/kern/kern_cpu.c
index e7dd1dd9f539..724131d713a9 100644
--- a/sys/kern/kern_cpu.c
+++ b/sys/kern/kern_cpu.c
@@ -680,7 +680,7 @@ cpufreq_insert_abs(struct cpufreq_softc *sc, struct cf_setting *sets,
 {
 	struct cf_level_lst *list;
 	struct cf_level *level, *search;
-	int i;
+	int i, inserted;
 
 	CF_MTX_ASSERT(&sc->lock);
 
@@ -693,6 +693,7 @@ cpufreq_insert_abs(struct cpufreq_softc *sc, struct cf_setting *sets,
 		level->total_set = sets[i];
 		level->total_set.dev = NULL;
 		sc->all_count++;
+		inserted = 0;
 
 		if (TAILQ_EMPTY(list)) {
 			CF_DEBUG("adding abs setting %d at head\n",
@@ -701,15 +702,26 @@ cpufreq_insert_abs(struct cpufreq_softc *sc, struct cf_setting *sets,
 			continue;
 		}
 
-		TAILQ_FOREACH_REVERSE(search, list, cf_level_lst, link) {
+		TAILQ_FOREACH_REVERSE(search, list, cf_level_lst, link)
 			if (sets[i].freq <= search->total_set.freq) {
 				CF_DEBUG("adding abs setting %d after %d\n",
 				    sets[i].freq, search->total_set.freq);
 				TAILQ_INSERT_AFTER(list, search, level, link);
+				inserted = 1;
 				break;
 			}
+
+		if (inserted == 0) {
+			TAILQ_FOREACH(search, list, link)
+				if (sets[i].freq >= search->total_set.freq) {
+					CF_DEBUG("adding abs setting %d before %d\n",
+					    sets[i].freq, search->total_set.freq);
+					TAILQ_INSERT_BEFORE(search, level, link);
+					break;
+				}
 		}
 	}
+
 	return (0);
 }