cpuquiet: Remove synchronization from runnables_work_func()
authorPeter Boonstoppel <pboonstoppel@nvidia.com>
Thu, 24 Jan 2013 19:04:02 +0000 (11:04 -0800)
committerHuang, Tao <huangtao@rock-chips.com>
Mon, 18 May 2015 08:07:10 +0000 (16:07 +0800)
runnables_stop() can deadlock when cancel_work_sync() waits for the
work function to end and the work function blocks on the same lock
held by runnables_stop().

Removing the locks from runnables_work_func() fixes this. This should
be safe because runnables_lock protects runnables_state and
runnables_work_func() only reads runnables_state. Also, the functions
that change state to DISABLED do a cancel_work_sync() to guarantee the
work function stopped running.

Bug 1215668

Change-Id: I70617b3b0fc81db8555869e67e3b11652af8d94c
Signed-off-by: Peter Boonstoppel <pboonstoppel@nvidia.com>
Reviewed-on: http://git-master/r/193881
Reviewed-by: Mandar Padmawar <mpadmawar@nvidia.com>
Tested-by: Mandar Padmawar <mpadmawar@nvidia.com>
drivers/cpuquiet/governors/runnable_threads.c

index 22cab876d5089993ece560f8b337343df9bdf06e..c91d4566a47def27977430e6bf0fd20c1a5664b4 100644 (file)
@@ -183,11 +183,8 @@ static void runnables_work_func(struct work_struct *work)
        unsigned int cpu = nr_cpu_ids;
        int action;
 
-       mutex_lock(&runnables_lock);
-       if (runnables_state != RUNNING) {
-               mutex_unlock(&runnables_lock);
+       if (runnables_state != RUNNING)
                return;
-       }
 
        action = get_action(nr_run_last);
        if (action > 0) {
@@ -199,7 +196,6 @@ static void runnables_work_func(struct work_struct *work)
                if (cpu < nr_cpu_ids)
                        cpuquiet_quiesence_cpu(cpu);
        }
-       mutex_unlock(&runnables_lock);
 }
 
 CPQ_BASIC_ATTRIBUTE(sample_rate, 0644, uint);