Merge "cpufreq: ondemand: Resolve deadlock when waking up dbs sync thread"

This commit is contained in:
Linux Build Service Account
2015-04-17 12:47:59 -07:00
committed by Gerrit - the friendly Code Review server
+13 -2
View File
@@ -4,7 +4,7 @@
* Copyright (C) 2001 Russell King
* (C) 2003 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>.
* Jun Nakajima <jun.nakajima@intel.com>
* (c) 2013 The Linux Foundation. All rights reserved.
* (c) 2013, 2015 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -108,6 +108,7 @@ struct cpu_dbs_info_s {
struct task_struct *sync_thread;
wait_queue_head_t sync_wq;
atomic_t src_sync_cpu;
atomic_t being_woken;
atomic_t sync_enabled;
};
static DEFINE_PER_CPU(struct cpu_dbs_info_s, od_cpu_dbs_info);
@@ -1087,7 +1088,16 @@ static int dbs_migration_notify(struct notifier_block *nb,
&per_cpu(od_cpu_dbs_info, target_cpu);
atomic_set(&target_dbs_info->src_sync_cpu, (int)arg);
wake_up(&target_dbs_info->sync_wq);
/*
* Avoid issuing recursive wakeup call, as sync thread itself could be
* seen as migrating triggering this notification. Note that sync thread
* of a cpu could be running for a short while with its affinity broken
* because of CPU hotplug.
*/
if (!atomic_cmpxchg(&target_dbs_info->being_woken, 0, 1)) {
wake_up(&target_dbs_info->sync_wq);
atomic_set(&target_dbs_info->being_woken, 0);
}
return NOTIFY_OK;
}
@@ -1442,6 +1452,7 @@ static int __init cpufreq_gov_dbs_init(void)
dbs_work->cpu = i;
atomic_set(&this_dbs_info->src_sync_cpu, -1);
atomic_set(&this_dbs_info->being_woken, 0);
init_waitqueue_head(&this_dbs_info->sync_wq);
this_dbs_info->sync_thread = kthread_run(dbs_sync_thread,