#define BUFF_MAX 255
#define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0]))
+#define INIT_VALUE -1
/*
* One byte digit has 3 position in decimal representation
#include <stdlib.h>
#include "pass.h"
+#include "pass-rescon.h"
#include "pass-resmon.h"
#define PASS_CPU_STATS_MAX_COUNT 20
int up_threshold = cpuhp->up_threshold;
int down_threshold = cpuhp->down_threshold;
int num_pass_gov = 0;
- int level = res->rescon.curr_level;
+ int level = 0;
int up_count = 0;
int down_count = 0;
int left_count = 0;
int i;
int j;
int64_t time;
+ int max_level;
+
+ pass_rescon_get_curr_level(res, &level);
+ pass_rescon_get_max_level(res, &max_level);
for (i = 0; i < PASS_CPU_STATS_MAX_COUNT; i++) {
time = cpu_stats[i].time;
if (up_count * 100 >= num_pass_gov * up_threshold) {
level += res->config_data.num_cpus;
- if (level > res->rescon.max_level)
+ if (level > max_level)
level -= res->config_data.num_cpus;
} else if (down_count * 100 >= num_pass_gov * down_threshold) {
level -= res->config_data.num_cpus;
if (right_count * 100 >= num_pass_gov * up_threshold) {
level += 1;
- if (level > res->rescon.max_level)
+ if (level > max_level)
level -= 1;
} else if (left_count * 100 >= num_pass_gov * down_threshold) {
level -= 1;
}
- /*
- if (level == res->prev_level) {
- for (i = num_pass_gov; i < PASS_CPU_STATS_MAX_COUNT; i++) {
- time = cpu_stats[i].time;
- freq = cpu_stats[i].freq;
- nr_running = cpu_stats[i].nr_runnings;
- busy_cpu = cpu_stats[i].num_busy_cpu;
-
- _I("[Level%d][%d][%lld] %d | %d | %d",
- level, i, time, freq,
- nr_running, busy_cpu);
- }
- }
-
- if (level != res->rescon.curr_level) {
- _I("\n[Level%d] num_pass_gov: [%2d]", level, num_pass_gov);
- _I("[Level%d] down_count : %2d (%3d >= %3d)", level, down_count,
- down_count * 100, num_pass_gov * down_threshold);
- _I("[Level%d] up_count : %2d (%3d >= %3d)", level, up_count,
- up_count * 100, num_pass_gov * up_threshold);
- _I("[Level%d] left_count : %2d (%3d >= %3d)", level, left_count,
- left_count * 100, num_pass_gov * down_threshold);
- _I("[Level%d] right_count : %2d (%3d >= %3d)", level, right_count,
- right_count * 100, num_pass_gov * up_threshold);
- }
- */
-
return level;
}
#include <stdlib.h>
#include "pass.h"
+#include "pass-rescon.h"
#include "pass-resmon.h"
#define PASS_CPU_STATS_MAX_COUNT 20
int up_threshold = cpuhp->up_threshold;
int down_threshold = cpuhp->down_threshold;
int num_pass_gov = 0;
- int level = res->rescon.curr_level;
+ int level = 0;
int up_count = 0;
int up_max_count = 0;
int down_count = 0;
int i;
int j;
int64_t time;
+ int max_level = 0;
+ int min_level = 0;
+
+ pass_rescon_get_curr_level(res, &level);
+ pass_rescon_get_max_level(res, &max_level);
+ pass_rescon_get_min_level(res, &min_level);
for (i = 0; i < PASS_CPU_STATS_MAX_COUNT; i++) {
time = cpu_stats[i].time;
*/
}
- if (level < res->rescon.max_level &&
+ if (level < max_level &&
freq == levels[level].limit_max_freq)
up_max_count++;
}
if (!num_pass_gov)
return level;
- if (up_count && level < res->rescon.max_level &&
+ if (up_count && level < max_level &&
up_count * 100 >= num_pass_gov * up_threshold) {
level += 1;
- } else if (down_count && level > res->rescon.min_level &&
+ } else if (down_count && level > min_level &&
down_count * 100 >= num_pass_gov * down_threshold) {
level -= 1;
}
struct pass_level *levels = res->config_data.levels;
struct pass_resource_config_data *config_data = &res->config_data;
struct resmon_result_src_cpuhp *stats = result;
- unsigned int level = res->rescon.curr_level;
+ int level = 0;
unsigned int cpu_threshold = 0;
unsigned int busy_cpu;
unsigned int cur_freq;
int limit_min_cpu;
int i;
int j;
+ int ret;
+
+ ret = pass_rescon_get_curr_level(res, &level);
+ if (ret < 0) {
+ _E("failed to get curr level of '%s' resource",
+ res->config_data.res_name);
+ return;
+ }
limit_min_cpu = levels[level].limit_min_cpu;
struct pass_cpuhp *cpuhp;
int curr_gov_timeout, next_gov_timeout;
int level;
+ int curr_level;
if (!res) {
_E("cannot call the governor timeout callback\n");
levels = res->config_data.levels;
cpuhp = &res->cpuhp;
+ pass_rescon_get_curr_level(res, &curr_level);
+
/* Calculate the number of busy cpu */
cpuhp_calculate_busy_cpu(res, result);
/* Store current governor timeout */
- curr_gov_timeout = levels[res->rescon.curr_level].gov_timeout;
+ curr_gov_timeout = levels[curr_level].gov_timeout;
/* Determine the amount of proper resource */
if (cpuhp->governor->governor) {
}
/* Get the governor timeout interval for the next */
- next_gov_timeout = levels[res->rescon.curr_level].gov_timeout;
+ next_gov_timeout = levels[curr_level].gov_timeout;
/*
* Change the governor timeout interval when the next interval is not
#include <libsyscommon/resource-type.h>
#include "pass.h"
+#include "pass-rescon.h"
#define MAX_NUM 255
#define MIN_TIMEOUT_MS 200
#define MAX_TIMEOUT_MS 3600000 /* 1 hour */
-#define INIT_VALUE -1
static int compare_compatible_name(const char *compatible,
const char *path_compatible)
}
/* Initialize config_data from property values of confiugartion file */
- res->rescon.min_level = cpuhp_min_level;
- res->rescon.max_level = cpuhp_max_level;
- res->rescon.init_level = cpuhp_init_level;
+ pass_rescon_set_min_level(res, cpuhp_min_level);
+ pass_rescon_set_max_level(res, cpuhp_max_level);
+ pass_rescon_set_init_level(res, cpuhp_init_level);
if (res->config_data.gov_timeout < MIN_TIMEOUT_MS
|| res->config_data.gov_timeout > MAX_TIMEOUT_MS)
if (init_level < 0)
init_level = 0;
- res->rescon.init_scenario_level = init_level;
+
+ /* Initialize config_data from property values of confiugartion file */
+ pass_rescon_set_init_scenario_level(res, init_level);
res->config_data.scenario_levels = calloc(
res->config_data.num_scenario_levels,
res->config_data.levels = NULL;
/* Initialize the ResCon's data */
- res->rescon.init_level = INIT_VALUE;
- res->rescon.prev_level = INIT_VALUE;
- res->rescon.min_level = INIT_VALUE;
- res->rescon.max_level = INIT_VALUE;
- res->rescon.init_scenario_level = INIT_VALUE;
- res->rescon.overridable = 1;
+ ret = pass_rescon_prepare(res);
+ if (ret < 0)
+ return ret;
/* Initialize the CPUHP's data */
cpuhp->pass_cpu_threshold = 0;
#define MIN_FAULT_AROUND_BYTES 4096
#define MAX_FAULT_AROUND_BYTES 65536
+/**
+ * @brief Represent PASS_MODULE_RESCON (Resource Controller) module.
+ * It should be always enabled in order to control h/w resources.
+ */
+struct pass_rescon {
+ /** State of PASS_MODULE_RESCON */
+ enum pass_state state;
+
+ /** Representing whether this resource can be overridden or not */
+ int overridable;
+
+ /**
+ * Initial level when initializing h/w resource by resource controller.
+ * If value is -1, it is not initialized by parser.
+ */
+ int init_level;
+ /**
+ * Current level controlled by resource controller.
+ * If value is -1, it is not initialized by parser.
+ */
+ int curr_level;
+ /**
+ * Previous level controlled by resource controller.
+ * If value is -1, it is not initialized by parser.
+ */
+ int prev_level;
+ /**
+ * Available minimum level controlled by resource controller.
+ * If value is -1, it is not initialized by parser.
+ */
+ int min_level;
+ /**
+ * Available maximum level controlled by resource controller.
+ * If value is -1, it is not initialized by parser.
+ */
+ int max_level;
+
+ /**
+ * Initial level when initializing h/w resource by resource controller.
+ * If value is -1, it is not initialized by parser.
+ */
+ int init_scenario_level;
+
+ /** Ondemanded scenario list */
+ GList *scenario_level_list;
+ /** Mutex of ondemanded scenario list */
+ GMutex scenario_level_mutex;
+};
+
static void rescon_print_level(struct pass_resource *res,
struct pass_level *level)
{
static int rescon_update(struct pass_resource *res)
{
- struct pass_rescon *rescon = &res->rescon;
+ struct pass_rescon *rescon = res->rescon;
struct pass_level *levels = res->config_data.levels;
struct pass_level *scenario_levels = res->config_data.scenario_levels;
struct pass_level adjusted_level;
adjusted_level.charging_current_uA = MAX_INT;
/* Adjust with pass_level */
- if (res->rescon.curr_level >= 0)
+ if (rescon->curr_level >= 0)
rescon_adjust_level(&adjusted_level, &levels[rescon->curr_level]);
/* Adjust with scenario pass_level */
static void rescon_set_scenario_level(struct pass_resource *res,
int scenario_level)
{
- struct pass_rescon *rescon = &res->rescon;
+ struct pass_rescon *rescon = res->rescon;
if (scenario_level < 0 || !rescon->overridable)
return;
static void rescon_unset_scenario_level(struct pass_resource *res,
int scenario_level)
{
- struct pass_rescon *rescon = &res->rescon;
+ struct pass_rescon *rescon = res->rescon;
if (scenario_level < 0 || !rescon->overridable)
return;
if (new_level < 0)
return 0;
- if (new_level > res->rescon.max_level)
- new_level = res->rescon.max_level;
+ if (new_level > res->rescon->max_level)
+ new_level = res->rescon->max_level;
- if (new_level < res->rescon.min_level)
- new_level = res->rescon.min_level;
+ if (new_level < res->rescon->min_level)
+ new_level = res->rescon->min_level;
- if (new_level == res->rescon.curr_level)
+ if (new_level == res->rescon->curr_level)
return 0;
- res->rescon.prev_level = res->rescon.curr_level;
- res->rescon.curr_level = new_level;
+ res->rescon->prev_level = res->rescon->curr_level;
+ res->rescon->curr_level = new_level;
return 0;
};
if (new_level < 0)
return 0;
- if (new_level > res->rescon.max_level)
- new_level = res->rescon.max_level;
+ if (new_level > res->rescon->max_level)
+ new_level = res->rescon->max_level;
- if (new_level < res->rescon.min_level)
- new_level = res->rescon.min_level;
+ if (new_level < res->rescon->min_level)
+ new_level = res->rescon->min_level;
- if (new_level == res->rescon.curr_level)
+ if (new_level == res->rescon->curr_level)
return 0;
- res->rescon.prev_level = res->rescon.curr_level;
- res->rescon.curr_level = new_level;
+ res->rescon->prev_level = res->rescon->curr_level;
+ res->rescon->curr_level = new_level;
return rescon_update(res);
};
*/
int pass_rescon_set_overridable(struct pass_resource *res, int overridable)
{
- if (!res)
+ if (!res || !res->rescon || overridable < -1 || overridable >= INT_MAX)
+ return -EINVAL;
+
+ res->rescon->overridable = overridable;
+
+ return 0;
+}
+
+int pass_rescon_set_init_level(struct pass_resource *res, int level)
+{
+ if (!res || !res->rescon || level < 0 || level >= INT_MAX)
return -EINVAL;
- res->rescon.overridable = overridable;
+ res->rescon->init_level = level;
return 0;
}
+int pass_rescon_set_curr_level(struct pass_resource *res, int level)
+{
+ if (!res || !res->rescon || level < 0 || level >= INT_MAX)
+ return -EINVAL;
+
+ res->rescon->curr_level = level;
+
+ return 0;
+}
+
+int pass_rescon_set_prev_level(struct pass_resource *res, int level)
+{
+ if (!res || !res->rescon || level < 0 || level >= INT_MAX)
+ return -EINVAL;
+
+ res->rescon->prev_level = level;
+
+ return 0;
+}
+
+int pass_rescon_set_min_level(struct pass_resource *res, int level)
+{
+ if (!res || !res->rescon || level < 0 || level >= INT_MAX)
+ return -EINVAL;
+
+ res->rescon->min_level = level;
+
+ return 0;
+}
+
+int pass_rescon_set_max_level(struct pass_resource *res, int level)
+{
+ if (!res || !res->rescon || level < 0 || level >= INT_MAX)
+ return -EINVAL;
+
+ res->rescon->max_level = level;
+
+ return 0;
+}
+
+int pass_rescon_set_init_scenario_level(struct pass_resource *res, int level)
+{
+ if (!res || !res->rescon || level < 0 || level >= INT_MAX)
+ return -EINVAL;
+
+ res->rescon->init_scenario_level = level;
+
+ return 0;
+}
+
+int pass_rescon_get_init_level(struct pass_resource *res, int *level)
+{
+ return (!res || !res->rescon) ? -EINVAL : res->rescon->init_level;
+}
+
+int pass_rescon_get_curr_level(struct pass_resource *res, int *level)
+{
+ return (!res || !res->rescon) ? -EINVAL : res->rescon->curr_level;
+}
+
+int pass_rescon_get_prev_level(struct pass_resource *res, int *level)
+{
+ return (!res || !res->rescon) ? -EINVAL : res->rescon->prev_level;
+}
+
+int pass_rescon_get_min_level(struct pass_resource *res, int *level)
+{
+ return (!res || !res->rescon) ? -EINVAL : res->rescon->min_level;
+}
+
+int pass_rescon_get_max_level(struct pass_resource *res, int *level)
+{
+ return (!res || !res->rescon) ? -EINVAL : res->rescon->max_level;
+}
+
/*
* @brief Deprecated function to support backward compatibility with sync.
* Set up the scenario pass_level by PASS_MODULE_PMQOS with data.
return rescon_update(res);
}
+int pass_rescon_prepare(struct pass_resource *res)
+{
+ if (!res || res->rescon != NULL)
+ return -EINVAL;
+
+ res->rescon = calloc(1, sizeof(struct pass_rescon));
+ if (!res->rescon)
+ return -ENOMEM;
+
+ res->rescon->init_level = INIT_VALUE;
+ res->rescon->prev_level = INIT_VALUE;
+ res->rescon->min_level = INIT_VALUE;
+ res->rescon->max_level = INIT_VALUE;
+ res->rescon->init_scenario_level = INIT_VALUE;
+ res->rescon->overridable = 1;
+ res->rescon->curr_level = INIT_VALUE;
+ res->rescon->prev_level = INIT_VALUE;
+
+ return 0;
+}
+
/**
* @brief Initialize PASS_MODULE_RESCON(Resource Controller) module.
* @param [in] res Instance of h/w resource
struct pass_rescon *rescon;
int ret;
- if (!res || res->rescon.state == PASS_ON)
+ if (!res || !res->rescon || res->rescon->state == PASS_ON)
return -1;
-
- rescon = &res->rescon;
+ rescon = res->rescon;
/* Initialize the variables of resource-controller */
- rescon->curr_level = -1;
- rescon->prev_level = -1;
-
if (!rescon->min_level)
rescon->min_level = 0;
res->config_data.default_min_level = rescon->min_level;
struct pass_rescon *rescon;
int ret;
- if (!res || res->rescon.state == PASS_OFF)
+ if (!res || !res->rescon || res->rescon->state == PASS_OFF)
return -1;
- rescon = &res->rescon;
+ rescon = res->rescon;
/* Restore the h/w resource by using the saved data */
ret = pass_hal_restore_initdata(res);
rescon->state = PASS_OFF;
+ free(rescon);
+ res->rescon = NULL;
+
return ret;
}
int pass_rescon_unset_scenario_level(struct pass_resource *res,
int scenario_level);
+/* Get and set the fields of struct pass_rescon */
+int pass_rescon_set_init_level(struct pass_resource *res, int level);
+int pass_rescon_set_curr_level(struct pass_resource *res, int level);
+int pass_rescon_set_prev_level(struct pass_resource *res, int level);
+int pass_rescon_set_min_level(struct pass_resource *res, int level);
+int pass_rescon_set_max_level(struct pass_resource *res, int level);
+int pass_rescon_set_init_scenario_level(struct pass_resource *res, int level);
int pass_rescon_set_overridable(struct pass_resource *res, int overridable);
+
+int pass_rescon_get_init_level(struct pass_resource *res, int *level);
+int pass_rescon_get_curr_level(struct pass_resource *res, int *level);
+int pass_rescon_get_prev_level(struct pass_resource *res, int *level);
+int pass_rescon_get_min_level(struct pass_resource *res, int *level);
+int pass_rescon_get_max_level(struct pass_resource *res, int *level);
+
+/* Init, exit and prepare the resource monitor module */
+int pass_rescon_prepare(struct pass_resource *res);
+int pass_rescon_init(struct pass_resource *res);
+int pass_rescon_exit(struct pass_resource *res);
+
/*
* Following APIs are deprecated. These functions are provided
* for keeping the compatibility with legacy feature.
#include "pass.h"
#include "pass-parser.h"
#include "pass-hal.h"
+#include "pass-rescon.h"
#define PASS_JSON_PATH "/hal/etc/pass/pass.json"
| PASS_MODULE_THERMAL,
};
-extern int pass_rescon_init(struct pass_resource *res);
-extern int pass_rescon_exit(struct pass_resource *res);
extern int pass_resmon_init(struct pass_resource *res);
extern int pass_resmon_exit(struct pass_resource *res);
extern int pass_cpuhp_init(struct pass_resource *res);
#define PASS_LEVEL_COND_MAX 3
+struct pass_rescon;
struct pass_resource;
struct pass_cpuhp_governor;
* PASS Module *
******************************************************/
-/**
- * @brief Represent PASS_MODULE_RESCON (Resource Controller) module.
- * It should be always enabled in order to control h/w resources.
- */
-struct pass_rescon {
- /** State of PASS_MODULE_RESCON */
- enum pass_state state;
-
- /** Representing whether this resource can be overridden or not */
- int overridable;
-
- /**
- * Initial level when initializing h/w resource by resource controller.
- * If value is -1, it is not initialized by parser.
- */
- int init_level;
- /**
- * Current level controlled by resource controller.
- * If value is -1, it is not initialized by parser.
- */
- int curr_level;
- /**
- * Previous level controlled by resource controller.
- * If value is -1, it is not initialized by parser.
- */
- int prev_level;
- /**
- * Available minimum level controlled by resource controller.
- * If value is -1, it is not initialized by parser.
- */
- int min_level;
- /**
- * Available maximum level controlled by resource controller.
- * If value is -1, it is not initialized by parser.
- */
- int max_level;
-
- /**
- * Initial level when initializing h/w resource by resource controller.
- * If value is -1, it is not initialized by parser.
- */
- int init_scenario_level;
-
- /** Ondemanded scenario list */
- GList *scenario_level_list;
- /** Mutex of ondemanded scenario list */
- GMutex scenario_level_mutex;
-};
/**
* @brief Represent PASS_MODULE_RESMON (Resource Monitor) module.
} hal;
/** Instance of PASS_MODULE_RESCON module */
- struct pass_rescon rescon;
+ struct pass_rescon *rescon;
/** Instance of PASS_MODULE_RESMON module */
struct pass_resmon resmon;
/** Instance of PASS_MODULE_CPUHP module */
PROJECT(pass C CXX)
SET(SRCS ${CMAKE_SOURCE_DIR}/src/pass/pass-hal.c
+ ${CMAKE_SOURCE_DIR}/src/pass/pass-rescon.c
${CMAKE_SOURCE_DIR}/src/pass/pass-parser.c
${CMAKE_SOURCE_DIR}/src/util/common.c
)
PROJECT(pass C CXX)
SET(SRCS ${CMAKE_SOURCE_DIR}/src/pass/pass-hal.c
+ ${CMAKE_SOURCE_DIR}/src/pass/pass-rescon.c
${CMAKE_SOURCE_DIR}/src/pass/pass-parser.c
${CMAKE_SOURCE_DIR}/src/util/common.c
${CMAKE_SOURCE_DIR}/src/util/privilege.c
SET(PASS_SRCS
${CMAKE_SOURCE_DIR}/src/util/common.c
${CMAKE_SOURCE_DIR}/src/pass/pass-hal.c
+ ${CMAKE_SOURCE_DIR}/src/pass/pass-rescon.c
${CMAKE_SOURCE_DIR}/src/pass/pass-parser.c
)