Skip to content

Commit

Permalink
sched/walt: kill {min,max}_capacity
Browse files Browse the repository at this point in the history
{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 <[email protected]>
Signed-off-by: Juri Lelli <[email protected]>
  • Loading branch information
Juri Lelli authored and DennySPB committed Mar 5, 2018
1 parent 52d9e11 commit d132bc5
Showing 1 changed file with 62 additions and 50 deletions.
112 changes: 62 additions & 50 deletions kernel/sched/walt.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ static unsigned int max_possible_freq = 1;
*/
static unsigned int min_max_freq = 1;

static unsigned int max_capacity = 1024;
static unsigned int min_capacity = 1024;
static unsigned int max_load_scale_factor = 1024;
static unsigned int max_possible_capacity = 1024;

Expand Down Expand Up @@ -879,39 +877,6 @@ void walt_fixup_busy_time(struct task_struct *p, int new_cpu)
double_rq_unlock(src_rq, dest_rq);
}

/* Keep track of max/min capacity possible across CPUs "currently" */
static void __update_min_max_capacity(void)
{
int i;
int max = 0, min = INT_MAX;

for_each_online_cpu(i) {
if (cpu_rq(i)->capacity > max)
max = cpu_rq(i)->capacity;
if (cpu_rq(i)->capacity < min)
min = cpu_rq(i)->capacity;
}

max_capacity = max;
min_capacity = min;
}

static void update_min_max_capacity(void)
{
unsigned long flags;
int i;

local_irq_save(flags);
for_each_possible_cpu(i)
raw_spin_lock(&cpu_rq(i)->lock);

__update_min_max_capacity();

for_each_possible_cpu(i)
raw_spin_unlock(&cpu_rq(i)->lock);
local_irq_restore(flags);
}

/*
* Return 'capacity' of a cpu in reference to "least" efficient cpu, such that
* least efficient cpu gets capacity of 1024
Expand Down Expand Up @@ -985,18 +950,67 @@ static int compute_load_scale_factor(int cpu)
static int cpufreq_notifier_policy(struct notifier_block *nb,
unsigned long val, void *data)
{
struct cpufreq_policy *policy = (struct cpufreq_policy *)data;
int i, update_max = 0;
u64 highest_mpc = 0, highest_mplsf = 0;
const struct cpumask *cpus = policy->related_cpus;
unsigned int orig_min_max_freq = min_max_freq;
unsigned int orig_max_possible_freq = max_possible_freq;
/* Initialized to policy->max in case policy->related_cpus is empty! */
unsigned int orig_max_freq = policy->max;

if (val != CPUFREQ_NOTIFY && val != CPUFREQ_REMOVE_POLICY &&
val != CPUFREQ_CREATE_POLICY)
return 0;
struct cpufreq_policy *policy = (struct cpufreq_policy *)data;
int i, update_max = 0;
u64 highest_mpc = 0, highest_mplsf = 0;
const struct cpumask *cpus = policy->related_cpus;
unsigned int orig_min_max_freq = min_max_freq;
unsigned int orig_max_possible_freq = max_possible_freq;
/* Initialized to policy->max in case policy->related_cpus is empty! */
unsigned int orig_max_freq = policy->max;

if (val != CPUFREQ_NOTIFY)
return 0;

for_each_cpu(i, policy->related_cpus) {
cpumask_copy(&cpu_rq(i)->freq_domain_cpumask,
policy->related_cpus);
orig_max_freq = cpu_rq(i)->max_freq;
cpu_rq(i)->min_freq = policy->min;
cpu_rq(i)->max_freq = policy->max;
cpu_rq(i)->cur_freq = policy->cur;
cpu_rq(i)->max_possible_freq = policy->cpuinfo.max_freq;
}

max_possible_freq = max(max_possible_freq, policy->cpuinfo.max_freq);
if (min_max_freq == 1)
min_max_freq = UINT_MAX;
min_max_freq = min(min_max_freq, policy->cpuinfo.max_freq);
BUG_ON(!min_max_freq);
BUG_ON(!policy->max);

/* Changes to policy other than max_freq don't require any updates */
if (orig_max_freq == policy->max)
return 0;

/*
* A changed min_max_freq or max_possible_freq (possible during bootup)
* needs to trigger re-computation of load_scale_factor and capacity for
* all possible cpus (even those offline). It also needs to trigger
* re-computation of nr_big_task count on all online cpus.
*
* A changed rq->max_freq otoh needs to trigger re-computation of
* load_scale_factor and capacity for just the cluster of cpus involved.
* Since small task definition depends on max_load_scale_factor, a
* changed load_scale_factor of one cluster could influence
* classification of tasks in another cluster. Hence a changed
* rq->max_freq will need to trigger re-computation of nr_big_task
* count on all online cpus.
*
* While it should be sufficient for nr_big_tasks to be
* re-computed for only online cpus, we have inadequate context
* information here (in policy notifier) with regard to hotplug-safety
* context in which notification is issued. As a result, we can't use
* get_online_cpus() here, as it can lead to deadlock. Until cpufreq is
* fixed up to issue notification always in hotplug-safe context,
* re-compute nr_big_task for all possible cpus.
*/

if (orig_min_max_freq != min_max_freq ||
orig_max_possible_freq != max_possible_freq) {
cpus = cpu_possible_mask;
update_max = 1;
}

if (val == CPUFREQ_REMOVE_POLICY || val == CPUFREQ_CREATE_POLICY) {
update_min_max_capacity();
Expand Down Expand Up @@ -1092,9 +1106,7 @@ static int cpufreq_notifier_policy(struct notifier_block *nb,
max_load_scale_factor = highest_mplsf;
}

__update_min_max_capacity();

return 0;
return 0;
}

static int cpufreq_notifier_trans(struct notifier_block *nb,
Expand Down

0 comments on commit d132bc5

Please sign in to comment.