Skip to content

Commit 25c411f

Browse files
johnstultz-workPeter Zijlstra
authored andcommitted
sched: Add CONFIG_SCHED_PROXY_EXEC & boot argument to enable/disable
Add a CONFIG_SCHED_PROXY_EXEC option, along with a boot argument sched_proxy_exec= that can be used to disable the feature at boot time if CONFIG_SCHED_PROXY_EXEC was enabled. Also uses this option to allow the rq->donor to be different from rq->curr. Signed-off-by: John Stultz <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Tested-by: K Prateek Nayak <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 8f21461 commit 25c411f

File tree

5 files changed

+71
-0
lines changed

5 files changed

+71
-0
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6387,6 +6387,11 @@
63876387
sa1100ir [NET]
63886388
See drivers/net/irda/sa1100_ir.c.
63896389

6390+
sched_proxy_exec= [KNL]
6391+
Enables or disables "proxy execution" style
6392+
solution to mutex-based priority inversion.
6393+
Format: <bool>
6394+
63906395
sched_verbose [KNL,EARLY] Enables verbose scheduler debug messages.
63916396

63926397
schedstats= [KNL,X86] Enable or disable scheduled statistics.

include/linux/sched.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1656,6 +1656,19 @@ struct task_struct {
16561656
randomized_struct_fields_end
16571657
} __attribute__ ((aligned (64)));
16581658

1659+
#ifdef CONFIG_SCHED_PROXY_EXEC
1660+
DECLARE_STATIC_KEY_TRUE(__sched_proxy_exec);
1661+
static inline bool sched_proxy_exec(void)
1662+
{
1663+
return static_branch_likely(&__sched_proxy_exec);
1664+
}
1665+
#else
1666+
static inline bool sched_proxy_exec(void)
1667+
{
1668+
return false;
1669+
}
1670+
#endif
1671+
16591672
#define TASK_REPORT_IDLE (TASK_REPORT + 1)
16601673
#define TASK_REPORT_MAX (TASK_REPORT_IDLE << 1)
16611674

init/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,18 @@ config UCLAMP_BUCKETS_COUNT
878878

879879
If in doubt, use the default value.
880880

881+
config SCHED_PROXY_EXEC
882+
bool "Proxy Execution"
883+
# Avoid some build failures w/ PREEMPT_RT until it can be fixed
884+
depends on !PREEMPT_RT
885+
# Need to investigate how to inform sched_ext of split contexts
886+
depends on !SCHED_CLASS_EXT
887+
# Not particularly useful until we get to multi-rq proxying
888+
depends on EXPERT
889+
help
890+
This option enables proxy execution, a mechanism for mutex-owning
891+
tasks to inherit the scheduling context of higher priority waiters.
892+
881893
endmenu
882894

883895
#

kernel/sched/core.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,35 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(sched_compute_energy_tp);
119119

120120
DEFINE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues);
121121

122+
#ifdef CONFIG_SCHED_PROXY_EXEC
123+
DEFINE_STATIC_KEY_TRUE(__sched_proxy_exec);
124+
static int __init setup_proxy_exec(char *str)
125+
{
126+
bool proxy_enable = true;
127+
128+
if (*str && kstrtobool(str + 1, &proxy_enable)) {
129+
pr_warn("Unable to parse sched_proxy_exec=\n");
130+
return 0;
131+
}
132+
133+
if (proxy_enable) {
134+
pr_info("sched_proxy_exec enabled via boot arg\n");
135+
static_branch_enable(&__sched_proxy_exec);
136+
} else {
137+
pr_info("sched_proxy_exec disabled via boot arg\n");
138+
static_branch_disable(&__sched_proxy_exec);
139+
}
140+
return 1;
141+
}
142+
#else
143+
static int __init setup_proxy_exec(char *str)
144+
{
145+
pr_warn("CONFIG_SCHED_PROXY_EXEC=n, so it cannot be enabled or disabled at boot time\n");
146+
return 0;
147+
}
148+
#endif
149+
__setup("sched_proxy_exec", setup_proxy_exec);
150+
122151
/*
123152
* Debugging: various feature bits
124153
*

kernel/sched/sched.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,10 +1142,15 @@ struct rq {
11421142
*/
11431143
unsigned long nr_uninterruptible;
11441144

1145+
#ifdef CONFIG_SCHED_PROXY_EXEC
1146+
struct task_struct __rcu *donor; /* Scheduling context */
1147+
struct task_struct __rcu *curr; /* Execution context */
1148+
#else
11451149
union {
11461150
struct task_struct __rcu *donor; /* Scheduler context */
11471151
struct task_struct __rcu *curr; /* Execution context */
11481152
};
1153+
#endif
11491154
struct sched_dl_entity *dl_server;
11501155
struct task_struct *idle;
11511156
struct task_struct *stop;
@@ -1326,10 +1331,17 @@ DECLARE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues);
13261331
#define cpu_curr(cpu) (cpu_rq(cpu)->curr)
13271332
#define raw_rq() raw_cpu_ptr(&runqueues)
13281333

1334+
#ifdef CONFIG_SCHED_PROXY_EXEC
1335+
static inline void rq_set_donor(struct rq *rq, struct task_struct *t)
1336+
{
1337+
rcu_assign_pointer(rq->donor, t);
1338+
}
1339+
#else
13291340
static inline void rq_set_donor(struct rq *rq, struct task_struct *t)
13301341
{
13311342
/* Do nothing */
13321343
}
1344+
#endif
13331345

13341346
#ifdef CONFIG_SCHED_CORE
13351347
static inline struct cpumask *sched_group_span(struct sched_group *sg);

0 commit comments

Comments
 (0)