From 61598093bbdd283a7edc367d900f223070ead8d2 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Fri, 10 May 2024 07:43:03 +0000
Subject: [PATCH] add ax88772C AX88772C_eeprom_tools

---
 kernel/kernel/sched/cpupri.c |   66 +++++++++++++++++++++++++++++---
 1 files changed, 59 insertions(+), 7 deletions(-)

diff --git a/kernel/kernel/sched/cpupri.c b/kernel/kernel/sched/cpupri.c
index 3e0c8f9..cb11531 100644
--- a/kernel/kernel/sched/cpupri.c
+++ b/kernel/kernel/sched/cpupri.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  *  kernel/sched/cpupri.c
  *
@@ -20,11 +21,6 @@
  *  searches).  For tasks with affinity restrictions, the algorithm has a
  *  worst case complexity of O(min(102, nr_domcpus)), though the scenario that
  *  yields the worst case search is fairly contrived.
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; version 2
- *  of the License.
  */
 #include "sched.h"
 
@@ -45,8 +41,29 @@
 	return cpupri;
 }
 
+#ifdef CONFIG_RT_SOFTINT_OPTIMIZATION
+/**
+ * drop_nopreempt_cpus - remove likely nonpreemptible cpus from the mask
+ * @lowest_mask: mask with selected CPUs (non-NULL)
+ */
+static void
+drop_nopreempt_cpus(struct cpumask *lowest_mask)
+{
+	unsigned int cpu = cpumask_first(lowest_mask);
+	while (cpu < nr_cpu_ids) {
+		/* unlocked access */
+		struct task_struct *task = READ_ONCE(cpu_rq(cpu)->curr);
+		if (task_may_not_preempt(task, cpu)) {
+			cpumask_clear_cpu(cpu, lowest_mask);
+		}
+		cpu = cpumask_next(cpu, lowest_mask);
+	}
+}
+#endif
+
 static inline int __cpupri_find(struct cpupri *cp, struct task_struct *p,
-				struct cpumask *lowest_mask, int idx)
+				struct cpumask *lowest_mask, int idx,
+				bool drop_nopreempts)
 {
 	struct cpupri_vec *vec  = &cp->pri_to_cpu[idx];
 	int skip = 0;
@@ -82,6 +99,12 @@
 
 	if (lowest_mask) {
 		cpumask_and(lowest_mask, p->cpus_ptr, vec->mask);
+		cpumask_and(lowest_mask, lowest_mask, cpu_active_mask);
+
+#ifdef CONFIG_RT_SOFTINT_OPTIMIZATION
+		if (drop_nopreempts)
+			drop_nopreempt_cpus(lowest_mask);
+#endif
 
 		/*
 		 * We have to ensure that we have at least one bit
@@ -127,12 +150,16 @@
 {
 	int task_pri = convert_prio(p->prio);
 	int idx, cpu;
+	bool drop_nopreempts = task_pri <= MAX_RT_PRIO;
 
 	BUG_ON(task_pri >= CPUPRI_NR_PRIORITIES);
 
+#ifdef CONFIG_RT_SOFTINT_OPTIMIZATION
+retry:
+#endif
 	for (idx = 0; idx < task_pri; idx++) {
 
-		if (!__cpupri_find(cp, p, lowest_mask, idx))
+		if (!__cpupri_find(cp, p, lowest_mask, idx, drop_nopreempts))
 			continue;
 
 		if (!lowest_mask || !fitness_fn)
@@ -153,6 +180,17 @@
 
 		return 1;
 	}
+
+	/*
+	 * If we can't find any non-preemptible cpu's, retry so we can
+	 * find the lowest priority target and avoid priority inversion.
+	 */
+#ifdef CONFIG_RT_SOFTINT_OPTIMIZATION
+	if (drop_nopreempts) {
+		drop_nopreempts = false;
+		goto retry;
+	}
+#endif
 
 	/*
 	 * If we failed to find a fitting lowest_mask, kick off a new search
@@ -176,6 +214,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(cpupri_find_fitness);
 
 /**
  * cpupri_set - update the CPU priority setting
@@ -294,3 +333,16 @@
 	for (i = 0; i < CPUPRI_NR_PRIORITIES; i++)
 		free_cpumask_var(cp->pri_to_cpu[i].mask);
 }
+
+#ifdef CONFIG_RT_SOFTINT_OPTIMIZATION
+/*
+ * cpupri_check_rt - check if CPU has a RT task
+ * should be called from rcu-sched read section.
+ */
+bool cpupri_check_rt(void)
+{
+	int cpu = raw_smp_processor_id();
+
+	return cpu_rq(cpu)->rd->cpupri.cpu_to_pri[cpu] > CPUPRI_NORMAL;
+}
+#endif

--
Gitblit v1.6.2