Messages in this thread Patch in this message | | | Date | Thu, 15 Apr 2010 16:35:26 +0530 | From | Arun R Bharadwaj <> | Subject | [v12 PATCH 1/8]: cpuidle: cleanup cpuidle.h header file. |
| |
* Arun R Bharadwaj <arun@linux.vnet.ibm.com> [2010-04-15 16:30:46]:
This patch re-designs the data structures used in cpuidle infrastructure. Currently, we have a per-cpu device structure. Each cpu needs to register under cpuidle as a cpuidle_device. This is not desirable and hence the per-cpu registration is removed by this patch.
This patch introduces a cpuidle_subsystem structure. This needs a one-time registration to cpuidle. Also the current design has an array of the idle states for each of the CPUs. This is changed to have a global array of idle states. The statistics data like 'usage' and 'time' which were earlier part of the cpuidle_states structure is biforcated to form a new structure cpuidle_stats, which is per-cpu.
Signed-off-by: Arun R Bharadwaj <arun@linux.vnet.ibm.com> --- drivers/cpuidle/cpuidle.h | 6 +-- include/linux/cpuidle.h | 70 ++++++++++++++++++++-------------------------- 2 files changed, 33 insertions(+), 43 deletions(-)
Index: linux.trees.git/include/linux/cpuidle.h =================================================================== --- linux.trees.git.orig/include/linux/cpuidle.h +++ linux.trees.git/include/linux/cpuidle.h @@ -20,8 +20,7 @@ #define CPUIDLE_STATE_MAX 8 #define CPUIDLE_NAME_LEN 16 #define CPUIDLE_DESC_LEN 32 - -struct cpuidle_device; +#define CPUIDLE_MAX_CPUS 128 /**************************** @@ -38,11 +37,11 @@ struct cpuidle_state { unsigned int power_usage; /* in mW */ unsigned int target_residency; /* in US */ - unsigned long long usage; - unsigned long long time; /* in US */ + int state_index; + unsigned long long *usage; + unsigned long long *time; - int (*enter) (struct cpuidle_device *dev, - struct cpuidle_state *state); + int (*enter) (struct cpuidle_state *state); }; /* Idle State Flags */ @@ -76,30 +75,31 @@ cpuidle_set_statedata(struct cpuidle_sta } struct cpuidle_state_kobj { + int cpuid; struct cpuidle_state *state; struct completion kobj_unregister; struct kobject kobj; }; -struct cpuidle_device { - unsigned int registered:1; - unsigned int enabled:1; - unsigned int cpu; - - int last_residency; - int state_count; - struct cpuidle_state states[CPUIDLE_STATE_MAX]; +struct cpuidle_stats { + unsigned long long usage[CPUIDLE_STATE_MAX]; + unsigned long long time[CPUIDLE_STATE_MAX]; /* in US */ struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX]; - struct cpuidle_state *last_state; - - struct list_head device_list; struct kobject kobj; struct completion kobj_unregister; - void *governor_data; +}; + +struct cpuidle_subsystem { + unsigned int registered:1; + int state_count; + int last_residency[CPUIDLE_MAX_CPUS]; + struct cpuidle_state *last_state[CPUIDLE_MAX_CPUS]; + struct cpuidle_state states[CPUIDLE_STATE_MAX]; struct cpuidle_state *safe_state; }; -DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices); +extern struct cpuidle_subsystem cpuidle_subsys; +DECLARE_PER_CPU(struct cpuidle_stats, stats); /** * cpuidle_get_last_residency - retrieves the last state's residency time @@ -107,9 +107,9 @@ DECLARE_PER_CPU(struct cpuidle_device *, * * NOTE: this value is invalid if CPUIDLE_FLAG_TIME_VALID isn't set */ -static inline int cpuidle_get_last_residency(struct cpuidle_device *dev) +static inline int cpuidle_get_last_residency(int cpu) { - return dev->last_residency; + return cpuidle_subsys.last_residency[cpu]; } @@ -123,32 +123,23 @@ struct cpuidle_driver { }; #ifdef CONFIG_CPU_IDLE - extern int cpuidle_register_driver(struct cpuidle_driver *drv); extern void cpuidle_unregister_driver(struct cpuidle_driver *drv); -extern int cpuidle_register_device(struct cpuidle_device *dev); -extern void cpuidle_unregister_device(struct cpuidle_device *dev); +extern int cpuidle_register_subsystem(int state_count); +extern void cpuidle_unregister_subsystem(void); extern void cpuidle_pause_and_lock(void); extern void cpuidle_resume_and_unlock(void); -extern int cpuidle_enable_device(struct cpuidle_device *dev); -extern void cpuidle_disable_device(struct cpuidle_device *dev); - #else - static inline int cpuidle_register_driver(struct cpuidle_driver *drv) {return 0;} static inline void cpuidle_unregister_driver(struct cpuidle_driver *drv) { } -static inline int cpuidle_register_device(struct cpuidle_device *dev) +static inline int cpuidle_register_subsystem(int state_count) {return 0;} -static inline void cpuidle_unregister_device(struct cpuidle_device *dev) { } - +static inline void cpuidle_unregister_subsystem(void) +{ } static inline void cpuidle_pause_and_lock(void) { } static inline void cpuidle_resume_and_unlock(void) { } -static inline int cpuidle_enable_device(struct cpuidle_device *dev) -{return 0;} -static inline void cpuidle_disable_device(struct cpuidle_device *dev) { } - #endif /****************************** @@ -160,11 +151,11 @@ struct cpuidle_governor { struct list_head governor_list; unsigned int rating; - int (*enable) (struct cpuidle_device *dev); - void (*disable) (struct cpuidle_device *dev); + int (*enable) (int cpu); + void (*disable) (int cpu); - int (*select) (struct cpuidle_device *dev); - void (*reflect) (struct cpuidle_device *dev); + int (*select) (int cpu); + void (*reflect) (int cpu); struct module *owner; }; @@ -187,5 +178,6 @@ static inline void cpuidle_unregister_go #else #define CPUIDLE_DRIVER_STATE_START 0 #endif +extern void cpuidle_idle_call(void); #endif /* _LINUX_CPUIDLE_H */ Index: linux.trees.git/drivers/cpuidle/cpuidle.h =================================================================== --- linux.trees.git.orig/drivers/cpuidle/cpuidle.h +++ linux.trees.git/drivers/cpuidle/cpuidle.h @@ -11,12 +11,10 @@ extern struct cpuidle_governor *cpuidle_curr_governor; extern struct cpuidle_driver *cpuidle_curr_driver; extern struct list_head cpuidle_governors; -extern struct list_head cpuidle_detected_devices; extern struct mutex cpuidle_lock; extern spinlock_t cpuidle_driver_lock; /* idle loop */ -extern void cpuidle_install_idle_handler(void); extern void cpuidle_uninstall_idle_handler(void); /* governors */ @@ -25,8 +23,8 @@ extern int cpuidle_switch_governor(struc /* sysfs */ extern int cpuidle_add_class_sysfs(struct sysdev_class *cls); extern void cpuidle_remove_class_sysfs(struct sysdev_class *cls); -extern int cpuidle_add_state_sysfs(struct cpuidle_device *device); -extern void cpuidle_remove_state_sysfs(struct cpuidle_device *device); +extern int cpuidle_add_state_sysfs(int cpu); +extern void cpuidle_remove_state_sysfs(int cpu); extern int cpuidle_add_sysfs(struct sys_device *sysdev); extern void cpuidle_remove_sysfs(struct sys_device *sysdev);
| |