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

Waking up sync thread recursively for same CPU causes deadlock.
Fix this by avoiding recursive wakeup call to same thread.

CRs-Fixed: 823472
Change-Id: Idc51f53da9fafc17d609132c8d72d85f76c8160f
Signed-off-by: Swetha Chikkaboraiah <schikk@codeaurora.org>
This commit is contained in:
Swetha Chikkaboraiah 2015-04-15 18:02:31 +05:30 committed by Zhao Wei Liew
parent c5f1a24591
commit 552f19b443

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);
@ -1091,7 +1092,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;
}
@ -1446,6 +1456,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,