Skip to content

Commit d132bc5

Browse files
Juri LelliDennySPB
authored andcommitted
sched/walt: kill {min,max}_capacity
{min,max}_capacity are static variables that are only updated from __update_min_max_capacity(), but not used anywhere else. Remove them together with the function updating them. This has also the nice side effect of fixing a LOCKDEP warning related to locking all CPUs in update_min_max_capacity(), as reported by Ke Wang: [ 2.853595] c0 ============================================= [ 2.859219] c0 [ INFO: possible recursive locking detected ] [ 2.864852] c0 4.4.6+ CyanogenMod#5 Tainted: G W [ 2.869604] c0 --------------------------------------------- [ 2.875230] c0 swapper/0/1 is trying to acquire lock: [ 2.880248] (&rq->lock){-.-.-.}, at: [<ffffff80081241cc>] cpufreq_notifier_policy+0x2e8/0x37c [ 2.888815] c0 [ 2.888815] c0 but task is already holding lock: [ 2.895132] (&rq->lock){-.-.-.}, at: [<ffffff80081241cc>] cpufreq_notifier_policy+0x2e8/0x37c [ 2.903700] c0 [ 2.903700] c0 other info that might help us debug this: [ 2.910710] c0 Possible unsafe locking scenario: [ 2.910710] c0 [ 2.917112] c0 CPU0 [ 2.919795] c0 ---- [ 2.922478] lock(&rq->lock); [ 2.925507] lock(&rq->lock); [ 2.928536] c0 [ 2.928536] c0 *** DEADLOCK *** [ 2.928536] c0 [ 2.935200] c0 May be due to missing lock nesting notation [ 2.935200] c0 [ 2.942471] c0 7 locks held by swapper/0/1: [ 2.946623] #0: (&dev->mutex){......}, at: [<ffffff800850e118>] __driver_attach+0x64/0xb8 [ 2.954931] #1: (&dev->mutex){......}, at: [<ffffff800850e128>] __driver_attach+0x74/0xb8 [ 2.963239] AOSP-JF-MM#2: (cpu_hotplug.lock){++++++}, at: [<ffffff80080cb218>] get_online_cpus+0x48/0xa8 [ 2.971979] CyanogenMod#3: (subsys mutex#6){+.+.+.}, at: [<ffffff800850bed4>] subsys_interface_register+0x44/0xc0 [ 2.981411] CyanogenMod#4: (&policy->rwsem){+.+.+.}, at: [<ffffff8008720338>] cpufreq_online+0x330/0x76c [ 2.990065] CyanogenMod#5: ((cpufreq_policy_notifier_list).rwsem){.+.+..}, at: [<ffffff80080f3418>] blocking_notifier_call_chain+0x38/0xc4 [ 3.001661] CyanogenMod#6: (&rq->lock){-.-.-.}, at: [<ffffff80081241cc>] cpufreq_notifier_policy+0x2e8/0x37c [ 3.010661] c0 [ 3.010661] c0 stack backtrace: [ 3.015514] c0 CPU: 0 PID: 1 Comm: swapper/0 Tainted: G W 4.4.6+ CyanogenMod#5 [ 3.022864] c0 Hardware name: Spreadtrum SP9860g Board (DT) [ 3.028402] c0 Call trace: [ 3.031092] c0 [<ffffff800808b50c>] dump_backtrace+0x0/0x210 [ 3.036716] c0 [<ffffff800808b73c>] show_stack+0x20/0x28 [ 3.041994] c0 [<ffffff8008433310>] dump_stack+0xa8/0xe0 [ 3.047273] c0 [<ffffff80081349e0>] __lock_acquire+0x1e0c/0x2218 [ 3.053243] c0 [<ffffff80081353c0>] lock_acquire+0xe0/0x280 [ 3.058784] c0 [<ffffff8008abfdfc>] _raw_spin_lock+0x44/0x58 [ 3.064407] c0 [<ffffff80081241cc>] cpufreq_notifier_policy+0x2e8/0x37c [ 3.070983] c0 [<ffffff80080f3458>] blocking_notifier_call_chain+0x78/0xc4 [ 3.077820] c0 [<ffffff8008720294>] cpufreq_online+0x28c/0x76c [ 3.083618] c0 [<ffffff80087208a4>] cpufreq_add_dev+0x98/0xdc [ 3.089331] c0 [<ffffff800850bf14>] subsys_interface_register+0x84/0xc0 [ 3.095907] c0 [<ffffff800871fa0c>] cpufreq_register_driver+0x168/0x28c [ 3.102486] c0 [<ffffff80087272f8>] sprd_cpufreq_probe+0x134/0x19c [ 3.108629] c0 [<ffffff8008510768>] platform_drv_probe+0x58/0xd0 [ 3.114599] c0 [<ffffff800850de2c>] driver_probe_device+0x1e8/0x470 [ 3.120830] c0 [<ffffff800850e168>] __driver_attach+0xb4/0xb8 [ 3.126541] c0 [<ffffff800850b750>] bus_for_each_dev+0x6c/0xac [ 3.132339] c0 [<ffffff800850d6c0>] driver_attach+0x2c/0x34 [ 3.137877] c0 [<ffffff800850d234>] bus_add_driver+0x210/0x298 [ 3.143676] c0 [<ffffff800850f1f4>] driver_register+0x7c/0x114 [ 3.149476] c0 [<ffffff8008510654>] __platform_driver_register+0x60/0x6c [ 3.156139] c0 [<ffffff8008f49f40>] sprd_cpufreq_platdrv_init+0x18/0x20 [ 3.162714] c0 [<ffffff8008082a64>] do_one_initcall+0xd0/0x1d8 [ 3.168514] c0 [<ffffff8008f0bc58>] kernel_init_freeable+0x1fc/0x29c [ 3.174834] c0 [<ffffff8008ab554c>] kernel_init+0x20/0x12c [ 3.180281] c0 [<ffffff8008086290>] ret_from_fork+0x10/0x40 Change-Id: I5ebc57ea2681350c2f942e7c90078298cf5ec096 Reported-by: Ke Wang <ke.wang@spreadtrum.com> Signed-off-by: Juri Lelli <juri.lelli@arm.com>
1 parent 52d9e11 commit d132bc5

