6.5 RC7
This commit is contained in:
parent
60dc452fb5
commit
ac1b61d8bd
10
config
10
config
@ -1,15 +1,15 @@
|
||||
#
|
||||
# Automatically generated file; DO NOT EDIT.
|
||||
# Linux/x86 6.5.0-rc1 Kernel Configuration
|
||||
# Linux/x86 6.5.0-rc7 Kernel Configuration
|
||||
#
|
||||
CONFIG_CC_VERSION_TEXT="gcc (GCC) 13.1.1 20230525"
|
||||
CONFIG_CC_VERSION_TEXT="gcc (GCC) 13.2.1 20230730"
|
||||
CONFIG_CC_IS_GCC=y
|
||||
CONFIG_GCC_VERSION=130101
|
||||
CONFIG_GCC_VERSION=130201
|
||||
CONFIG_CLANG_VERSION=0
|
||||
CONFIG_AS_IS_GNU=y
|
||||
CONFIG_AS_VERSION=24000
|
||||
CONFIG_AS_VERSION=24100
|
||||
CONFIG_LD_IS_BFD=y
|
||||
CONFIG_LD_VERSION=24000
|
||||
CONFIG_LD_VERSION=24100
|
||||
CONFIG_LLD_VERSION=0
|
||||
CONFIG_RUST_IS_AVAILABLE=y
|
||||
CONFIG_CC_CAN_LINK=y
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
From 218c51e49185b75b4e36c8f11b5c77686f955a0a Mon Sep 17 00:00:00 2001
|
||||
From 6d15f875cb0c7fd65fc422c0545d57fc2e124f7c Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jung <admin@ptr1337.dev>
|
||||
Date: Sun, 30 Jul 2023 09:38:51 +0200
|
||||
Subject: [PATCH] EEVDF
|
||||
Date: Sun, 20 Aug 2023 15:56:13 +0200
|
||||
Subject: [PATCH] EEVDF-cachy
|
||||
|
||||
Signed-off-by: Peter Jung <admin@ptr1337.dev>
|
||||
---
|
||||
@ -13,14 +13,14 @@ Signed-off-by: Peter Jung <admin@ptr1337.dev>
|
||||
init/init_task.c | 3 +-
|
||||
kernel/sched/core.c | 65 +-
|
||||
kernel/sched/debug.c | 49 +-
|
||||
kernel/sched/fair.c | 1138 +++++++++++------------
|
||||
kernel/sched/features.h | 23 +-
|
||||
kernel/sched/fair.c | 1150 +++++++++++------------
|
||||
kernel/sched/features.h | 24 +-
|
||||
kernel/sched/sched.h | 21 +-
|
||||
tools/include/uapi/linux/sched.h | 4 +-
|
||||
12 files changed, 702 insertions(+), 668 deletions(-)
|
||||
12 files changed, 715 insertions(+), 668 deletions(-)
|
||||
|
||||
diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst
|
||||
index 4ef890191196..3a8d3e1e5591 100644
|
||||
index 4ef8901911961..3a8d3e1e55910 100644
|
||||
--- a/Documentation/admin-guide/cgroup-v2.rst
|
||||
+++ b/Documentation/admin-guide/cgroup-v2.rst
|
||||
@@ -1121,6 +1121,16 @@ All time durations are in microseconds.
|
||||
@ -41,7 +41,7 @@ index 4ef890191196..3a8d3e1e5591 100644
|
||||
|
||||
Memory
|
||||
diff --git a/include/linux/rbtree_augmented.h b/include/linux/rbtree_augmented.h
|
||||
index 7ee7ed5de722..6dbc5a1bf6a8 100644
|
||||
index 7ee7ed5de7227..6dbc5a1bf6a8c 100644
|
||||
--- a/include/linux/rbtree_augmented.h
|
||||
+++ b/include/linux/rbtree_augmented.h
|
||||
@@ -60,6 +60,32 @@ rb_insert_augmented_cached(struct rb_node *node,
|
||||
@ -78,7 +78,7 @@ index 7ee7ed5de722..6dbc5a1bf6a8 100644
|
||||
* Template for declaring augmented rbtree callbacks (generic case)
|
||||
*
|
||||
diff --git a/include/linux/sched.h b/include/linux/sched.h
|
||||
index 609bde814cb0..c940c4dc8304 100644
|
||||
index 609bde814cb06..c940c4dc83048 100644
|
||||
--- a/include/linux/sched.h
|
||||
+++ b/include/linux/sched.h
|
||||
@@ -549,13 +549,18 @@ struct sched_entity {
|
||||
@ -110,7 +110,7 @@ index 609bde814cb0..c940c4dc8304 100644
|
||||
struct sched_entity se;
|
||||
struct sched_rt_entity rt;
|
||||
diff --git a/include/uapi/linux/sched.h b/include/uapi/linux/sched.h
|
||||
index 3bac0a8ceab2..b2e932c25be6 100644
|
||||
index 3bac0a8ceab26..b2e932c25be62 100644
|
||||
--- a/include/uapi/linux/sched.h
|
||||
+++ b/include/uapi/linux/sched.h
|
||||
@@ -132,6 +132,7 @@ struct clone_args {
|
||||
@ -131,7 +131,7 @@ index 3bac0a8ceab2..b2e932c25be6 100644
|
||||
|
||||
#endif /* _UAPI_LINUX_SCHED_H */
|
||||
diff --git a/include/uapi/linux/sched/types.h b/include/uapi/linux/sched/types.h
|
||||
index f2c4589d4dbf..db1e8199e8c8 100644
|
||||
index f2c4589d4dbfe..db1e8199e8c80 100644
|
||||
--- a/include/uapi/linux/sched/types.h
|
||||
+++ b/include/uapi/linux/sched/types.h
|
||||
@@ -10,6 +10,7 @@ struct sched_param {
|
||||
@ -175,7 +175,7 @@ index f2c4589d4dbf..db1e8199e8c8 100644
|
||||
|
||||
#endif /* _UAPI_LINUX_SCHED_TYPES_H */
|
||||
diff --git a/init/init_task.c b/init/init_task.c
|
||||
index ff6c4b9bfe6b..511cbcf3510d 100644
|
||||
index ff6c4b9bfe6b1..511cbcf3510dc 100644
|
||||
--- a/init/init_task.c
|
||||
+++ b/init/init_task.c
|
||||
@@ -78,6 +78,7 @@ struct task_struct init_task
|
||||
@ -196,7 +196,7 @@ index ff6c4b9bfe6b..511cbcf3510d 100644
|
||||
.rt = {
|
||||
.run_list = LIST_HEAD_INIT(init_task.rt.run_list),
|
||||
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
|
||||
index c52c2eba7c73..aff81e12460e 100644
|
||||
index c52c2eba7c739..aff81e12460ed 100644
|
||||
--- a/kernel/sched/core.c
|
||||
+++ b/kernel/sched/core.c
|
||||
@@ -1305,6 +1305,12 @@ static void set_load_weight(struct task_struct *p, bool update_load)
|
||||
@ -358,7 +358,7 @@ index c52c2eba7c73..aff81e12460e 100644
|
||||
#ifdef CONFIG_CFS_BANDWIDTH
|
||||
{
|
||||
diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
|
||||
index 066ff1c8ae4e..e7e83181fbb6 100644
|
||||
index 066ff1c8ae4eb..e7e83181fbb6c 100644
|
||||
--- a/kernel/sched/debug.c
|
||||
+++ b/kernel/sched/debug.c
|
||||
@@ -347,10 +347,7 @@ static __init int sched_init_debug(void)
|
||||
@ -462,7 +462,7 @@ index 066ff1c8ae4e..e7e83181fbb6 100644
|
||||
P(dl.runtime);
|
||||
P(dl.deadline);
|
||||
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
|
||||
index 2c335df30171..461409c0eac7 100644
|
||||
index 2c335df301718..e0a4c13dab04f 100644
|
||||
--- a/kernel/sched/fair.c
|
||||
+++ b/kernel/sched/fair.c
|
||||
@@ -47,6 +47,7 @@
|
||||
@ -868,7 +868,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
}
|
||||
|
||||
struct sched_entity *__pick_first_entity(struct cfs_rq *cfs_rq)
|
||||
@@ -678,14 +845,81 @@ struct sched_entity *__pick_first_entity(struct cfs_rq *cfs_rq)
|
||||
@@ -678,14 +845,88 @@ struct sched_entity *__pick_first_entity(struct cfs_rq *cfs_rq)
|
||||
return __node_2_se(left);
|
||||
}
|
||||
|
||||
@ -904,6 +904,13 @@ index 2c335df30171..461409c0eac7 100644
|
||||
+ if (curr && (!curr->on_rq || !entity_eligible(cfs_rq, curr)))
|
||||
+ curr = NULL;
|
||||
+
|
||||
+ /*
|
||||
+ * Once selected, run a task until it either becomes non-eligible or
|
||||
+ * until it gets a new slice. See the HACK in set_next_entity().
|
||||
+ */
|
||||
+ if (sched_feat(RUN_TO_PARITY) && curr && curr->vlag == curr->deadline)
|
||||
+ return curr;
|
||||
+
|
||||
+ while (node) {
|
||||
+ struct sched_entity *se = __node_2_se(node);
|
||||
+
|
||||
@ -938,8 +945,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
+
|
||||
+ node = node->rb_right;
|
||||
+ }
|
||||
|
||||
- return __node_2_se(next);
|
||||
+
|
||||
+ if (!best || (curr && deadline_gt(deadline, best, curr)))
|
||||
+ best = curr;
|
||||
+
|
||||
@ -950,12 +956,13 @@ index 2c335df30171..461409c0eac7 100644
|
||||
+ return left;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
|
||||
- return __node_2_se(next);
|
||||
+ return best;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SCHED_DEBUG
|
||||
@@ -707,104 +941,53 @@ int sched_update_scaling(void)
|
||||
@@ -707,104 +948,53 @@ int sched_update_scaling(void)
|
||||
{
|
||||
unsigned int factor = get_update_sysctl_factor();
|
||||
|
||||
@ -982,12 +989,12 @@ index 2c335df30171..461409c0eac7 100644
|
||||
{
|
||||
- if (unlikely(se->load.weight != NICE_0_LOAD))
|
||||
- delta = __calc_delta(delta, NICE_0_LOAD, &se->load);
|
||||
-
|
||||
- return delta;
|
||||
-}
|
||||
+ u32 weight = sched_prio_to_weight[prio];
|
||||
+ u64 base = sysctl_sched_base_slice;
|
||||
|
||||
- return delta;
|
||||
-}
|
||||
-
|
||||
-/*
|
||||
- * The idea is to set a period in which each task runs once.
|
||||
- *
|
||||
@ -1088,7 +1095,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
}
|
||||
|
||||
#include "pelt.h"
|
||||
@@ -939,6 +1122,7 @@ static void update_curr(struct cfs_rq *cfs_rq)
|
||||
@@ -939,6 +1129,7 @@ static void update_curr(struct cfs_rq *cfs_rq)
|
||||
schedstat_add(cfs_rq->exec_clock, delta_exec);
|
||||
|
||||
curr->vruntime += calc_delta_fair(delta_exec, curr);
|
||||
@ -1096,7 +1103,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
update_min_vruntime(cfs_rq);
|
||||
|
||||
if (entity_is_task(curr)) {
|
||||
@@ -3393,16 +3577,36 @@ dequeue_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se) { }
|
||||
@@ -3393,16 +3584,36 @@ dequeue_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se) { }
|
||||
static void reweight_entity(struct cfs_rq *cfs_rq, struct sched_entity *se,
|
||||
unsigned long weight)
|
||||
{
|
||||
@ -1133,7 +1140,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
#ifdef CONFIG_SMP
|
||||
do {
|
||||
u32 divider = get_pelt_divider(&se->avg);
|
||||
@@ -3412,9 +3616,11 @@ static void reweight_entity(struct cfs_rq *cfs_rq, struct sched_entity *se,
|
||||
@@ -3412,9 +3623,11 @@ static void reweight_entity(struct cfs_rq *cfs_rq, struct sched_entity *se,
|
||||
#endif
|
||||
|
||||
enqueue_load_avg(cfs_rq, se);
|
||||
@ -1147,7 +1154,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
}
|
||||
|
||||
void reweight_task(struct task_struct *p, int prio)
|
||||
@@ -4710,158 +4916,123 @@ static inline void update_misfit_status(struct task_struct *p, struct rq *rq) {}
|
||||
@@ -4710,158 +4923,123 @@ static inline void update_misfit_status(struct task_struct *p, struct rq *rq) {}
|
||||
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
@ -1170,15 +1177,15 @@ index 2c335df30171..461409c0eac7 100644
|
||||
{
|
||||
- struct cfs_rq *cfs_rq;
|
||||
- u64 sleep_time;
|
||||
-
|
||||
- if (se->exec_start == 0)
|
||||
- return false;
|
||||
-
|
||||
- cfs_rq = cfs_rq_of(se);
|
||||
+ u64 vslice = calc_delta_fair(se->slice, se);
|
||||
+ u64 vruntime = avg_vruntime(cfs_rq);
|
||||
+ s64 lag = 0;
|
||||
|
||||
- if (se->exec_start == 0)
|
||||
- return false;
|
||||
-
|
||||
- cfs_rq = cfs_rq_of(se);
|
||||
-
|
||||
- sleep_time = rq_clock_task(rq_of(cfs_rq));
|
||||
+ /*
|
||||
+ * Due to how V is constructed as the weighted average of entities,
|
||||
@ -1395,7 +1402,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
/*
|
||||
* When enqueuing a sched_entity, we must:
|
||||
* - Update loads to have both entity and cfs_rq synced with now.
|
||||
@@ -4873,18 +5044,28 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
|
||||
@@ -4873,18 +5051,28 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
|
||||
*/
|
||||
update_load_avg(cfs_rq, se, UPDATE_TG | DO_ATTACH);
|
||||
se_update_runnable(se);
|
||||
@ -1427,7 +1434,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
if (!curr)
|
||||
__enqueue_entity(cfs_rq, se);
|
||||
se->on_rq = 1;
|
||||
@@ -4896,17 +5077,6 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
|
||||
@@ -4896,17 +5084,6 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1445,7 +1452,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
static void __clear_buddies_next(struct sched_entity *se)
|
||||
{
|
||||
for_each_sched_entity(se) {
|
||||
@@ -4918,27 +5088,10 @@ static void __clear_buddies_next(struct sched_entity *se)
|
||||
@@ -4918,27 +5095,10 @@ static void __clear_buddies_next(struct sched_entity *se)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1473,7 +1480,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
}
|
||||
|
||||
static __always_inline void return_cfs_rq_runtime(struct cfs_rq *cfs_rq);
|
||||
@@ -4972,20 +5125,12 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
|
||||
@@ -4972,20 +5132,12 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
|
||||
|
||||
clear_buddies(cfs_rq, se);
|
||||
|
||||
@ -1495,7 +1502,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
/* return excess runtime on last dequeue */
|
||||
return_cfs_rq_runtime(cfs_rq);
|
||||
|
||||
@@ -5004,52 +5149,6 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
|
||||
@@ -5004,52 +5156,6 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
|
||||
update_idle_cfs_rq_clock_pelt(cfs_rq);
|
||||
}
|
||||
|
||||
@ -1548,7 +1555,19 @@ index 2c335df30171..461409c0eac7 100644
|
||||
static void
|
||||
set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
|
||||
{
|
||||
@@ -5088,9 +5187,6 @@ set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
|
||||
@@ -5065,6 +5171,11 @@ set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
|
||||
update_stats_wait_end_fair(cfs_rq, se);
|
||||
__dequeue_entity(cfs_rq, se);
|
||||
update_load_avg(cfs_rq, se, UPDATE_TG);
|
||||
+ /*
|
||||
+ * HACK, stash a copy of deadline at the point of pick in vlag,
|
||||
+ * which isn't used until dequeue.
|
||||
+ */
|
||||
+ se->vlag = se->deadline;
|
||||
}
|
||||
|
||||
update_stats_curr_start(cfs_rq, se);
|
||||
@@ -5088,9 +5199,6 @@ set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
|
||||
se->prev_sum_exec_runtime = se->sum_exec_runtime;
|
||||
}
|
||||
|
||||
@ -1558,30 +1577,33 @@ index 2c335df30171..461409c0eac7 100644
|
||||
/*
|
||||
* Pick the next process, keeping these things in mind, in this order:
|
||||
* 1) keep things fair between processes/task groups
|
||||
@@ -5101,50 +5197,14 @@ wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se);
|
||||
@@ -5101,50 +5209,14 @@ wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se);
|
||||
static struct sched_entity *
|
||||
pick_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *curr)
|
||||
{
|
||||
- struct sched_entity *left = __pick_first_entity(cfs_rq);
|
||||
- struct sched_entity *se;
|
||||
-
|
||||
/*
|
||||
- /*
|
||||
- * If curr is set we have to see if its left of the leftmost entity
|
||||
- * still in the tree, provided there was anything in the tree at all.
|
||||
+ * Enabling NEXT_BUDDY will affect latency but not fairness.
|
||||
*/
|
||||
- */
|
||||
- if (!left || (curr && entity_before(curr, left)))
|
||||
- left = curr;
|
||||
-
|
||||
- se = left; /* ideally we run the leftmost entity */
|
||||
-
|
||||
- /*
|
||||
/*
|
||||
- * Avoid running the skip buddy, if running something else can
|
||||
- * be done without getting too unfair.
|
||||
- */
|
||||
+ * Enabling NEXT_BUDDY will affect latency but not fairness.
|
||||
*/
|
||||
- if (cfs_rq->skip && cfs_rq->skip == se) {
|
||||
- struct sched_entity *second;
|
||||
-
|
||||
+ if (sched_feat(NEXT_BUDDY) &&
|
||||
+ cfs_rq->next && entity_eligible(cfs_rq, cfs_rq->next))
|
||||
+ return cfs_rq->next;
|
||||
|
||||
- if (se == curr) {
|
||||
- second = __pick_first_entity(cfs_rq);
|
||||
- } else {
|
||||
@ -1589,10 +1611,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
- if (!second || (curr && entity_before(curr, second)))
|
||||
- second = curr;
|
||||
- }
|
||||
+ if (sched_feat(NEXT_BUDDY) &&
|
||||
+ cfs_rq->next && entity_eligible(cfs_rq, cfs_rq->next))
|
||||
+ return cfs_rq->next;
|
||||
|
||||
-
|
||||
- if (second && wakeup_preempt_entity(second, left) < 1)
|
||||
- se = second;
|
||||
- }
|
||||
@ -1614,7 +1633,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
}
|
||||
|
||||
static bool check_cfs_rq_runtime(struct cfs_rq *cfs_rq);
|
||||
@@ -5161,8 +5221,6 @@ static void put_prev_entity(struct cfs_rq *cfs_rq, struct sched_entity *prev)
|
||||
@@ -5161,8 +5233,6 @@ static void put_prev_entity(struct cfs_rq *cfs_rq, struct sched_entity *prev)
|
||||
/* throttle cfs_rqs exceeding runtime */
|
||||
check_cfs_rq_runtime(cfs_rq);
|
||||
|
||||
@ -1623,7 +1642,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
if (prev->on_rq) {
|
||||
update_stats_wait_start_fair(cfs_rq, prev);
|
||||
/* Put 'current' back into the tree. */
|
||||
@@ -5203,9 +5261,6 @@ entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr, int queued)
|
||||
@@ -5203,9 +5273,6 @@ entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr, int queued)
|
||||
hrtimer_active(&rq_of(cfs_rq)->hrtick_timer))
|
||||
return;
|
||||
#endif
|
||||
@ -1633,7 +1652,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
}
|
||||
|
||||
|
||||
@@ -6228,13 +6283,12 @@ static inline void unthrottle_offline_cfs_rqs(struct rq *rq) {}
|
||||
@@ -6228,13 +6295,12 @@ static inline void unthrottle_offline_cfs_rqs(struct rq *rq) {}
|
||||
static void hrtick_start_fair(struct rq *rq, struct task_struct *p)
|
||||
{
|
||||
struct sched_entity *se = &p->se;
|
||||
@ -1648,7 +1667,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
s64 delta = slice - ran;
|
||||
|
||||
if (delta < 0) {
|
||||
@@ -6258,8 +6312,7 @@ static void hrtick_update(struct rq *rq)
|
||||
@@ -6258,8 +6324,7 @@ static void hrtick_update(struct rq *rq)
|
||||
if (!hrtick_enabled_fair(rq) || curr->sched_class != &fair_sched_class)
|
||||
return;
|
||||
|
||||
@ -1658,7 +1677,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
}
|
||||
#else /* !CONFIG_SCHED_HRTICK */
|
||||
static inline void
|
||||
@@ -6300,17 +6353,6 @@ static int sched_idle_rq(struct rq *rq)
|
||||
@@ -6300,17 +6365,6 @@ static int sched_idle_rq(struct rq *rq)
|
||||
rq->nr_running);
|
||||
}
|
||||
|
||||
@ -1676,7 +1695,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
#ifdef CONFIG_SMP
|
||||
static int sched_idle_cpu(int cpu)
|
||||
{
|
||||
@@ -7816,18 +7858,6 @@ static void migrate_task_rq_fair(struct task_struct *p, int new_cpu)
|
||||
@@ -7816,18 +7870,6 @@ static void migrate_task_rq_fair(struct task_struct *p, int new_cpu)
|
||||
{
|
||||
struct sched_entity *se = &p->se;
|
||||
|
||||
@ -1695,7 +1714,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
if (!task_on_rq_migrating(p)) {
|
||||
remove_entity_load_avg(se);
|
||||
|
||||
@@ -7865,66 +7895,6 @@ balance_fair(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
|
||||
@@ -7865,66 +7907,6 @@ balance_fair(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
|
||||
}
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
@ -1762,7 +1781,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
static void set_next_buddy(struct sched_entity *se)
|
||||
{
|
||||
for_each_sched_entity(se) {
|
||||
@@ -7936,12 +7906,6 @@ static void set_next_buddy(struct sched_entity *se)
|
||||
@@ -7936,12 +7918,6 @@ static void set_next_buddy(struct sched_entity *se)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1775,7 +1794,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
/*
|
||||
* Preempt the current task with a newly woken task if needed:
|
||||
*/
|
||||
@@ -7950,7 +7914,6 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_
|
||||
@@ -7950,7 +7926,6 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_
|
||||
struct task_struct *curr = rq->curr;
|
||||
struct sched_entity *se = &curr->se, *pse = &p->se;
|
||||
struct cfs_rq *cfs_rq = task_cfs_rq(curr);
|
||||
@ -1783,7 +1802,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
int next_buddy_marked = 0;
|
||||
int cse_is_idle, pse_is_idle;
|
||||
|
||||
@@ -7966,7 +7929,7 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_
|
||||
@@ -7966,7 +7941,7 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_
|
||||
if (unlikely(throttled_hierarchy(cfs_rq_of(pse))))
|
||||
return;
|
||||
|
||||
@ -1792,7 +1811,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
set_next_buddy(pse);
|
||||
next_buddy_marked = 1;
|
||||
}
|
||||
@@ -8011,35 +7974,19 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_
|
||||
@@ -8011,35 +7986,19 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_
|
||||
if (cse_is_idle != pse_is_idle)
|
||||
return;
|
||||
|
||||
@ -1835,7 +1854,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
@@ -8240,8 +8187,6 @@ static void put_prev_task_fair(struct rq *rq, struct task_struct *prev)
|
||||
@@ -8240,8 +8199,6 @@ static void put_prev_task_fair(struct rq *rq, struct task_struct *prev)
|
||||
|
||||
/*
|
||||
* sched_yield() is very simple
|
||||
@ -1844,7 +1863,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
*/
|
||||
static void yield_task_fair(struct rq *rq)
|
||||
{
|
||||
@@ -8257,21 +8202,19 @@ static void yield_task_fair(struct rq *rq)
|
||||
@@ -8257,21 +8214,19 @@ static void yield_task_fair(struct rq *rq)
|
||||
|
||||
clear_buddies(cfs_rq, se);
|
||||
|
||||
@ -1878,7 +1897,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
}
|
||||
|
||||
static bool yield_to_task_fair(struct rq *rq, struct task_struct *p)
|
||||
@@ -8514,8 +8457,7 @@ static int task_hot(struct task_struct *p, struct lb_env *env)
|
||||
@@ -8514,8 +8469,7 @@ static int task_hot(struct task_struct *p, struct lb_env *env)
|
||||
* Buddy candidates are cache hot:
|
||||
*/
|
||||
if (sched_feat(CACHE_HOT_BUDDY) && env->dst_rq->nr_running &&
|
||||
@ -1888,7 +1907,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
return 1;
|
||||
|
||||
if (sysctl_sched_migration_cost == -1)
|
||||
@@ -12025,8 +11967,8 @@ static void rq_offline_fair(struct rq *rq)
|
||||
@@ -12025,8 +11979,8 @@ static void rq_offline_fair(struct rq *rq)
|
||||
static inline bool
|
||||
__entity_slice_used(struct sched_entity *se, int min_nr_tasks)
|
||||
{
|
||||
@ -1898,7 +1917,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
|
||||
return (rtime * min_nr_tasks > slice);
|
||||
}
|
||||
@@ -12182,8 +12124,8 @@ static void task_tick_fair(struct rq *rq, struct task_struct *curr, int queued)
|
||||
@@ -12182,8 +12136,8 @@ static void task_tick_fair(struct rq *rq, struct task_struct *curr, int queued)
|
||||
*/
|
||||
static void task_fork_fair(struct task_struct *p)
|
||||
{
|
||||
@ -1908,7 +1927,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
struct rq *rq = this_rq();
|
||||
struct rq_flags rf;
|
||||
|
||||
@@ -12192,22 +12134,9 @@ static void task_fork_fair(struct task_struct *p)
|
||||
@@ -12192,22 +12146,9 @@ static void task_fork_fair(struct task_struct *p)
|
||||
|
||||
cfs_rq = task_cfs_rq(current);
|
||||
curr = cfs_rq->curr;
|
||||
@ -1933,7 +1952,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
rq_unlock(rq, &rf);
|
||||
}
|
||||
|
||||
@@ -12236,34 +12165,6 @@ prio_changed_fair(struct rq *rq, struct task_struct *p, int oldprio)
|
||||
@@ -12236,34 +12177,6 @@ prio_changed_fair(struct rq *rq, struct task_struct *p, int oldprio)
|
||||
check_preempt_curr(rq, p, 0);
|
||||
}
|
||||
|
||||
@ -1968,7 +1987,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
#ifdef CONFIG_FAIR_GROUP_SCHED
|
||||
/*
|
||||
* Propagate the changes of the sched_entity across the tg tree to make it
|
||||
@@ -12334,16 +12235,6 @@ static void attach_entity_cfs_rq(struct sched_entity *se)
|
||||
@@ -12334,16 +12247,6 @@ static void attach_entity_cfs_rq(struct sched_entity *se)
|
||||
static void detach_task_cfs_rq(struct task_struct *p)
|
||||
{
|
||||
struct sched_entity *se = &p->se;
|
||||
@ -1985,7 +2004,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
|
||||
detach_entity_cfs_rq(se);
|
||||
}
|
||||
@@ -12351,12 +12242,8 @@ static void detach_task_cfs_rq(struct task_struct *p)
|
||||
@@ -12351,12 +12254,8 @@ static void detach_task_cfs_rq(struct task_struct *p)
|
||||
static void attach_task_cfs_rq(struct task_struct *p)
|
||||
{
|
||||
struct sched_entity *se = &p->se;
|
||||
@ -1998,7 +2017,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
}
|
||||
|
||||
static void switched_from_fair(struct rq *rq, struct task_struct *p)
|
||||
@@ -12467,6 +12354,7 @@ int alloc_fair_sched_group(struct task_group *tg, struct task_group *parent)
|
||||
@@ -12467,6 +12366,7 @@ int alloc_fair_sched_group(struct task_group *tg, struct task_group *parent)
|
||||
goto err;
|
||||
|
||||
tg->shares = NICE_0_LOAD;
|
||||
@ -2006,7 +2025,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
|
||||
init_cfs_bandwidth(tg_cfs_bandwidth(tg));
|
||||
|
||||
@@ -12565,6 +12453,9 @@ void init_tg_cfs_entry(struct task_group *tg, struct cfs_rq *cfs_rq,
|
||||
@@ -12565,6 +12465,9 @@ void init_tg_cfs_entry(struct task_group *tg, struct cfs_rq *cfs_rq,
|
||||
}
|
||||
|
||||
se->my_q = cfs_rq;
|
||||
@ -2016,7 +2035,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
/* guarantee group entities always have weight */
|
||||
update_load_set(&se->load, NICE_0_LOAD);
|
||||
se->parent = parent;
|
||||
@@ -12695,6 +12586,29 @@ int sched_group_set_idle(struct task_group *tg, long idle)
|
||||
@@ -12695,6 +12598,29 @@ int sched_group_set_idle(struct task_group *tg, long idle)
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2046,7 +2065,7 @@ index 2c335df30171..461409c0eac7 100644
|
||||
#else /* CONFIG_FAIR_GROUP_SCHED */
|
||||
|
||||
void free_fair_sched_group(struct task_group *tg) { }
|
||||
@@ -12721,7 +12635,7 @@ static unsigned int get_rr_interval_fair(struct rq *rq, struct task_struct *task
|
||||
@@ -12721,7 +12647,7 @@ static unsigned int get_rr_interval_fair(struct rq *rq, struct task_struct *task
|
||||
* idle runqueue:
|
||||
*/
|
||||
if (rq->cfs.load.weight)
|
||||
@ -2056,10 +2075,10 @@ index 2c335df30171..461409c0eac7 100644
|
||||
return rr_interval;
|
||||
}
|
||||
diff --git a/kernel/sched/features.h b/kernel/sched/features.h
|
||||
index ee7f23c76bd3..54334ca5c5c6 100644
|
||||
index ee7f23c76bd33..546d212ef40d8 100644
|
||||
--- a/kernel/sched/features.h
|
||||
+++ b/kernel/sched/features.h
|
||||
@@ -1,16 +1,11 @@
|
||||
@@ -1,16 +1,12 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
-/*
|
||||
- * Only give sleepers 50% of their service deficit. This allows
|
||||
@ -2077,10 +2096,11 @@ index ee7f23c76bd3..54334ca5c5c6 100644
|
||||
-SCHED_FEAT(START_DEBIT, true)
|
||||
+SCHED_FEAT(PLACE_LAG, true)
|
||||
+SCHED_FEAT(PLACE_DEADLINE_INITIAL, true)
|
||||
+SCHED_FEAT(RUN_TO_PARITY, true)
|
||||
|
||||
/*
|
||||
* Prefer to schedule the task we woke last (assuming it failed
|
||||
@@ -19,13 +14,6 @@ SCHED_FEAT(START_DEBIT, true)
|
||||
@@ -19,13 +15,6 @@ SCHED_FEAT(START_DEBIT, true)
|
||||
*/
|
||||
SCHED_FEAT(NEXT_BUDDY, false)
|
||||
|
||||
@ -2094,7 +2114,7 @@ index ee7f23c76bd3..54334ca5c5c6 100644
|
||||
/*
|
||||
* Consider buddies to be cache hot, decreases the likeliness of a
|
||||
* cache buddy being migrated away, increases cache locality.
|
||||
@@ -98,6 +86,3 @@ SCHED_FEAT(UTIL_EST, true)
|
||||
@@ -98,6 +87,3 @@ SCHED_FEAT(UTIL_EST, true)
|
||||
SCHED_FEAT(UTIL_EST_FASTUP, true)
|
||||
|
||||
SCHED_FEAT(LATENCY_WARN, false)
|
||||
@ -2102,7 +2122,7 @@ index ee7f23c76bd3..54334ca5c5c6 100644
|
||||
-SCHED_FEAT(ALT_PERIOD, true)
|
||||
-SCHED_FEAT(BASE_SLICE, true)
|
||||
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
|
||||
index e93e006a942b..67cd7e1fd501 100644
|
||||
index e93e006a942b9..67cd7e1fd5016 100644
|
||||
--- a/kernel/sched/sched.h
|
||||
+++ b/kernel/sched/sched.h
|
||||
@@ -372,6 +372,8 @@ struct task_group {
|
||||
@ -2182,7 +2202,7 @@ index e93e006a942b..67cd7e1fd501 100644
|
||||
+
|
||||
#endif /* _KERNEL_SCHED_SCHED_H */
|
||||
diff --git a/tools/include/uapi/linux/sched.h b/tools/include/uapi/linux/sched.h
|
||||
index 3bac0a8ceab2..b2e932c25be6 100644
|
||||
index 3bac0a8ceab26..b2e932c25be62 100644
|
||||
--- a/tools/include/uapi/linux/sched.h
|
||||
+++ b/tools/include/uapi/linux/sched.h
|
||||
@@ -132,6 +132,7 @@ struct clone_args {
|
||||
|
@ -1,51 +1,48 @@
|
||||
From 377657f92d256b364813e3f8b2a58edfc9833815 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jung <admin@ptr1337.dev>
|
||||
Date: Sun, 30 Jul 2023 09:43:51 +0200
|
||||
From f353b9eb23586e55b99a6bfe7da9563be5fcca29 Mon Sep 17 00:00:00 2001
|
||||
From: Piotr Gorski <lucjan.lucjanov@gmail.com>
|
||||
Date: Sat, 12 Aug 2023 21:05:20 +0200
|
||||
Subject: [PATCH] bore-eevdf
|
||||
|
||||
Signed-off-by: Peter Jung <admin@ptr1337.dev>
|
||||
Signed-off-by: Piotr Gorski <lucjan.lucjanov@gmail.com>
|
||||
---
|
||||
include/linux/sched.h | 30 ++++++
|
||||
init/Kconfig | 20 ++++
|
||||
kernel/sched/core.c | 118 +++++++++++++++++++++
|
||||
kernel/sched/debug.c | 4 +
|
||||
kernel/sched/fair.c | 228 ++++++++++++++++++++++++++++++++++++++--
|
||||
kernel/sched/features.h | 4 +
|
||||
kernel/sched/sched.h | 1 +
|
||||
7 files changed, 397 insertions(+), 8 deletions(-)
|
||||
include/linux/sched.h | 29 ++++++
|
||||
init/Kconfig | 20 ++++
|
||||
kernel/sched/core.c | 122 +++++++++++++++++++++++
|
||||
kernel/sched/debug.c | 4 +
|
||||
kernel/sched/fair.c | 219 +++++++++++++++++++++++++++++++++++++++---
|
||||
kernel/sched/sched.h | 1 +
|
||||
6 files changed, 384 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/include/linux/sched.h b/include/linux/sched.h
|
||||
index c940c4dc8304..8663c0813f81 100644
|
||||
index c940c4dc8..984931de0 100644
|
||||
--- a/include/linux/sched.h
|
||||
+++ b/include/linux/sched.h
|
||||
@@ -545,6 +545,26 @@ struct sched_statistics {
|
||||
@@ -545,6 +545,24 @@ struct sched_statistics {
|
||||
#endif /* CONFIG_SCHEDSTATS */
|
||||
} ____cacheline_aligned;
|
||||
|
||||
+#ifdef CONFIG_SCHED_BORE
|
||||
+union union16 {
|
||||
+typedef union {
|
||||
+ u16 u16;
|
||||
+ s16 s16;
|
||||
+ u8 u8[2];
|
||||
+ s8 s8[2];
|
||||
+};
|
||||
+typedef union union16 x16;
|
||||
+} x16;
|
||||
+
|
||||
+union union32 {
|
||||
+typedef union {
|
||||
+ u32 u32;
|
||||
+ s32 s32;
|
||||
+ u16 u16[2];
|
||||
+ s16 s16[2];
|
||||
+ u8 u8[4];
|
||||
+ s8 s8[4];
|
||||
+};
|
||||
+typedef union union32 x32;
|
||||
+} x32;
|
||||
+#endif // CONFIG_SCHED_BORE
|
||||
+
|
||||
struct sched_entity {
|
||||
/* For load-balancing: */
|
||||
struct load_weight load;
|
||||
@@ -559,6 +579,12 @@ struct sched_entity {
|
||||
@@ -559,6 +577,12 @@ struct sched_entity {
|
||||
u64 sum_exec_runtime;
|
||||
u64 prev_sum_exec_runtime;
|
||||
u64 vruntime;
|
||||
@ -58,19 +55,20 @@ index c940c4dc8304..8663c0813f81 100644
|
||||
s64 vlag;
|
||||
u64 slice;
|
||||
|
||||
@@ -990,6 +1016,10 @@ struct task_struct {
|
||||
@@ -990,6 +1014,11 @@ struct task_struct {
|
||||
struct list_head children;
|
||||
struct list_head sibling;
|
||||
struct task_struct *group_leader;
|
||||
+#ifdef CONFIG_SCHED_BORE
|
||||
+ u16 child_burst_cache;
|
||||
+ u16 child_burst_count_cache;
|
||||
+ u64 child_burst_last_cached;
|
||||
+#endif // CONFIG_SCHED_BORE
|
||||
|
||||
/*
|
||||
* 'ptraced' is the list of tasks this task is using ptrace() on.
|
||||
diff --git a/init/Kconfig b/init/Kconfig
|
||||
index 71755cc8ed3e..c697be79e594 100644
|
||||
index 71755cc8e..c697be79e 100644
|
||||
--- a/init/Kconfig
|
||||
+++ b/init/Kconfig
|
||||
@@ -1277,6 +1277,26 @@ config CHECKPOINT_RESTORE
|
||||
@ -101,19 +99,21 @@ index 71755cc8ed3e..c697be79e594 100644
|
||||
bool "Automatic process group scheduling"
|
||||
select CGROUPS
|
||||
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
|
||||
index aff81e12460e..839605620f63 100644
|
||||
index aff81e124..a4eba9e47 100644
|
||||
--- a/kernel/sched/core.c
|
||||
+++ b/kernel/sched/core.c
|
||||
@@ -4491,6 +4491,113 @@ int wake_up_state(struct task_struct *p, unsigned int state)
|
||||
@@ -4491,6 +4491,117 @@ int wake_up_state(struct task_struct *p, unsigned int state)
|
||||
return try_to_wake_up(p, state, 0);
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_SCHED_BORE
|
||||
+extern unsigned int sched_burst_cache_lifetime;
|
||||
+extern unsigned int sched_bore;
|
||||
+extern unsigned int sched_burst_fork_atavistic;
|
||||
+
|
||||
+void __init sched_init_bore(void) {
|
||||
+ init_task.child_burst_cache = 0;
|
||||
+ init_task.child_burst_count_cache = 0;
|
||||
+ init_task.child_burst_last_cached = 0;
|
||||
+ init_task.se.burst_time = 0;
|
||||
+ init_task.se.prev_burst_penalty = 0;
|
||||
@ -123,6 +123,7 @@ index aff81e12460e..839605620f63 100644
|
||||
+
|
||||
+void inline sched_fork_bore(struct task_struct *p) {
|
||||
+ p->child_burst_cache = 0;
|
||||
+ p->child_burst_count_cache = 0;
|
||||
+ p->child_burst_last_cached = 0;
|
||||
+ p->se.burst_time = 0;
|
||||
+ p->se.curr_burst_penalty = 0;
|
||||
@ -144,6 +145,7 @@ index aff81e12460e..839605620f63 100644
|
||||
+ u16 avg = 0;
|
||||
+ if (cnt) avg = DIV_ROUND_CLOSEST(sum, cnt);
|
||||
+ p->child_burst_cache = max(avg, p->se.burst_penalty);
|
||||
+ p->child_burst_count_cache = cnt;
|
||||
+ p->child_burst_last_cached = now;
|
||||
+}
|
||||
+
|
||||
@ -178,8 +180,8 @@ index aff81e12460e..839605620f63 100644
|
||||
+ if (child_burst_cache_expired(dec, now))
|
||||
+ update_child_burst_cache_atavistic(dec, now, depth - 1, &cnt, &sum);
|
||||
+ else {
|
||||
+ cnt += dcnt;
|
||||
+ sum += (dec->child_burst_cache) * dcnt;
|
||||
+ cnt += dec->child_burst_count_cache;
|
||||
+ sum += (u32)dec->child_burst_cache * dec->child_burst_count_cache;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
@ -198,7 +200,7 @@ index aff81e12460e..839605620f63 100644
|
||||
+
|
||||
+ read_lock(&tasklist_lock);
|
||||
+
|
||||
+ if (sched_burst_fork_atavistic) {
|
||||
+ if (likely(sched_bore) && likely(sched_burst_fork_atavistic)) {
|
||||
+ while ((anc->real_parent != anc) && (count_child_tasks(anc) == 1))
|
||||
+ anc = anc->real_parent;
|
||||
+ if (child_burst_cache_expired(anc, now))
|
||||
@ -218,7 +220,7 @@ index aff81e12460e..839605620f63 100644
|
||||
/*
|
||||
* Perform scheduler related setup for a newly forked process p.
|
||||
* p is forked by current.
|
||||
@@ -4507,6 +4614,9 @@ static void __sched_fork(unsigned long clone_flags, struct task_struct *p)
|
||||
@@ -4507,6 +4618,9 @@ static void __sched_fork(unsigned long clone_flags, struct task_struct *p)
|
||||
p->se.prev_sum_exec_runtime = 0;
|
||||
p->se.nr_migrations = 0;
|
||||
p->se.vruntime = 0;
|
||||
@ -228,7 +230,7 @@ index aff81e12460e..839605620f63 100644
|
||||
p->se.vlag = 0;
|
||||
INIT_LIST_HEAD(&p->se.group_node);
|
||||
|
||||
@@ -4828,6 +4938,9 @@ void sched_cgroup_fork(struct task_struct *p, struct kernel_clone_args *kargs)
|
||||
@@ -4828,6 +4942,9 @@ void sched_cgroup_fork(struct task_struct *p, struct kernel_clone_args *kargs)
|
||||
|
||||
void sched_post_fork(struct task_struct *p)
|
||||
{
|
||||
@ -238,20 +240,20 @@ index aff81e12460e..839605620f63 100644
|
||||
uclamp_post_fork(p);
|
||||
}
|
||||
|
||||
@@ -9954,6 +10067,11 @@ void __init sched_init(void)
|
||||
@@ -9954,6 +10071,11 @@ void __init sched_init(void)
|
||||
BUG_ON(&dl_sched_class != &stop_sched_class + 1);
|
||||
#endif
|
||||
|
||||
+#ifdef CONFIG_SCHED_BORE
|
||||
+ sched_init_bore();
|
||||
+ printk(KERN_INFO "BORE (Burst-Oriented Response Enhancer) CPU Scheduler modification 3.0 Beta2 by Masahito Suzuki");
|
||||
+ printk(KERN_INFO "BORE (Burst-Oriented Response Enhancer) CPU Scheduler modification 3.1.2 by Masahito Suzuki");
|
||||
+#endif // CONFIG_SCHED_BORE
|
||||
+
|
||||
wait_bit_init();
|
||||
|
||||
#ifdef CONFIG_FAIR_GROUP_SCHED
|
||||
diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
|
||||
index e7e83181fbb6..ff41a524c1ee 100644
|
||||
index e7e83181f..ff41a524c 100644
|
||||
--- a/kernel/sched/debug.c
|
||||
+++ b/kernel/sched/debug.c
|
||||
@@ -348,6 +348,7 @@ static __init int sched_init_debug(void)
|
||||
@ -273,7 +275,7 @@ index e7e83181fbb6..ff41a524c1ee 100644
|
||||
SEQ_printf(m, " %d %d", task_node(p), task_numa_group_id(p));
|
||||
#endif
|
||||
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
|
||||
index 461409c0eac7..90ce27fb0a3f 100644
|
||||
index 461409c0e..1293fe037 100644
|
||||
--- a/kernel/sched/fair.c
|
||||
+++ b/kernel/sched/fair.c
|
||||
@@ -19,6 +19,9 @@
|
||||
@ -309,7 +311,7 @@ index 461409c0eac7..90ce27fb0a3f 100644
|
||||
|
||||
/*
|
||||
* After fork, child runs first. If set to 0 (default) then
|
||||
@@ -84,8 +87,93 @@ static unsigned int normalized_sysctl_sched_base_slice = 750000ULL;
|
||||
@@ -84,8 +87,85 @@ static unsigned int normalized_sysctl_sched_base_slice = 750000ULL;
|
||||
*/
|
||||
unsigned int sysctl_sched_child_runs_first __read_mostly;
|
||||
|
||||
@ -330,8 +332,8 @@ index 461409c0eac7..90ce27fb0a3f 100644
|
||||
+#ifdef CONFIG_SCHED_BORE
|
||||
+unsigned int __read_mostly sched_bore = 1;
|
||||
+unsigned int __read_mostly sched_burst_cache_lifetime = 60000000;
|
||||
+unsigned int __read_mostly sched_burst_penalty_offset = 18;
|
||||
+unsigned int __read_mostly sched_burst_penalty_scale = 1292;
|
||||
+unsigned int __read_mostly sched_burst_penalty_offset = 22;
|
||||
+unsigned int __read_mostly sched_burst_penalty_scale = 1366;
|
||||
+unsigned int __read_mostly sched_burst_smoothness_up = 1;
|
||||
+unsigned int __read_mostly sched_burst_smoothness_down = 0;
|
||||
+unsigned int __read_mostly sched_burst_fork_atavistic = 2;
|
||||
@ -339,27 +341,22 @@ index 461409c0eac7..90ce27fb0a3f 100644
|
||||
+static int sixty_four = 64;
|
||||
+static int maxval_12_bits = 4095;
|
||||
+
|
||||
+#define MAX_BURST_PENALTY ((u32)(40UL << 8) - 1)
|
||||
+#define MAX_BURST_PENALTY ((40U << 8) - 1)
|
||||
+
|
||||
+static inline u32 log2plus1_u64_u32f8(u64 v) {
|
||||
+ x32 result;
|
||||
+ int msb = fls64(v);
|
||||
+ result.u8[0] = v << (64 - msb) >> 55;
|
||||
+ int excess_bits = msb - 9;
|
||||
+ result.u8[0] = (0 <= excess_bits)? v >> excess_bits: v << -excess_bits;
|
||||
+ result.u8[1] = msb;
|
||||
+ return result.u32;
|
||||
+}
|
||||
+
|
||||
+static inline u32 u8h_u32(u8 v) {
|
||||
+ x32 result;
|
||||
+ result.u8[1] = v;
|
||||
+ return result.u32;
|
||||
+}
|
||||
+
|
||||
+static inline u32 calc_burst_penalty(struct sched_entity *se) {
|
||||
+static inline u32 calc_burst_penalty(u64 burst_time) {
|
||||
+ u32 greed, tolerance, penalty, scaled_penalty;
|
||||
+
|
||||
+ greed = log2plus1_u64_u32f8(se->burst_time);
|
||||
+ tolerance = u8h_u32(sched_burst_penalty_offset);
|
||||
+ greed = log2plus1_u64_u32f8(burst_time);
|
||||
+ tolerance = sched_burst_penalty_offset << 8;
|
||||
+ penalty = max(0, (s32)greed - (s32)tolerance);
|
||||
+ scaled_penalty = penalty * sched_burst_penalty_scale >> 10;
|
||||
+
|
||||
@ -367,19 +364,21 @@ index 461409c0eac7..90ce27fb0a3f 100644
|
||||
+}
|
||||
+
|
||||
+static void update_burst_penalty(struct sched_entity *se) {
|
||||
+ se->curr_burst_penalty = calc_burst_penalty(se);
|
||||
+ se->curr_burst_penalty = calc_burst_penalty(se->burst_time);
|
||||
+ se->burst_penalty = max(se->prev_burst_penalty, se->curr_burst_penalty);
|
||||
+}
|
||||
+
|
||||
+static inline u64 penalty_scale(u64 delta, struct sched_entity *se) {
|
||||
+ u8 score = ((x16*)&se->burst_penalty)->u8[1];
|
||||
+static inline u64 penalty_scale(u64 delta, struct sched_entity *se, bool half) {
|
||||
+ u32 score = ((x16*)&se->burst_penalty)->u8[1];
|
||||
+ if (half) score >>= 1;
|
||||
+ return mul_u64_u32_shr(delta, sched_prio_to_wmult[score], 22);
|
||||
+}
|
||||
+
|
||||
+static inline u32 binary_smooth(u32 new, u32 old) {
|
||||
+ return (new >= old)?
|
||||
+ old + ((new - old) >> sched_burst_smoothness_up):
|
||||
+ old - ((old - new) >> sched_burst_smoothness_down);
|
||||
+ int increment = new - old;
|
||||
+ return (0 <= increment)?
|
||||
+ old + ( increment >> sched_burst_smoothness_up):
|
||||
+ old - (-increment >> sched_burst_smoothness_down);
|
||||
+}
|
||||
+
|
||||
+static void restart_burst(struct sched_entity *se) {
|
||||
@ -389,21 +388,16 @@ index 461409c0eac7..90ce27fb0a3f 100644
|
||||
+ se->burst_time = 0;
|
||||
+}
|
||||
+
|
||||
+#define calc_delta_fair(delta, se) __calc_delta_fair(delta, se, true)
|
||||
+#define calc_delta_fair_unscaled(delta, se) __calc_delta_fair(delta, se, false)
|
||||
+static inline u64
|
||||
+__calc_delta_fair(u64 delta, struct sched_entity *se, bool bscale);
|
||||
+
|
||||
+static s64 wakeup_preempt_backstep_delta(u64 rtime, struct sched_entity *se) {
|
||||
+ u64 delta = calc_delta_fair_unscaled(rtime, se);
|
||||
+ return delta - penalty_scale(delta, se);
|
||||
+static inline void vruntime_backstep(s64 *vdiff, struct sched_entity *se) {
|
||||
+ u64 delta_exec = se->sum_exec_runtime - se->prev_sum_exec_runtime;
|
||||
+ *vdiff += delta_exec - penalty_scale(delta_exec, se, false);
|
||||
+}
|
||||
+#endif // CONFIG_SCHED_BORE
|
||||
+
|
||||
int sched_thermal_decay_shift;
|
||||
static int __init setup_sched_thermal_decay_shift(char *str)
|
||||
{
|
||||
@@ -145,6 +233,69 @@ static unsigned int sysctl_numa_balancing_promote_rate_limit = 65536;
|
||||
@@ -145,6 +225,69 @@ static unsigned int sysctl_numa_balancing_promote_rate_limit = 65536;
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
static struct ctl_table sched_fair_sysctls[] = {
|
||||
@ -473,7 +467,7 @@ index 461409c0eac7..90ce27fb0a3f 100644
|
||||
{
|
||||
.procname = "sched_child_runs_first",
|
||||
.data = &sysctl_sched_child_runs_first,
|
||||
@@ -238,6 +389,7 @@ static void update_sysctl(void)
|
||||
@@ -238,6 +381,7 @@ static void update_sysctl(void)
|
||||
#define SET_SYSCTL(name) \
|
||||
(sysctl_##name = (factor) * normalized_sysctl_##name)
|
||||
SET_SYSCTL(sched_base_slice);
|
||||
@ -481,13 +475,14 @@ index 461409c0eac7..90ce27fb0a3f 100644
|
||||
#undef SET_SYSCTL
|
||||
}
|
||||
|
||||
@@ -308,11 +460,19 @@ static u64 __calc_delta(u64 delta_exec, unsigned long weight, struct load_weight
|
||||
@@ -308,11 +452,20 @@ static u64 __calc_delta(u64 delta_exec, unsigned long weight, struct load_weight
|
||||
/*
|
||||
* delta /= w
|
||||
*/
|
||||
+#ifdef CONFIG_SCHED_BORE
|
||||
+static inline u64
|
||||
+__calc_delta_fair(u64 delta, struct sched_entity *se, bool bscale)
|
||||
+#define calc_delta_fair_half(delta, se) __calc_delta_fair(delta, se, true)
|
||||
+#define calc_delta_fair(delta, se) __calc_delta_fair(delta, se, false)
|
||||
+static inline u64 __calc_delta_fair(u64 delta, struct sched_entity *se, bool half)
|
||||
+#else // CONFIG_SCHED_BORE
|
||||
static inline u64 calc_delta_fair(u64 delta, struct sched_entity *se)
|
||||
+#endif // CONFIG_SCHED_BORE
|
||||
@ -496,24 +491,12 @@ index 461409c0eac7..90ce27fb0a3f 100644
|
||||
delta = __calc_delta(delta, NICE_0_LOAD, &se->load);
|
||||
|
||||
+#ifdef CONFIG_SCHED_BORE
|
||||
+ if (bscale && likely(sched_bore)) delta = penalty_scale(delta, se);
|
||||
+ if (likely(sched_bore)) delta = penalty_scale(delta, se, half);
|
||||
+#endif // CONFIG_SCHED_BORE
|
||||
return delta;
|
||||
}
|
||||
|
||||
@@ -706,7 +866,11 @@ void update_entity_lag(struct cfs_rq *cfs_rq, struct sched_entity *se)
|
||||
SCHED_WARN_ON(!se->on_rq);
|
||||
lag = avg_vruntime(cfs_rq) - se->vruntime;
|
||||
|
||||
+#ifdef CONFIG_SCHED_BORE
|
||||
+ limit = calc_delta_fair_unscaled(max_t(u64, 2*se->slice, TICK_NSEC), se);
|
||||
+#else // CONFIG_SCHED_BORE
|
||||
limit = calc_delta_fair(max_t(u64, 2*se->slice, TICK_NSEC), se);
|
||||
+#endif // CONFIG_SCHED_BORE
|
||||
se->vlag = clamp(lag, -limit, limit);
|
||||
}
|
||||
|
||||
@@ -944,6 +1108,7 @@ int sched_update_scaling(void)
|
||||
@@ -944,6 +1097,7 @@ int sched_update_scaling(void)
|
||||
#define WRT_SYSCTL(name) \
|
||||
(normalized_sysctl_##name = sysctl_##name / (factor))
|
||||
WRT_SYSCTL(sched_base_slice);
|
||||
@ -521,18 +504,29 @@ index 461409c0eac7..90ce27fb0a3f 100644
|
||||
#undef WRT_SYSCTL
|
||||
|
||||
return 0;
|
||||
@@ -1121,6 +1286,10 @@ static void update_curr(struct cfs_rq *cfs_rq)
|
||||
@@ -1121,7 +1275,11 @@ static void update_curr(struct cfs_rq *cfs_rq)
|
||||
curr->sum_exec_runtime += delta_exec;
|
||||
schedstat_add(cfs_rq->exec_clock, delta_exec);
|
||||
|
||||
- curr->vruntime += calc_delta_fair(delta_exec, curr);
|
||||
+#ifdef CONFIG_SCHED_BORE
|
||||
+ curr->burst_time += delta_exec;
|
||||
+ update_burst_penalty(curr);
|
||||
+#endif // CONFIG_SCHED_BORE
|
||||
curr->vruntime += calc_delta_fair(delta_exec, curr);
|
||||
+ curr->vruntime += max(1ULL, calc_delta_fair(delta_exec, curr));
|
||||
update_deadline(cfs_rq, curr);
|
||||
update_min_vruntime(cfs_rq);
|
||||
@@ -5187,6 +5356,9 @@ set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
|
||||
|
||||
@@ -4919,7 +5077,7 @@ static inline void update_misfit_status(struct task_struct *p, struct rq *rq) {}
|
||||
static void
|
||||
place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
|
||||
{
|
||||
- u64 vslice = calc_delta_fair(se->slice, se);
|
||||
+ u64 vslice = calc_delta_fair_half(se->slice, se);
|
||||
u64 vruntime = avg_vruntime(cfs_rq);
|
||||
s64 lag = 0;
|
||||
|
||||
@@ -5187,6 +5345,9 @@ set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
|
||||
se->prev_sum_exec_runtime = se->sum_exec_runtime;
|
||||
}
|
||||
|
||||
@ -542,7 +536,7 @@ index 461409c0eac7..90ce27fb0a3f 100644
|
||||
/*
|
||||
* Pick the next process, keeping these things in mind, in this order:
|
||||
* 1) keep things fair between processes/task groups
|
||||
@@ -5197,14 +5369,16 @@ set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
|
||||
@@ -5197,14 +5358,16 @@ set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
|
||||
static struct sched_entity *
|
||||
pick_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *curr)
|
||||
{
|
||||
@ -561,18 +555,14 @@ index 461409c0eac7..90ce27fb0a3f 100644
|
||||
}
|
||||
|
||||
static bool check_cfs_rq_runtime(struct cfs_rq *cfs_rq);
|
||||
@@ -6452,6 +6626,38 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags)
|
||||
@@ -6452,6 +6615,30 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags)
|
||||
hrtick_update(rq);
|
||||
}
|
||||
|
||||
+static unsigned long wakeup_gran(struct sched_entity *se)
|
||||
+{
|
||||
+ unsigned long gran = sysctl_sched_wakeup_granularity;
|
||||
+#ifdef CONFIG_SCHED_BORE
|
||||
+ return calc_delta_fair_unscaled(gran, se);
|
||||
+#else // CONFIG_SCHED_BORE
|
||||
+ return calc_delta_fair(gran, se);
|
||||
+#endif // CONFIG_SCHED_BORE
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
@ -580,11 +570,7 @@ index 461409c0eac7..90ce27fb0a3f 100644
|
||||
+{
|
||||
+ s64 gran, vdiff = curr->vruntime - se->vruntime;
|
||||
+#ifdef CONFIG_SCHED_BORE
|
||||
+ if (likely(sched_bore)) {
|
||||
+ u64 rtime = curr->sum_exec_runtime - curr->prev_sum_exec_runtime;
|
||||
+ vdiff += wakeup_preempt_backstep_delta(rtime, curr)
|
||||
+ - wakeup_preempt_backstep_delta(rtime, se);
|
||||
+ }
|
||||
+ if (likely(sched_bore)) vruntime_backstep(&vdiff, curr);
|
||||
+#endif // CONFIG_SCHED_BORE
|
||||
+
|
||||
+ if (vdiff <= 0)
|
||||
@ -600,7 +586,7 @@ index 461409c0eac7..90ce27fb0a3f 100644
|
||||
static void set_next_buddy(struct sched_entity *se);
|
||||
|
||||
/*
|
||||
@@ -6470,6 +6676,9 @@ static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int flags)
|
||||
@@ -6470,6 +6657,9 @@ static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int flags)
|
||||
util_est_dequeue(&rq->cfs, p);
|
||||
|
||||
for_each_sched_entity(se) {
|
||||
@ -610,7 +596,7 @@ index 461409c0eac7..90ce27fb0a3f 100644
|
||||
cfs_rq = cfs_rq_of(se);
|
||||
dequeue_entity(cfs_rq, se, flags);
|
||||
|
||||
@@ -7980,7 +8189,7 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_
|
||||
@@ -7980,7 +8170,7 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_
|
||||
/*
|
||||
* XXX pick_eevdf(cfs_rq) != se ?
|
||||
*/
|
||||
@ -619,34 +605,32 @@ index 461409c0eac7..90ce27fb0a3f 100644
|
||||
goto preempt;
|
||||
|
||||
return;
|
||||
@@ -8193,6 +8402,9 @@ static void yield_task_fair(struct rq *rq)
|
||||
struct task_struct *curr = rq->curr;
|
||||
struct cfs_rq *cfs_rq = task_cfs_rq(curr);
|
||||
struct sched_entity *se = &curr->se;
|
||||
@@ -8197,8 +8387,12 @@ static void yield_task_fair(struct rq *rq)
|
||||
/*
|
||||
* Are we the only task in the tree?
|
||||
*/
|
||||
- if (unlikely(rq->nr_running == 1))
|
||||
+ if (unlikely(rq->nr_running == 1)) {
|
||||
+#ifdef CONFIG_SCHED_BORE
|
||||
+ restart_burst(se);
|
||||
+#endif // CONFIG_SCHED_BORE
|
||||
return;
|
||||
+ }
|
||||
|
||||
clear_buddies(cfs_rq, se);
|
||||
|
||||
@@ -8207,6 +8401,9 @@ static void yield_task_fair(struct rq *rq)
|
||||
* Update run-time statistics of the 'current'.
|
||||
*/
|
||||
update_curr(cfs_rq);
|
||||
+#ifdef CONFIG_SCHED_BORE
|
||||
+ restart_burst(se);
|
||||
+#endif // CONFIG_SCHED_BORE
|
||||
|
||||
/*
|
||||
* Are we the only task in the tree?
|
||||
diff --git a/kernel/sched/features.h b/kernel/sched/features.h
|
||||
index 54334ca5c5c6..416ec4bcdb0f 100644
|
||||
--- a/kernel/sched/features.h
|
||||
+++ b/kernel/sched/features.h
|
||||
@@ -12,7 +12,11 @@ SCHED_FEAT(PLACE_DEADLINE_INITIAL, true)
|
||||
* wakeup-preemption), since its likely going to consume data we
|
||||
* touched, increases cache locality.
|
||||
*/
|
||||
+#ifdef CONFIG_SCHED_BORE
|
||||
+SCHED_FEAT(NEXT_BUDDY, true)
|
||||
+#else // CONFIG_SCHED_BORE
|
||||
SCHED_FEAT(NEXT_BUDDY, false)
|
||||
+#endif // CONFIG_SCHED_BORE
|
||||
|
||||
/*
|
||||
* Consider buddies to be cache hot, decreases the likeliness of a
|
||||
* Tell update_rq_clock() that we've just updated,
|
||||
* so we don't do microscopic update in schedule()
|
||||
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
|
||||
index 67cd7e1fd501..04d065015d6c 100644
|
||||
index 67cd7e1fd..04d065015 100644
|
||||
--- a/kernel/sched/sched.h
|
||||
+++ b/kernel/sched/sched.h
|
||||
@@ -2506,6 +2506,7 @@ extern const_debug unsigned int sysctl_sched_nr_migrate;
|
||||
@ -658,4 +642,4 @@ index 67cd7e1fd501..04d065015d6c 100644
|
||||
#ifdef CONFIG_SCHED_DEBUG
|
||||
extern int sysctl_resched_latency_warn_ms;
|
||||
--
|
||||
2.41.0
|
||||
2.42.0.rc0.25.ga82fb66fed
|
||||
|
@ -1,573 +0,0 @@
|
||||
From ab6268d199fa749e274a48b00c443538ae492b16 Mon Sep 17 00:00:00 2001
|
||||
From: Piotr Gorski <lucjan.lucjanov@gmail.com>
|
||||
Date: Wed, 9 Aug 2023 14:07:31 +0200
|
||||
Subject: [PATCH] amd-6.5: merge changes from dev tree
|
||||
|
||||
Signed-off-by: Piotr Gorski <lucjan.lucjanov@gmail.com>
|
||||
---
|
||||
.../admin-guide/kernel-parameters.txt | 5 +
|
||||
Documentation/admin-guide/pm/amd-pstate.rst | 55 +++++
|
||||
drivers/acpi/cppc_acpi.c | 13 ++
|
||||
drivers/acpi/processor_driver.c | 6 +
|
||||
drivers/cpufreq/amd-pstate.c | 191 ++++++++++++++++--
|
||||
drivers/cpufreq/cpufreq.c | 13 ++
|
||||
include/acpi/cppc_acpi.h | 5 +
|
||||
include/linux/amd-pstate.h | 1 +
|
||||
include/linux/cpufreq.h | 4 +
|
||||
9 files changed, 272 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
|
||||
index a1457995f..1f53c395a 100644
|
||||
--- a/Documentation/admin-guide/kernel-parameters.txt
|
||||
+++ b/Documentation/admin-guide/kernel-parameters.txt
|
||||
@@ -363,6 +363,11 @@
|
||||
selects a performance level in this range and appropriate
|
||||
to the current workload.
|
||||
|
||||
+ amd_prefcore=
|
||||
+ [X86]
|
||||
+ enable
|
||||
+ Enable AMD Pstate Preferred Core.
|
||||
+
|
||||
amijoy.map= [HW,JOY] Amiga joystick support
|
||||
Map of devices attached to JOY0DAT and JOY1DAT
|
||||
Format: <a>,<b>
|
||||
diff --git a/Documentation/admin-guide/pm/amd-pstate.rst b/Documentation/admin-guide/pm/amd-pstate.rst
|
||||
index 1cf40f692..4a30cf235 100644
|
||||
--- a/Documentation/admin-guide/pm/amd-pstate.rst
|
||||
+++ b/Documentation/admin-guide/pm/amd-pstate.rst
|
||||
@@ -353,6 +353,49 @@ is activated. In this mode, driver requests minimum and maximum performance
|
||||
level and the platform autonomously selects a performance level in this range
|
||||
and appropriate to the current workload.
|
||||
|
||||
+AMD Pstate Preferred Core
|
||||
+=================================
|
||||
+
|
||||
+The core frequency is subjected to the process variation in semiconductors.
|
||||
+Not all cores are able to reach the maximum frequency respecting the
|
||||
+infrastructure limits. Consequently, AMD has redefined the concept of
|
||||
+maximum frequency of a part. This means that a fraction of cores can reach
|
||||
+maximum frequency. To find the best process scheduling policy for a given
|
||||
+scenario, OS needs to know the core ordering informed by the platform through
|
||||
+highest performance capability register of the CPPC interface.
|
||||
+
|
||||
+``AMD Pstate Preferred Core`` use ITMT arch provides functions and data structures
|
||||
+for enabling the scheduler to favor scheduling on cores can be get a higher frequency
|
||||
+with lower voltage under preferred core. And it has the ability to dynamically
|
||||
+change the preferred core based on the workload and platform conditions and
|
||||
+accounting for thermals and aging.
|
||||
+
|
||||
+The priority metric will be initialized by the AMD Pstate driver. The AMD Pstate
|
||||
+driver will also determine whether or not ``AMD Pstate Preferred Core`` is
|
||||
+supported by the platform.
|
||||
+
|
||||
+AMD Pstate driver will provide an initial core ordering when the system boots.
|
||||
+The platform uses the CPPC interfaces to communicate the core ranking to the
|
||||
+operating system and scheduler to make sure that OS is choosing the cores
|
||||
+with highest performance firstly for scheduling the process. When AMD Pstate
|
||||
+driver receives a message with the highest performance change, it will
|
||||
+update the core ranking and set the cpu's priority.
|
||||
+
|
||||
+AMD Preferred Core Switch
|
||||
+=================================
|
||||
+Kernel Parameters
|
||||
+-----------------
|
||||
+
|
||||
+``AMD Pstate Preferred Core`` has two states: enable and disable.
|
||||
+Enable/disable states can be chosen by different kernel parameters.
|
||||
+Default disable ``AMD Pstate Preferred Core``.
|
||||
+
|
||||
+``amd_prefcore=enable``
|
||||
+
|
||||
+If ``amd_prefcore=enable`` is passed to kernel command line option
|
||||
+then enable ``AMD Pstate Preferred Core`` if the processor and power
|
||||
+firmware can support preferred core feature.
|
||||
+
|
||||
User Space Interface in ``sysfs`` - General
|
||||
===========================================
|
||||
|
||||
@@ -385,6 +428,18 @@ control its functionality at the system level. They are located in the
|
||||
to the operation mode represented by that string - or to be
|
||||
unregistered in the "disable" case.
|
||||
|
||||
+``prefcore_state``
|
||||
+ Preferred Core state of the driver: "enabled" or "disabled".
|
||||
+
|
||||
+ "enabled"
|
||||
+ Enable the AMD Preferred Core.
|
||||
+
|
||||
+ "disabled"
|
||||
+ Disable the AMD Preferred Core
|
||||
+
|
||||
+
|
||||
+ This attribute is read-only to check the state of Preferred Core.
|
||||
+
|
||||
``cpupower`` tool support for ``amd-pstate``
|
||||
===============================================
|
||||
|
||||
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
|
||||
index 7ff269a78..ad388a0e8 100644
|
||||
--- a/drivers/acpi/cppc_acpi.c
|
||||
+++ b/drivers/acpi/cppc_acpi.c
|
||||
@@ -1154,6 +1154,19 @@ int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf)
|
||||
return cppc_get_perf(cpunum, NOMINAL_PERF, nominal_perf);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * cppc_get_highest_perf - Get the highest performance register value.
|
||||
+ * @cpunum: CPU from which to get highest performance.
|
||||
+ * @highest_perf: Return address.
|
||||
+ *
|
||||
+ * Return: 0 for success, -EIO otherwise.
|
||||
+ */
|
||||
+int cppc_get_highest_perf(int cpunum, u64 *highest_perf)
|
||||
+{
|
||||
+ return cppc_get_perf(cpunum, HIGHEST_PERF, highest_perf);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(cppc_get_highest_perf);
|
||||
+
|
||||
/**
|
||||
* cppc_get_epp_perf - Get the epp register value.
|
||||
* @cpunum: CPU from which to get epp preference value.
|
||||
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
|
||||
index 4bd16b3f0..29b2fb68a 100644
|
||||
--- a/drivers/acpi/processor_driver.c
|
||||
+++ b/drivers/acpi/processor_driver.c
|
||||
@@ -27,6 +27,7 @@
|
||||
#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
|
||||
#define ACPI_PROCESSOR_NOTIFY_POWER 0x81
|
||||
#define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82
|
||||
+#define ACPI_PROCESSOR_NOTIFY_HIGEST_PERF_CHANGED 0x85
|
||||
|
||||
MODULE_AUTHOR("Paul Diefenbaugh");
|
||||
MODULE_DESCRIPTION("ACPI Processor Driver");
|
||||
@@ -83,6 +84,11 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
|
||||
acpi_bus_generate_netlink_event(device->pnp.device_class,
|
||||
dev_name(&device->dev), event, 0);
|
||||
break;
|
||||
+ case ACPI_PROCESSOR_NOTIFY_HIGEST_PERF_CHANGED:
|
||||
+ cpufreq_update_highest_perf(pr->id);
|
||||
+ acpi_bus_generate_netlink_event(device->pnp.device_class,
|
||||
+ dev_name(&device->dev), event, 0);
|
||||
+ break;
|
||||
default:
|
||||
acpi_handle_debug(handle, "Unsupported event [0x%x]\n", event);
|
||||
break;
|
||||
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
|
||||
index 81fba0dcb..ba10aa971 100644
|
||||
--- a/drivers/cpufreq/amd-pstate.c
|
||||
+++ b/drivers/cpufreq/amd-pstate.c
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/static_call.h>
|
||||
#include <linux/amd-pstate.h>
|
||||
+#include <linux/topology.h>
|
||||
|
||||
#include <acpi/processor.h>
|
||||
#include <acpi/cppc_acpi.h>
|
||||
@@ -49,6 +50,8 @@
|
||||
|
||||
#define AMD_PSTATE_TRANSITION_LATENCY 20000
|
||||
#define AMD_PSTATE_TRANSITION_DELAY 1000
|
||||
+#define AMD_PSTATE_PREFCORE_THRESHOLD 166
|
||||
+#define AMD_PSTATE_MAX_CPPC_PERF 255
|
||||
|
||||
/*
|
||||
* TODO: We need more time to fine tune processors with shared memory solution
|
||||
@@ -65,6 +68,14 @@ static struct cpufreq_driver amd_pstate_epp_driver;
|
||||
static int cppc_state = AMD_PSTATE_UNDEFINED;
|
||||
static bool cppc_enabled;
|
||||
|
||||
+/*
|
||||
+ * CPPC Preferred Core feature is supported by power firmware
|
||||
+ */
|
||||
+static bool prefcore_enabled = false;
|
||||
+
|
||||
+/* Disable AMD Pstate Preferred Core loading */
|
||||
+static bool no_prefcore __read_mostly = true;
|
||||
+
|
||||
/*
|
||||
* AMD Energy Preference Performance (EPP)
|
||||
* The EPP is used in the CCLK DPM controller to drive
|
||||
@@ -290,27 +301,26 @@ static inline int amd_pstate_enable(bool enable)
|
||||
static int pstate_init_perf(struct amd_cpudata *cpudata)
|
||||
{
|
||||
u64 cap1;
|
||||
- u32 highest_perf;
|
||||
|
||||
int ret = rdmsrl_safe_on_cpu(cpudata->cpu, MSR_AMD_CPPC_CAP1,
|
||||
&cap1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- /*
|
||||
- * TODO: Introduce AMD specific power feature.
|
||||
- *
|
||||
- * CPPC entry doesn't indicate the highest performance in some ASICs.
|
||||
+ /* For platforms that do not support the preferred core feature, the
|
||||
+ * highest_pef may be configured with 166 or 255, to avoid max frequency
|
||||
+ * calculated wrongly. we take the AMD_CPPC_HIGHEST_PERF(cap1) value as
|
||||
+ * the default max perf.
|
||||
*/
|
||||
- highest_perf = amd_get_highest_perf();
|
||||
- if (highest_perf > AMD_CPPC_HIGHEST_PERF(cap1))
|
||||
- highest_perf = AMD_CPPC_HIGHEST_PERF(cap1);
|
||||
-
|
||||
- WRITE_ONCE(cpudata->highest_perf, highest_perf);
|
||||
+ if (!prefcore_enabled)
|
||||
+ WRITE_ONCE(cpudata->highest_perf, AMD_CPPC_HIGHEST_PERF(cap1));
|
||||
+ else
|
||||
+ WRITE_ONCE(cpudata->highest_perf, AMD_PSTATE_PREFCORE_THRESHOLD);
|
||||
|
||||
WRITE_ONCE(cpudata->nominal_perf, AMD_CPPC_NOMINAL_PERF(cap1));
|
||||
WRITE_ONCE(cpudata->lowest_nonlinear_perf, AMD_CPPC_LOWNONLIN_PERF(cap1));
|
||||
WRITE_ONCE(cpudata->lowest_perf, AMD_CPPC_LOWEST_PERF(cap1));
|
||||
+ WRITE_ONCE(cpudata->prefcore_highest_perf, AMD_CPPC_HIGHEST_PERF(cap1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -318,22 +328,21 @@ static int pstate_init_perf(struct amd_cpudata *cpudata)
|
||||
static int cppc_init_perf(struct amd_cpudata *cpudata)
|
||||
{
|
||||
struct cppc_perf_caps cppc_perf;
|
||||
- u32 highest_perf;
|
||||
|
||||
int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- highest_perf = amd_get_highest_perf();
|
||||
- if (highest_perf > cppc_perf.highest_perf)
|
||||
- highest_perf = cppc_perf.highest_perf;
|
||||
-
|
||||
- WRITE_ONCE(cpudata->highest_perf, highest_perf);
|
||||
+ if (!prefcore_enabled)
|
||||
+ WRITE_ONCE(cpudata->highest_perf, cppc_perf.highest_perf);
|
||||
+ else
|
||||
+ WRITE_ONCE(cpudata->highest_perf, AMD_PSTATE_PREFCORE_THRESHOLD);
|
||||
|
||||
WRITE_ONCE(cpudata->nominal_perf, cppc_perf.nominal_perf);
|
||||
WRITE_ONCE(cpudata->lowest_nonlinear_perf,
|
||||
cppc_perf.lowest_nonlinear_perf);
|
||||
WRITE_ONCE(cpudata->lowest_perf, cppc_perf.lowest_perf);
|
||||
+ WRITE_ONCE(cpudata->prefcore_highest_perf, cppc_perf.highest_perf);
|
||||
|
||||
if (cppc_state == AMD_PSTATE_ACTIVE)
|
||||
return 0;
|
||||
@@ -676,6 +685,118 @@ static void amd_perf_ctl_reset(unsigned int cpu)
|
||||
wrmsrl_on_cpu(cpu, MSR_AMD_PERF_CTL, 0);
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Set AMD Pstate Preferred Core enable can't be done directly from cpufreq callbacks
|
||||
+ * due to locking, so queue the work for later.
|
||||
+ */
|
||||
+static void amd_pstste_sched_prefcore_workfn(struct work_struct *work)
|
||||
+{
|
||||
+ sched_set_itmt_support();
|
||||
+}
|
||||
+static DECLARE_WORK(sched_prefcore_work, amd_pstste_sched_prefcore_workfn);
|
||||
+
|
||||
+/**
|
||||
+ * Get the highest performance register value.
|
||||
+ * @cpu: CPU from which to get highest performance.
|
||||
+ * @highest_perf: Return address.
|
||||
+ *
|
||||
+ * Return: 0 for success, -EIO otherwise.
|
||||
+ */
|
||||
+static int amd_pstate_get_highest_perf(int cpu, u64 *highest_perf)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ if (boot_cpu_has(X86_FEATURE_CPPC)) {
|
||||
+ u64 cap1;
|
||||
+
|
||||
+ ret = rdmsrl_safe_on_cpu(cpu, MSR_AMD_CPPC_CAP1, &cap1);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ WRITE_ONCE(*highest_perf, AMD_CPPC_HIGHEST_PERF(cap1));
|
||||
+ } else {
|
||||
+ ret = cppc_get_highest_perf(cpu, highest_perf);
|
||||
+ }
|
||||
+
|
||||
+ return (ret);
|
||||
+}
|
||||
+
|
||||
+static void amd_pstate_init_prefcore(void)
|
||||
+{
|
||||
+ int cpu, ret;
|
||||
+ u64 highest_perf;
|
||||
+
|
||||
+ if (no_prefcore)
|
||||
+ return;
|
||||
+
|
||||
+ for_each_possible_cpu(cpu) {
|
||||
+ ret = amd_pstate_get_highest_perf(cpu, &highest_perf);
|
||||
+ if (ret)
|
||||
+ break;
|
||||
+
|
||||
+ sched_set_itmt_core_prio(highest_perf, cpu);
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * This code can be run during CPU online under the
|
||||
+ * CPU hotplug locks, so sched_set_amd_prefcore_support()
|
||||
+ * cannot be called from here. Queue up a work item
|
||||
+ * to invoke it.
|
||||
+ */
|
||||
+ schedule_work(&sched_prefcore_work);
|
||||
+}
|
||||
+
|
||||
+static void amd_pstate_update_highest_perf(unsigned int cpu)
|
||||
+{
|
||||
+ struct cpufreq_policy *policy;
|
||||
+ struct amd_cpudata *cpudata;
|
||||
+ u32 prev_high = 0, cur_high = 0;
|
||||
+ u64 highest_perf;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!prefcore_enabled)
|
||||
+ return;
|
||||
+
|
||||
+ ret = amd_pstate_get_highest_perf(cpu, &highest_perf);
|
||||
+ if (ret)
|
||||
+ return;
|
||||
+
|
||||
+ policy = cpufreq_cpu_get(cpu);
|
||||
+ cpudata = policy->driver_data;
|
||||
+ cur_high = highest_perf;
|
||||
+ prev_high = READ_ONCE(cpudata->prefcore_highest_perf);
|
||||
+
|
||||
+ if (prev_high != cur_high) {
|
||||
+ WRITE_ONCE(cpudata->prefcore_highest_perf, cur_high);
|
||||
+ sched_set_itmt_core_prio(cur_high, cpu);
|
||||
+ }
|
||||
+
|
||||
+ cpufreq_cpu_put(policy);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Check if AMD Pstate Preferred core feature is supported and enabled
|
||||
+ * 1) no_prefcore is used to enable or disable AMD Pstate Preferred Core
|
||||
+ * loading when user would like to enable or disable it. Without that,
|
||||
+ * AMD Pstate Preferred Core will be disabled by default if the processor
|
||||
+ * and power firmware can support preferred core feature.
|
||||
+ * 2) prefcore_enabled is used to indicate whether CPPC preferred core is enabled.
|
||||
+ */
|
||||
+static void check_prefcore_supported(int cpu)
|
||||
+{
|
||||
+ u64 highest_perf;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (no_prefcore)
|
||||
+ return;
|
||||
+
|
||||
+ ret = amd_pstate_get_highest_perf(cpu, &highest_perf);
|
||||
+ if (ret)
|
||||
+ return;
|
||||
+
|
||||
+ if(highest_perf < AMD_PSTATE_MAX_CPPC_PERF)
|
||||
+ prefcore_enabled = true;
|
||||
+}
|
||||
+
|
||||
static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
int min_freq, max_freq, nominal_freq, lowest_nonlinear_freq, ret;
|
||||
@@ -697,6 +818,9 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
|
||||
|
||||
cpudata->cpu = policy->cpu;
|
||||
|
||||
+ /* check if CPPC preferred core feature is enabled*/
|
||||
+ check_prefcore_supported(policy->cpu);
|
||||
+
|
||||
ret = amd_pstate_init_perf(cpudata);
|
||||
if (ret)
|
||||
goto free_cpudata1;
|
||||
@@ -1012,8 +1136,8 @@ static int amd_pstate_update_status(const char *buf, size_t size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static ssize_t show_status(struct kobject *kobj,
|
||||
- struct kobj_attribute *attr, char *buf)
|
||||
+static ssize_t status_show(struct device *dev,
|
||||
+ struct device_attribute *attr, char *buf)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
@@ -1024,7 +1148,7 @@ static ssize_t show_status(struct kobject *kobj,
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static ssize_t store_status(struct kobject *a, struct kobj_attribute *b,
|
||||
+static ssize_t status_store(struct device *a, struct device_attribute *b,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
char *p = memchr(buf, '\n', count);
|
||||
@@ -1037,13 +1161,20 @@ static ssize_t store_status(struct kobject *a, struct kobj_attribute *b,
|
||||
return ret < 0 ? ret : count;
|
||||
}
|
||||
|
||||
+static ssize_t prefcore_state_show(struct device *dev,
|
||||
+ struct device_attribute *attr, char *buf)
|
||||
+{
|
||||
+ return sysfs_emit(buf, "%s\n", prefcore_enabled ? "enabled" : "disabled");
|
||||
+}
|
||||
+
|
||||
cpufreq_freq_attr_ro(amd_pstate_max_freq);
|
||||
cpufreq_freq_attr_ro(amd_pstate_lowest_nonlinear_freq);
|
||||
|
||||
cpufreq_freq_attr_ro(amd_pstate_highest_perf);
|
||||
cpufreq_freq_attr_rw(energy_performance_preference);
|
||||
cpufreq_freq_attr_ro(energy_performance_available_preferences);
|
||||
-define_one_global_rw(status);
|
||||
+static DEVICE_ATTR_RW(status);
|
||||
+static DEVICE_ATTR_RO(prefcore_state);
|
||||
|
||||
static struct freq_attr *amd_pstate_attr[] = {
|
||||
&amd_pstate_max_freq,
|
||||
@@ -1062,7 +1193,8 @@ static struct freq_attr *amd_pstate_epp_attr[] = {
|
||||
};
|
||||
|
||||
static struct attribute *pstate_global_attributes[] = {
|
||||
- &status.attr,
|
||||
+ &dev_attr_status.attr,
|
||||
+ &dev_attr_prefcore_state.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -1114,6 +1246,9 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
|
||||
cpudata->cpu = policy->cpu;
|
||||
cpudata->epp_policy = 0;
|
||||
|
||||
+ /* check if CPPC preferred core feature is supported*/
|
||||
+ check_prefcore_supported(policy->cpu);
|
||||
+
|
||||
ret = amd_pstate_init_perf(cpudata);
|
||||
if (ret)
|
||||
goto free_cpudata1;
|
||||
@@ -1392,6 +1527,7 @@ static struct cpufreq_driver amd_pstate_driver = {
|
||||
.suspend = amd_pstate_cpu_suspend,
|
||||
.resume = amd_pstate_cpu_resume,
|
||||
.set_boost = amd_pstate_set_boost,
|
||||
+ .update_highest_perf = amd_pstate_update_highest_perf,
|
||||
.name = "amd-pstate",
|
||||
.attr = amd_pstate_attr,
|
||||
};
|
||||
@@ -1406,6 +1542,7 @@ static struct cpufreq_driver amd_pstate_epp_driver = {
|
||||
.online = amd_pstate_epp_cpu_online,
|
||||
.suspend = amd_pstate_epp_suspend,
|
||||
.resume = amd_pstate_epp_resume,
|
||||
+ .update_highest_perf = amd_pstate_update_highest_perf,
|
||||
.name = "amd-pstate-epp",
|
||||
.attr = amd_pstate_epp_attr,
|
||||
};
|
||||
@@ -1506,6 +1643,8 @@ static int __init amd_pstate_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
+ amd_pstate_init_prefcore();
|
||||
+
|
||||
return ret;
|
||||
|
||||
global_attr_free:
|
||||
@@ -1527,7 +1666,17 @@ static int __init amd_pstate_param(char *str)
|
||||
|
||||
return amd_pstate_set_driver(mode_idx);
|
||||
}
|
||||
+
|
||||
+static int __init amd_prefcore_param(char *str)
|
||||
+{
|
||||
+ if (!strcmp(str, "enable"))
|
||||
+ no_prefcore = false;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
early_param("amd_pstate", amd_pstate_param);
|
||||
+early_param("amd_prefcore", amd_prefcore_param);
|
||||
|
||||
MODULE_AUTHOR("Huang Rui <ray.huang@amd.com>");
|
||||
MODULE_DESCRIPTION("AMD Processor P-state Frequency Driver");
|
||||
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
|
||||
index 50bbc969f..842357abf 100644
|
||||
--- a/drivers/cpufreq/cpufreq.c
|
||||
+++ b/drivers/cpufreq/cpufreq.c
|
||||
@@ -2675,6 +2675,19 @@ void cpufreq_update_limits(unsigned int cpu)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpufreq_update_limits);
|
||||
|
||||
+/**
|
||||
+ * cpufreq_update_highest_perf - Update highest performance for a given CPU.
|
||||
+ * @cpu: CPU to update the highest performance for.
|
||||
+ *
|
||||
+ * Invoke the driver's ->update_highest_perf callback if present
|
||||
+ */
|
||||
+void cpufreq_update_highest_perf(unsigned int cpu)
|
||||
+{
|
||||
+ if (cpufreq_driver->update_highest_perf)
|
||||
+ cpufreq_driver->update_highest_perf(cpu);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(cpufreq_update_highest_perf);
|
||||
+
|
||||
/*********************************************************************
|
||||
* BOOST *
|
||||
*********************************************************************/
|
||||
diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
|
||||
index 6126c977e..c0b69ffe7 100644
|
||||
--- a/include/acpi/cppc_acpi.h
|
||||
+++ b/include/acpi/cppc_acpi.h
|
||||
@@ -139,6 +139,7 @@ struct cppc_cpudata {
|
||||
#ifdef CONFIG_ACPI_CPPC_LIB
|
||||
extern int cppc_get_desired_perf(int cpunum, u64 *desired_perf);
|
||||
extern int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf);
|
||||
+extern int cppc_get_highest_perf(int cpunum, u64 *highest_perf);
|
||||
extern int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs);
|
||||
extern int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls);
|
||||
extern int cppc_set_enable(int cpu, bool enable);
|
||||
@@ -165,6 +166,10 @@ static inline int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
+static inline int cppc_get_highest_perf(int cpunum, u64 *highest_perf)
|
||||
+{
|
||||
+ return -ENOTSUPP;
|
||||
+}
|
||||
static inline int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
diff --git a/include/linux/amd-pstate.h b/include/linux/amd-pstate.h
|
||||
index 446394f84..fa86bc953 100644
|
||||
--- a/include/linux/amd-pstate.h
|
||||
+++ b/include/linux/amd-pstate.h
|
||||
@@ -70,6 +70,7 @@ struct amd_cpudata {
|
||||
u32 nominal_perf;
|
||||
u32 lowest_nonlinear_perf;
|
||||
u32 lowest_perf;
|
||||
+ u32 prefcore_highest_perf;
|
||||
|
||||
u32 max_freq;
|
||||
u32 min_freq;
|
||||
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
|
||||
index 172ff51c1..766c83a4f 100644
|
||||
--- a/include/linux/cpufreq.h
|
||||
+++ b/include/linux/cpufreq.h
|
||||
@@ -231,6 +231,7 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu);
|
||||
void refresh_frequency_limits(struct cpufreq_policy *policy);
|
||||
void cpufreq_update_policy(unsigned int cpu);
|
||||
void cpufreq_update_limits(unsigned int cpu);
|
||||
+void cpufreq_update_highest_perf(unsigned int cpu);
|
||||
bool have_governor_per_policy(void);
|
||||
bool cpufreq_supports_freq_invariance(void);
|
||||
struct kobject *get_governor_parent_kobj(struct cpufreq_policy *policy);
|
||||
@@ -376,6 +377,9 @@ struct cpufreq_driver {
|
||||
/* Called to update policy limits on firmware notifications. */
|
||||
void (*update_limits)(unsigned int cpu);
|
||||
|
||||
+ /* Called to update highest performance on firmware notifications. */
|
||||
+ void (*update_highest_perf)(unsigned int cpu);
|
||||
+
|
||||
/* optional */
|
||||
int (*bios_limit)(int cpu, unsigned int *limit);
|
||||
|
||||
--
|
||||
2.42.0.rc0.25.ga82fb66fed
|
@ -16,5 +16,3 @@ patch -Np1 < "../patches/0002-eevdfbore.patch"
|
||||
patch -Np1 < "../patches/0004-Allow-to-set-custom-USB-pollrate-for-specific-device.patch"
|
||||
# Allow pre polaris cards to use the amdgpu kernel module
|
||||
patch -Np1 < "../patches/0005-amdgpu-si-cik-default.patch"
|
||||
# AMD Patch for CPPC
|
||||
patch -Np1 < "../patches/0006-AMD-cppc.patch"
|
Loading…
Reference in New Issue
Block a user