diff --git a/kernel/cpu.c b/kernel/cpu.c index bfef669cbcde..dd56d5a5ae87 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #define CREATE_TRACE_POINTS @@ -1154,9 +1155,37 @@ out: return ret; } +static int switch_to_rt_policy(void) +{ + struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 }; + unsigned int policy = current->policy; + int err; + + /* Nobody should be attempting hotplug from these policy contexts. */ + if (policy == SCHED_BATCH || policy == SCHED_IDLE || + policy == SCHED_DEADLINE) + return -EPERM; + + if (policy == SCHED_FIFO || policy == SCHED_RR) + return 1; + + /* Only SCHED_NORMAL left. */ + err = sched_setscheduler_nocheck(current, SCHED_FIFO, ¶m); + return err; + +} + +static int switch_to_fair_policy(void) +{ + struct sched_param param = { .sched_priority = 0 }; + + return sched_setscheduler_nocheck(current, SCHED_NORMAL, ¶m); +} + static int do_cpu_up(unsigned int cpu, enum cpuhp_state target) { int err = 0; + int switch_err = 0; if (!cpu_possible(cpu)) { pr_err("can't online cpu %d because it is not configured as may-hotadd at boot time\n", @@ -1167,6 +1196,10 @@ static int do_cpu_up(unsigned int cpu, enum cpuhp_state target) return -EINVAL; } + switch_err = switch_to_rt_policy(); + if (switch_err < 0) + return switch_err; + err = try_online_node(cpu_to_node(cpu)); if (err) return err; @@ -1185,6 +1218,14 @@ static int do_cpu_up(unsigned int cpu, enum cpuhp_state target) err = _cpu_up(cpu, 0, target); out: cpu_maps_update_done(); + + if (!switch_err) { + switch_err = switch_to_fair_policy(); + if (switch_err) + pr_err("Hotplug policy switch err=%d Task %s pid=%d\n", + switch_err, current->comm, current->pid); + } + return err; }