1 file changed

Lines changed: 62 additions & 50 deletions

File tree

kernel/sched/walt.c

Lines changed: 62 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,6 @@ static unsigned int max_possible_freq = 1;
6262
*/
6363
static unsigned int min_max_freq = 1;
6464

65-
static unsigned int max_capacity = 1024;
66-
static unsigned int min_capacity = 1024;
6765
static unsigned int max_load_scale_factor = 1024;
6866
static unsigned int max_possible_capacity = 1024;
6967

@@ -879,39 +877,6 @@ void walt_fixup_busy_time(struct task_struct *p, int new_cpu)
879877
double_rq_unlock(src_rq, dest_rq);
880878
}
881879

882-
/* Keep track of max/min capacity possible across CPUs "currently" */
883-
static void __update_min_max_capacity(void)
884-
{
885-
int i;
886-
int max = 0, min = INT_MAX;
887-
888-
for_each_online_cpu(i) {
889-
if (cpu_rq(i)->capacity > max)
890-
max = cpu_rq(i)->capacity;
891-
if (cpu_rq(i)->capacity < min)
892-
min = cpu_rq(i)->capacity;
893-
}
894-
895-
max_capacity = max;
896-
min_capacity = min;
897-
}
898-
899-
static void update_min_max_capacity(void)
900-
{
901-
unsigned long flags;
902-
int i;
903-
904-
local_irq_save(flags);
905-
for_each_possible_cpu(i)
906-
raw_spin_lock(&cpu_rq(i)->lock);
907-
908-
__update_min_max_capacity();
909-
910-
for_each_possible_cpu(i)
911-
raw_spin_unlock(&cpu_rq(i)->lock);
912-
local_irq_restore(flags);
913-
}
914-
915880
/*
916881
* Return 'capacity' of a cpu in reference to "least" efficient cpu, such that
917882
* least efficient cpu gets capacity of 1024
@@ -985,18 +950,67 @@ static int compute_load_scale_factor(int cpu)
985950
static int cpufreq_notifier_policy(struct notifier_block *nb,
986951
unsigned long val, void *data)
987952
{
988-
struct cpufreq_policy *policy = (struct cpufreq_policy *)data;
989-
int i, update_max = 0;
990-
u64 highest_mpc = 0, highest_mplsf = 0;
991-
const struct cpumask *cpus = policy->related_cpus;
992-
unsigned int orig_min_max_freq = min_max_freq;
993-
unsigned int orig_max_possible_freq = max_possible_freq;
994-
/* Initialized to policy->max in case policy->related_cpus is empty! */
995-
unsigned int orig_max_freq = policy->max;
996-
997-
if (val != CPUFREQ_NOTIFY && val != CPUFREQ_REMOVE_POLICY &&
998-
val != CPUFREQ_CREATE_POLICY)
999-
return 0;
953+
struct cpufreq_policy *policy = (struct cpufreq_policy *)data;
954+
int i, update_max = 0;
955+
u64 highest_mpc = 0, highest_mplsf = 0;
956+
const struct cpumask *cpus = policy->related_cpus;
957+
unsigned int orig_min_max_freq = min_max_freq;
958+
unsigned int orig_max_possible_freq = max_possible_freq;
959+
/* Initialized to policy->max in case policy->related_cpus is empty! */
960+
unsigned int orig_max_freq = policy->max;
961+
962+
if (val != CPUFREQ_NOTIFY)
963+
return 0;
964+
965+
for_each_cpu(i, policy->related_cpus) {
966+
cpumask_copy(&cpu_rq(i)->freq_domain_cpumask,
967+
policy->related_cpus);
968+
orig_max_freq = cpu_rq(i)->max_freq;
969+
cpu_rq(i)->min_freq = policy->min;
970+
cpu_rq(i)->max_freq = policy->max;
971+
cpu_rq(i)->cur_freq = policy->cur;
972+
cpu_rq(i)->max_possible_freq = policy->cpuinfo.max_freq;
973+
}
974+
975+
max_possible_freq = max(max_possible_freq, policy->cpuinfo.max_freq);
976+
if (min_max_freq == 1)
977+
min_max_freq = UINT_MAX;
978+
min_max_freq = min(min_max_freq, policy->cpuinfo.max_freq);
979+
BUG_ON(!min_max_freq);
980+
BUG_ON(!policy->max);
981+
982+
/* Changes to policy other than max_freq don't require any updates */
983+
if (orig_max_freq == policy->max)
984+
return 0;
985+
986+
/*
987+
* A changed min_max_freq or max_possible_freq (possible during bootup)
988+
* needs to trigger re-computation of load_scale_factor and capacity for
989+
* all possible cpus (even those offline). It also needs to trigger
990+
* re-computation of nr_big_task count on all online cpus.
991+
*
992+
* A changed rq->max_freq otoh needs to trigger re-computation of
993+
* load_scale_factor and capacity for just the cluster of cpus involved.
994+
* Since small task definition depends on max_load_scale_factor, a
995+
* changed load_scale_factor of one cluster could influence
996+
* classification of tasks in another cluster. Hence a changed
997+
* rq->max_freq will need to trigger re-computation of nr_big_task
998+
* count on all online cpus.
999+
*
1000+
* While it should be sufficient for nr_big_tasks to be
1001+
* re-computed for only online cpus, we have inadequate context
1002+
* information here (in policy notifier) with regard to hotplug-safety
1003+
* context in which notification is issued. As a result, we can't use
1004+
* get_online_cpus() here, as it can lead to deadlock. Until cpufreq is
1005+
* fixed up to issue notification always in hotplug-safe context,
1006+
* re-compute nr_big_task for all possible cpus.
1007+
*/
1008+
1009+
if (orig_min_max_freq != min_max_freq ||
1010+
orig_max_possible_freq != max_possible_freq) {
1011+
cpus = cpu_possible_mask;
1012+
update_max = 1;
1013+
}
10001014

10011015
if (val == CPUFREQ_REMOVE_POLICY || val == CPUFREQ_CREATE_POLICY) {
10021016
update_min_max_capacity();
@@ -1092,9 +1106,7 @@ static int cpufreq_notifier_policy(struct notifier_block *nb,
10921106
max_load_scale_factor = highest_mplsf;
10931107
}
10941108

1095-
__update_min_max_capacity();
1096-
1097-
return 0;
1109+
return 0;
10981110
}
10991111

11001112
static int cpufreq_notifier_trans(struct notifier_block *nb,

0 commit comments

Comments
 (0)