cpuidle: Split cpuidle_state structure and move per-cpu statistics fields

This is the first step towards global registration of cpuidle
states. The statistics used primarily by the governor are per-cpu
and have to be split from rest of the fields inside cpuidle_state,
which would be made global i.e. single copy. The driver_data field
is also per-cpu and moved.

Signed-off-by: Deepthi Dharwar <[email protected]>
Signed-off-by: Trinabh Gupta <[email protected]>
Tested-by: Jean Pihet <[email protected]>
Reviewed-by: Kevin Hilman <[email protected]>
Acked-by: Arjan van de Ven <[email protected]>
Acked-by: Kevin Hilman <[email protected]>
Signed-off-by: Len Brown <[email protected]>
This commit is contained in:
Deepthi Dharwar 2011-10-28 16:20:33 +05:30 • committed by Len Brown
commit 4202735e8a
7 changed files with 90 additions and 54 deletions

View file

@ -105,9 +105,9 @@ int cpuidle_idle_call(void)
/* This can be moved to within driver enter routine
* but that results in multiple copies of same code.
*/
dev->states[entered_state].time +=
dev->states_usage[entered_state].time +=
(unsigned long long)dev->last_residency;
dev->states[entered_state].usage++;
dev->states_usage[entered_state].usage++;
}
/* give the governor an opportunity to reflect on the outcome */
@ -186,8 +186,9 @@ static int poll_idle(struct cpuidle_device *dev, int index)
static void poll_idle_init(struct cpuidle_device *dev)
{
struct cpuidle_state *state = &dev->states[0];
struct cpuidle_state_usage *state_usage = &dev->states_usage[0];
cpuidle_set_statedata(state, NULL);
cpuidle_set_statedata(state_usage, NULL);
snprintf(state->name, CPUIDLE_NAME_LEN, "POLL");
snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE");
@ -235,8 +236,8 @@ int cpuidle_enable_device(struct cpuidle_device *dev)
goto fail_sysfs;
for (i = 0; i < dev->state_count; i++) {
dev->states[i].usage = 0;
dev->states[i].time = 0;
dev->states_usage[i].usage = 0;
dev->states_usage[i].time = 0;
}
dev->last_residency = 0;

View file

@ -216,7 +216,8 @@ static struct kobj_type ktype_cpuidle = {
struct cpuidle_state_attr {
struct attribute attr;
ssize_t (*show)(struct cpuidle_state *, char *);
ssize_t (*show)(struct cpuidle_state *, \
struct cpuidle_state_usage *, char *);
ssize_t (*store)(struct cpuidle_state *, const char *, size_t);
};
@ -224,19 +225,22 @@ struct cpuidle_state_attr {
static struct cpuidle_state_attr attr_##_name = __ATTR(_name, 0444, show, NULL)
#define define_show_state_function(_name) \
static ssize_t show_state_##_name(struct cpuidle_state *state, char *buf) \
static ssize_t show_state_##_name(struct cpuidle_state *state, \
struct cpuidle_state_usage *state_usage, char *buf) \
{ \
return sprintf(buf, "%u\n", state->_name);\
}
#define define_show_state_ull_function(_name) \
static ssize_t show_state_##_name(struct cpuidle_state *state, char *buf) \
static ssize_t show_state_##_name(struct cpuidle_state *state, \
struct cpuidle_state_usage *state_usage, char *buf) \
{ \
return sprintf(buf, "%llu\n", state->_name);\
return sprintf(buf, "%llu\n", state_usage->_name);\
}
#define define_show_state_str_function(_name) \
static ssize_t show_state_##_name(struct cpuidle_state *state, char *buf) \
static ssize_t show_state_##_name(struct cpuidle_state *state, \
struct cpuidle_state_usage *state_usage, char *buf) \
{ \
if (state->_name[0] == '\0')\
return sprintf(buf, "<null>\n");\
@ -269,16 +273,18 @@ static struct attribute *cpuidle_state_default_attrs[] = {
#define kobj_to_state_obj(k) container_of(k, struct cpuidle_state_kobj, kobj)
#define kobj_to_state(k) (kobj_to_state_obj(k)->state)
#define kobj_to_state_usage(k) (kobj_to_state_obj(k)->state_usage)
#define attr_to_stateattr(a) container_of(a, struct cpuidle_state_attr, attr)
static ssize_t cpuidle_state_show(struct kobject * kobj,
struct attribute * attr ,char * buf)
{
int ret = -EIO;
struct cpuidle_state *state = kobj_to_state(kobj);
struct cpuidle_state_usage *state_usage = kobj_to_state_usage(kobj);
struct cpuidle_state_attr * cattr = attr_to_stateattr(attr);
if (cattr->show)
ret = cattr->show(state, buf);
ret = cattr->show(state, state_usage, buf);
return ret;
}
@ -323,6 +329,7 @@ int cpuidle_add_state_sysfs(struct cpuidle_device *device)
if (!kobj)
goto error_state;
kobj->state = &device->states[i];
kobj->state_usage = &device->states_usage[i];
init_completion(&kobj->kobj_unregister);
ret = kobject_init_and_add(&kobj->kobj, &ktype_state_cpuidle, &device->kobj,