Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

cpuidle: fix cpuidle time and usage overflow

cpuidle C-state sysfs node time and usage are very easy to overflow because
they are all of unsigned int type, time will overflow within about two hours,
usage will take longer time to overflow, but they are increasing for ever.

This patch will convert them to unsigned long long.

Signed-off-by: Yi Yang <yi.y.yang@intel.com>
Acked-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>

authored by

Yi Yang and committed by
Len Brown
8b78cf60 996520c1

+11 -5
+1 -1
drivers/cpuidle/cpuidle.c
··· 67 67 /* enter the state and update stats */ 68 68 dev->last_residency = target_state->enter(dev, target_state); 69 69 dev->last_state = target_state; 70 - target_state->time += dev->last_residency; 70 + target_state->time += (unsigned long long)dev->last_residency; 71 71 target_state->usage++; 72 72 73 73 /* give the governor an opportunity to reflect on the outcome */
+8 -2
drivers/cpuidle/sysfs.c
··· 218 218 return sprintf(buf, "%u\n", state->_name);\ 219 219 } 220 220 221 + #define define_show_state_ull_function(_name) \ 222 + static ssize_t show_state_##_name(struct cpuidle_state *state, char *buf) \ 223 + { \ 224 + return sprintf(buf, "%llu\n", state->_name);\ 225 + } 226 + 221 227 #define define_show_state_str_function(_name) \ 222 228 static ssize_t show_state_##_name(struct cpuidle_state *state, char *buf) \ 223 229 { \ ··· 234 228 235 229 define_show_state_function(exit_latency) 236 230 define_show_state_function(power_usage) 237 - define_show_state_function(usage) 238 - define_show_state_function(time) 231 + define_show_state_ull_function(usage) 232 + define_show_state_ull_function(time) 239 233 define_show_state_str_function(name) 240 234 define_show_state_str_function(desc) 241 235
+2 -2
include/linux/cpuidle.h
··· 38 38 unsigned int power_usage; /* in mW */ 39 39 unsigned int target_residency; /* in US */ 40 40 41 - unsigned int usage; 42 - unsigned int time; /* in US */ 41 + unsigned long long usage; 42 + unsigned long long time; /* in US */ 43 43 44 44 int (*enter) (struct cpuidle_device *dev, 45 45 struct cpuidle_state *state);