#define PASS_CPU_STATS_MAX_COUNT 20
+struct pass_governor {
+ char name[BUFF_MAX];
+ enum pass_gov_state gov_state;
+
+ int (*init)(struct pass_resource *res);
+ int (*exit)(struct pass_resource *res);
+ int (*update)(struct pass_resource *res, enum pass_gov_state state);
+ int (*governor)(struct pass_resource *res);
+};
+
/*
* is_enabled - Check the state of PASS governor
- * @policy: instance of pass_policy structure
+ * @policy: the instance of struct pass_policy
*
* Return true if the state of PASS is PASS_GOV_START
* Return false if the state of PASS is PASS_GOV_STOP
*/
static bool is_enabled(struct pass_policy *policy)
{
- if (!policy)
- return false;
-
if (policy->governor->gov_state != PASS_GOV_START)
return false;
/*
* pass_notifier_pmqos - Callback func of DEVICE_NOTIFIER_PMQOS
* @data: the scenario name
- * @user_data: the instance of struct pass_policy
+ * @user_data: the instance of struct pass_resource
*/
static int pass_notifier_pmqos(void *data, void *user_data)
{
- struct pass_policy *policy = user_data;
+ struct pass_resource *res = user_data;
- if (policy->state == PASS_ON)
- pass_notifier_pmqos_func(policy, data);
+ if (res->policy.state == PASS_ON)
+ pass_notifier_pmqos_func(res, data);
return 0;
}
/*
* pass_notifier_init - Register notifiers and init
- * @policy: the instance of pass_policy structure
+ * @res: the instance of struct pass_resource
*/
-static int pass_notifier_init(struct pass_policy *policy)
+static int pass_notifier_init(struct pass_resource *res)
{
/* Register DEVICE_NOTIFIER_PMQOS */
return register_notifier(DEVICE_NOTIFIER_PMQOS, pass_notifier_pmqos,
- policy);
+ res);
}
/*
* pass_notifier_exit - Un-register notifiers and exit
- * @policy: the instance of pass_policy structure
+ * @res: the instance of struct pass_resource
*/
-static int pass_notifier_exit(struct pass_policy *policy)
+static int pass_notifier_exit(struct pass_resource *res)
{
/* Un-register DEVICE_NOTIFIER_PMQOS */
unregister_notifier(DEVICE_NOTIFIER_PMQOS, pass_notifier_pmqos,
- policy);
+ res);
return 0;
}
/*
* pass_hotplug_stop - Stop PASS hotplug
- *
- * @policy: the instance of struct pass_policy
+ * @res: the instance of struct pass_resource
*/
-static void pass_hotplug_stop(struct pass_policy *policy)
+static void pass_hotplug_stop(struct pass_resource *res)
{
+ struct pass_policy *policy = &res->policy;
struct pass_level *levels = policy->levels;
int level = policy->max_level;
policy->hotplug->online = levels[level].limit_min_cpu;
}
-static int pass_hotplug_dummy_governor(struct pass_policy *policy)
+static int pass_hotplug_dummy_governor(struct pass_resource *res)
{
+ struct pass_policy *policy = &res->policy;
int level = policy->curr_level;
return policy->levels[level].limit_min_cpu;
/*
* pass_get_governor - Return specific hotplug instance according to type
- *
+ * @res: the instance of struct pass_resource
* @type: the type of PASS hotplug
*/
-struct pass_hotplug* pass_get_hotplug(struct pass_policy *policy,
+struct pass_hotplug* pass_get_hotplug(struct pass_resource *res,
enum pass_gov_type type)
{
struct pass_hotplug *hotplug;
/*
* pass_calculate_busy_cpu - Count a number of busy cpu among NR_CPUS by using
* runnable_avg_sum/runnable_avg_period
- *
- * @policy: the instance of struct pass_policy
+ * @res: the instance of struct pass_resource
*/
-static void pass_calculate_busy_cpu(struct pass_policy *policy)
+static void pass_calculate_busy_cpu(struct pass_resource *res)
{
+ struct pass_policy *policy = &res->policy;
struct pass_cpu_stats *stats = policy->pass_cpu_stats;
- struct pass_resource *res = to_pass_resource(policy);
struct pass_level *levels = policy->levels;
struct pass_conf_data *cdata = &res->cdata;
unsigned int level = policy->curr_level;
/*
* pass_governor_timeout_cb - Callback for each timeout interval of the governor
- *
- * @data: the instance of struct pass_policy
+ * @data: the instance of struct pass_resource
*/
static gboolean pass_governor_timeout_cb(gpointer data)
{
- struct pass_policy *policy = (struct pass_policy *) data;
+ struct pass_resource *res = (struct pass_resource *)data;
+ struct pass_policy *policy = &res->policy;
static int count = 0;
double curr_gov_timeout, next_gov_timeout;
int level, ret;
- if (!policy) {
+ if (!res) {
_E("cannot call the governor timeout callback\n");
return FALSE;
}
* - the number of nr_running
* - the resource utilization
*/
- ret = pass_get_cpu_stats(policy);
+ ret = pass_get_cpu_stats(res);
if (ret < 0) {
if (count++ < PASS_CPU_STATS_MAX_COUNT)
return TRUE;
count = 0;
_E("cannot read the 'pass_cpu_stats' sysfs entry");
- pass_governor_update(policy, PASS_GOV_STOP);
+ pass_governor_update(res, PASS_GOV_STOP);
return FALSE;
}
/* Calculate the number of busy cpu */
- pass_calculate_busy_cpu(policy);
+ pass_calculate_busy_cpu(res);
/* Store current governor timeout */
curr_gov_timeout = policy->levels[policy->curr_level].gov_timeout;
/* Determine the amount of proper resource */
if (policy->governor->governor) {
- level = policy->governor->governor(policy);
+ level = policy->governor->governor(res);
- pass_rescon_set_level(policy, level);
+ pass_rescon_set_level(res, level);
} else {
_E("cannot call the governor function");
- pass_governor_update(policy, PASS_GOV_STOP);
+ pass_governor_update(res, PASS_GOV_STOP);
return FALSE;
}
policy->gov_timeout_id = g_timeout_add(
(guint)(next_gov_timeout * 1000),
pass_governor_timeout_cb,
- (gpointer)policy);
+ (gpointer)res);
}
return TRUE;
/*
* __pass_governor_start - Start PASS governor through D-Bus
- *
- * @policy: the instance of struct pass_policy
+ * @res: the instance of struct pass_resource
*/
-static void __pass_governor_start(struct pass_policy *policy)
+static void __pass_governor_start(struct pass_resource *res)
{
- struct pass_resource *res = to_pass_resource(policy);
+ struct pass_policy *policy = &res->policy;
struct pass_conf_data *cdata = &res->cdata;
if (!policy->governor) {
policy->gov_timeout_id = g_timeout_add(
(guint)(policy->gov_timeout * 1000),
(GSourceFunc)pass_governor_timeout_cb,
- (gpointer)policy);
+ (gpointer)res);
if (!policy->gov_timeout_id) {
_E("cannot add core timer for governor");
- pass_governor_update(policy, PASS_GOV_STOP);
+ pass_governor_update(res, PASS_GOV_STOP);
return;
}
} else {
if (policy->init_level > policy->max_level)
policy->init_level = policy->max_level;
- pass_rescon_set_level(policy, policy->init_level);
+ pass_rescon_set_level(res, policy->init_level);
/* Set PASS state as PASS_GOV_START */
policy->governor->gov_state = PASS_GOV_START;
/*
* __pass_governor_stop - Stop PASS governor through D-Bus
- *
- * @policy: the instance of struct pass_policy
+ * @res: the instance of struct pass_resource
*/
-static void __pass_governor_stop(struct pass_policy *policy)
+static void __pass_governor_stop(struct pass_resource *res)
{
- struct pass_resource *res = to_pass_resource(policy);
+ struct pass_policy *policy = &res->policy;
struct pass_conf_data *cdata = &res->cdata;
if (!policy->governor) {
return;
}
- pass_hotplug_stop(policy);
+ pass_hotplug_stop(res);
if (policy->gov_timeout_id) {
g_source_remove(policy->gov_timeout_id);
_I("Stop governor for '%s' resource", cdata->res_name);
}
-static int __pass_governor_init(struct pass_policy *policy)
+static int __pass_governor_init(struct pass_resource *res)
{
+ struct pass_policy *policy = &res->policy;
int ret;
if (policy->gov_timeout < 0) {
_E("invalid timeout value [%d]!", policy->gov_timeout);
- pass_governor_update(policy, PASS_GOV_STOP);
+ pass_governor_update(res, PASS_GOV_STOP);
return -EINVAL;
}
/* Set default PASS state */
policy->governor->gov_state = PASS_GOV_STOP;
- ret = pass_notifier_init(policy);
+ ret = pass_notifier_init(res);
if (ret < 0) {
_E("cannot initialize notifier for the pmqos (%d)\n", ret);
return ret;
}
if (policy->state == PASS_ON)
- pass_governor_update(policy, PASS_GOV_START);
+ pass_governor_update(res, PASS_GOV_START);
return 0;
}
-static int __pass_governor_exit(struct pass_policy *policy)
+static int __pass_governor_exit(struct pass_resource *res)
{
+ struct pass_policy *policy = &res->policy;
int i;
/* Exit notifier */
- pass_notifier_exit(policy);
+ pass_notifier_exit(res);
/*
* Stop timer and
* Restore the frequency and the number of online resources
*/
- pass_governor_update(policy, PASS_GOV_STOP);
+ pass_governor_update(res, PASS_GOV_STOP);
/* Free allocated memory */
for (i = 0; i < policy->num_pass_cpu_stats; i++) {
return 0;
}
-static int __pass_governor_update(struct pass_policy *policy,
+static int __pass_governor_update(struct pass_resource *res,
enum pass_gov_state state)
{
- if (!policy) {
- _E("cannot update PASS governor");
- return -EINVAL;
- }
-
switch (state) {
case PASS_GOV_START:
- __pass_governor_start(policy);
+ __pass_governor_start(res);
break;
case PASS_GOV_STOP:
- __pass_governor_stop(policy);
+ __pass_governor_stop(res);
break;
default:
_E("Unknown governor state");
/*
* pass_get_governor - Return specific governor instance according to type
- *
* @type: the type of PASS governor
*/
-struct pass_governor* pass_get_governor(struct pass_policy *policy,
+struct pass_governor* pass_get_governor(struct pass_resource *res,
enum pass_gov_type type)
{
switch (type) {
}
/*
- * __pass_governor_init - Initialize PASS governor
- *
- * @policy: the instance of struct pass_policy
+ * pass_governor_init - Initialize PASS governor
+ * @res: the instance of struct pass_resource
*/
-int pass_governor_init(struct pass_policy *policy)
+int pass_governor_init(struct pass_resource *res)
{
- if (!policy || !policy->governor || !policy->governor->init)
+ struct pass_policy *policy;
+
+ if (!res)
return -EINVAL;
- return policy->governor->init(policy);
+ policy = &res->policy;
+
+ if (!policy->governor || !policy->governor->init)
+ return -EINVAL;
+
+ return policy->governor->init(res);
}
/*
- * __pass_governor_exit - Exit PASS governor
+ * pass_governor_exit - Exit PASS governor
+ * @res: the instance of struct pass_resource
*/
-int pass_governor_exit(struct pass_policy *policy)
+int pass_governor_exit(struct pass_resource *res)
{
- if (!policy || !policy->governor || !policy->governor->exit)
+ struct pass_policy *policy;
+
+ if (!res)
return -EINVAL;
- return policy->governor->exit(policy);
+ policy = &res->policy;
+
+ if (!policy->governor || !policy->governor->exit)
+ return -EINVAL;
+
+ return policy->governor->exit(res);
}
/*
- * __pass_governor_update - Restart/Pause PASS governor
- *
- * @policy: the instance of struct pass_policy
+ * pass_governor_update - Restart/Pause PASS governor
+ * @res: the instance of struct pass_resource
* @state: the state of governor
* PASS_GOV_START : start governor
* PASS_GOV_STOP: stop governor
*/
-int pass_governor_update(struct pass_policy *policy,
+int pass_governor_update(struct pass_resource *res,
enum pass_gov_state state)
{
- if (!policy || !policy->governor || !policy->governor->update)
+ struct pass_policy *policy;
+
+ if (!res)
+ return -EINVAL;
+
+ policy = &res->policy;
+
+ if (!policy->governor || !policy->governor->update)
return -EINVAL;
- return policy->governor->update(policy, state);
+ return policy->governor->update(res, state);
}
/*
* pass_rescon_set_level - Change frequency and number of online resources
*
- * @policy: the instance of struct pass_policy
+ * @res: the instance of struct pass_resource
* @new_level: the desired pass level
*/
-int pass_rescon_set_level(struct pass_policy *policy, int new_level)
+int pass_rescon_set_level(struct pass_resource *res, int new_level)
{
- struct pass_resource *res = to_pass_resource(policy);
- struct pass_conf_data *cdata = &res->cdata;
- struct pass_level *levels = policy->levels;
- struct pass_hotplug *hotplug = policy->hotplug;
- int curr_level = policy->curr_level;
+ struct pass_policy *policy;
+ struct pass_conf_data *cdata;
+ struct pass_level *levels;
+ struct pass_hotplug *hotplug;
+ int curr_level;
int limit_max_freq;
int limit_min_freq;
int limit_min_cpu;
int fault_around_bytes;
int ret;
+ if (!res)
+ return -EINVAL;
+
+ policy = &res->policy;
+
+ cdata = &res->cdata;
+ levels = policy->levels;
+ hotplug = policy->hotplug;
+ curr_level = policy->curr_level;
+
if (new_level > policy->max_level)
new_level = policy->max_level;
/* Turn on/off CPUs according the maximum number of online CPU */
if (hotplug) {
if (hotplug->governor)
- limit_min_cpu = hotplug->governor(policy);
+ limit_min_cpu = hotplug->governor(res);
else
limit_min_cpu = 1;
/*
* pass_rescon_set_level_scope - Change the scope of pass level
*
- * @policy: the instance of struct pass_policy
+ * @res: the instance of struct pass_resource
* @new_level: the desirous pass level
* @min_level: the minimum pass level
* @max_level: the maximum pass level
* @data: the PMQoS's data containing the scenario name and lock state
*/
-int pass_rescon_set_level_scope(struct pass_policy *policy, int new_level,
+int pass_rescon_set_level_scope(struct pass_resource *res, int new_level,
int min_level, int max_level, void *data)
{
- if (!policy)
+ struct pass_policy *policy;
+
+ if (!res)
return -EINVAL;
+ policy = &res->policy;
/*
* FIXME: PMQoS core sends the raw data to the HAL in order to
* be removed after finding the proper method.
*/
if (data)
- pass_set_pmqos_data(to_pass_resource(policy), data);
+ pass_set_pmqos_data(res, data);
if (min_level > max_level) {
_E("min_level(%d) have to be smaller than max_level(%d)\n",
policy->min_level = min_level;
policy->max_level = max_level;
- pass_rescon_set_level(policy, new_level);
+ pass_rescon_set_level(res, new_level);
return 0;
}