Liao Chang 61bfbf7951 cpufreq: Fix the race condition while updating the transition_task of policy
The field 'transition_task' of policy structure is used to track the
task which is performing the frequency transition. Using this field to
print a warning once detect a case where the same task is calling
_begin() again before completing the preivous frequency transition via
the _end().

However, there is a potential race condition in _end() and _begin() APIs
while updating the field 'transition_task' of policy, the scenario is
depicted below:

             Task A                            Task B

        /* 1st freq transition */
        Invoke _begin() {
                ...
                ...
        }
                                        /* 2nd freq transition */
                                        Invoke _begin() {
                                                ... //waiting for A to
                                                ... //clear
                                                ... //transition_ongoing
                                                ... //in _end() for
                                                ... //the 1st transition
                                                        |
        Change the frequency                            |
                                                        |
        Invoke _end() {                                 |
                ...                                     |
                ...                                     |
                transition_ongoing = false;             V
                                                transition_ongoing = true;
                                                transition_task = current;
                transition_task = NULL;
                ... //A overwrites the task
                ... //performing the transition
                ... //result in error warning.
        }

To fix this race condition, the transition_lock of policy structure is
now acquired before updating policy structure in _end() API. Which ensure
that only one task can update the 'transition_task' field at a time.

Link: https://lore.kernel.org/all/b3c61d8a-d52d-3136-fbf0-d1de9f1ba411@huawei.com/
Fixes: ca654dc3a93d ("cpufreq: Catch double invocations of cpufreq_freq_transition_begin/end")
Signed-off-by: Liao Chang <liaochang1@huawei.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2023-08-29 20:19:31 +02:00
..
2023-08-28 17:58:39 -07:00
2023-08-28 09:31:32 -07:00
2023-06-29 11:00:17 -07:00
2023-08-28 11:04:18 -07:00
2023-06-29 08:09:31 -06:00
2023-08-12 02:36:28 +03:00
2023-08-28 17:22:39 -07:00
2023-08-07 00:01:41 +05:30
2023-08-28 16:35:01 -07:00
2023-08-28 17:34:54 -07:00
2023-07-12 11:56:22 -07:00
2023-08-28 16:35:01 -07:00
2023-08-28 09:31:32 -07:00
2023-06-29 15:28:33 -07:00
2023-08-28 11:33:03 +02:00
2023-08-24 19:10:53 -07:00
2023-07-03 10:55:04 -07:00
2023-08-28 12:59:45 -07:00
2023-08-11 12:14:08 -07:00
2023-06-15 13:42:18 +02:00
2023-08-18 10:55:49 +05:30
2023-08-11 09:39:17 -07:00
2023-08-28 17:34:54 -07:00
2023-08-28 17:49:33 -07:00
2023-07-05 12:55:06 -07:00
2023-07-03 17:03:05 -07:00
2023-06-29 15:22:19 -07:00
2023-07-03 10:43:10 -07:00
2023-08-28 17:22:39 -07:00
2023-08-27 07:33:54 -07:00
2023-08-28 12:59:45 -07:00
2023-07-30 11:47:56 -07:00
2023-07-08 12:35:18 -07:00
2023-06-29 15:22:19 -07:00
2023-08-28 17:58:39 -07:00
2023-08-28 09:31:32 -07:00
2023-06-30 15:22:09 -07:00
2023-08-22 12:12:50 +02:00
2023-08-21 13:27:44 +02:00