2018-12-03 13:29:29 +03:00
// SPDX-License-Identifier: GPL-2.0
2016-03-10 22:44:47 +03:00
/*
* Scheduler code and data structures related to cpufreq .
*
* Copyright ( C ) 2016 , Intel Corporation
* Author : Rafael J . Wysocki < rafael . j . wysocki @ intel . com >
*/
# include "sched.h"
DEFINE_PER_CPU ( struct update_util_data * , cpufreq_update_util_data ) ;
/**
2016-04-02 02:08:43 +03:00
* cpufreq_add_update_util_hook - Populate the CPU ' s update_util_data pointer .
2016-03-10 22:44:47 +03:00
* @ cpu : The CPU to set the pointer for .
* @ data : New pointer value .
2016-04-02 02:08:43 +03:00
* @ func : Callback function to set for the CPU .
2016-03-10 22:44:47 +03:00
*
2016-04-02 02:08:43 +03:00
* Set and publish the update_util_data pointer for the given CPU .
2016-03-10 22:44:47 +03:00
*
2016-04-02 02:08:43 +03:00
* The update_util_data pointer of @ cpu is set to @ data and the callback
* function pointer in the target struct update_util_data is set to @ func .
* That function will be called by cpufreq_update_util ( ) from RCU - sched
* read - side critical sections , so it must not sleep . @ data will always be
* passed to it as the first argument which allows the function to get to the
* target update_util_data structure and its container .
*
* The update_util_data pointer of @ cpu must be NULL when this function is
* called or it will WARN ( ) and return with no effect .
2016-03-10 22:44:47 +03:00
*/
2016-04-02 02:08:43 +03:00
void cpufreq_add_update_util_hook ( int cpu , struct update_util_data * data ,
void ( * func ) ( struct update_util_data * data , u64 time ,
2016-08-16 23:14:55 +03:00
unsigned int flags ) )
2016-03-10 22:44:47 +03:00
{
2016-04-02 02:08:43 +03:00
if ( WARN_ON ( ! data | | ! func ) )
2016-03-10 22:44:47 +03:00
return ;
2016-04-02 02:08:43 +03:00
if ( WARN_ON ( per_cpu ( cpufreq_update_util_data , cpu ) ) )
return ;
data - > func = func ;
2016-03-10 22:44:47 +03:00
rcu_assign_pointer ( per_cpu ( cpufreq_update_util_data , cpu ) , data ) ;
}
2016-04-02 02:08:43 +03:00
EXPORT_SYMBOL_GPL ( cpufreq_add_update_util_hook ) ;
/**
* cpufreq_remove_update_util_hook - Clear the CPU ' s update_util_data pointer .
* @ cpu : The CPU to clear the pointer for .
*
* Clear the update_util_data pointer for the given CPU .
*
* Callers must use RCU - sched callbacks to free any memory that might be
* accessed via the old update_util_data pointer or invoke synchronize_sched ( )
* right after this function to avoid use - after - free .
*/
void cpufreq_remove_update_util_hook ( int cpu )
{
rcu_assign_pointer ( per_cpu ( cpufreq_update_util_data , cpu ) , NULL ) ;
}
EXPORT_SYMBOL_GPL ( cpufreq_remove_update_util_hook ) ;