diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-29 14:18:09 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-29 14:18:09 -0400 |
commit | f310642123e0d32d919c60ca3fab5acd130c4ba3 (patch) | |
tree | f3844152e2e8c0fdd01621a400f84c8a159252a0 /kernel/pm_qos_params.c | |
parent | ef1d57599dc904fdb31b8e9b5336350d21a1fde1 (diff) | |
parent | 5d4c47e0195b989f284907358bd5c268a44b91c7 (diff) |
Merge branch 'idle-release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-idle-2.6
* 'idle-release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-idle-2.6:
x86 idle: deprecate mwait_idle() and "idle=mwait" cmdline param
x86 idle: deprecate "no-hlt" cmdline param
x86 idle APM: deprecate CONFIG_APM_CPU_IDLE
x86 idle floppy: deprecate disable_hlt()
x86 idle: EXPORT_SYMBOL(default_idle, pm_idle) only when APM demands it
x86 idle: clarify AMD erratum 400 workaround
idle governor: Avoid lock acquisition to read pm_qos before entering idle
cpuidle: menu: fixed wrapping timers at 4.294 seconds
Diffstat (limited to 'kernel/pm_qos_params.c')
-rw-r--r-- | kernel/pm_qos_params.c | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c index fd8d1e035df9..6824ca7d4d0c 100644 --- a/kernel/pm_qos_params.c +++ b/kernel/pm_qos_params.c | |||
@@ -54,11 +54,17 @@ enum pm_qos_type { | |||
54 | PM_QOS_MIN /* return the smallest value */ | 54 | PM_QOS_MIN /* return the smallest value */ |
55 | }; | 55 | }; |
56 | 56 | ||
57 | /* | ||
58 | * Note: The lockless read path depends on the CPU accessing | ||
59 | * target_value atomically. Atomic access is only guaranteed on all CPU | ||
60 | * types linux supports for 32 bit quantites | ||
61 | */ | ||
57 | struct pm_qos_object { | 62 | struct pm_qos_object { |
58 | struct plist_head requests; | 63 | struct plist_head requests; |
59 | struct blocking_notifier_head *notifiers; | 64 | struct blocking_notifier_head *notifiers; |
60 | struct miscdevice pm_qos_power_miscdev; | 65 | struct miscdevice pm_qos_power_miscdev; |
61 | char *name; | 66 | char *name; |
67 | s32 target_value; /* Do not change to 64 bit */ | ||
62 | s32 default_value; | 68 | s32 default_value; |
63 | enum pm_qos_type type; | 69 | enum pm_qos_type type; |
64 | }; | 70 | }; |
@@ -71,7 +77,8 @@ static struct pm_qos_object cpu_dma_pm_qos = { | |||
71 | .requests = PLIST_HEAD_INIT(cpu_dma_pm_qos.requests, pm_qos_lock), | 77 | .requests = PLIST_HEAD_INIT(cpu_dma_pm_qos.requests, pm_qos_lock), |
72 | .notifiers = &cpu_dma_lat_notifier, | 78 | .notifiers = &cpu_dma_lat_notifier, |
73 | .name = "cpu_dma_latency", | 79 | .name = "cpu_dma_latency", |
74 | .default_value = 2000 * USEC_PER_SEC, | 80 | .target_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE, |
81 | .default_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE, | ||
75 | .type = PM_QOS_MIN, | 82 | .type = PM_QOS_MIN, |
76 | }; | 83 | }; |
77 | 84 | ||
@@ -80,7 +87,8 @@ static struct pm_qos_object network_lat_pm_qos = { | |||
80 | .requests = PLIST_HEAD_INIT(network_lat_pm_qos.requests, pm_qos_lock), | 87 | .requests = PLIST_HEAD_INIT(network_lat_pm_qos.requests, pm_qos_lock), |
81 | .notifiers = &network_lat_notifier, | 88 | .notifiers = &network_lat_notifier, |
82 | .name = "network_latency", | 89 | .name = "network_latency", |
83 | .default_value = 2000 * USEC_PER_SEC, | 90 | .target_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE, |
91 | .default_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE, | ||
84 | .type = PM_QOS_MIN | 92 | .type = PM_QOS_MIN |
85 | }; | 93 | }; |
86 | 94 | ||
@@ -90,7 +98,8 @@ static struct pm_qos_object network_throughput_pm_qos = { | |||
90 | .requests = PLIST_HEAD_INIT(network_throughput_pm_qos.requests, pm_qos_lock), | 98 | .requests = PLIST_HEAD_INIT(network_throughput_pm_qos.requests, pm_qos_lock), |
91 | .notifiers = &network_throughput_notifier, | 99 | .notifiers = &network_throughput_notifier, |
92 | .name = "network_throughput", | 100 | .name = "network_throughput", |
93 | .default_value = 0, | 101 | .target_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE, |
102 | .default_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE, | ||
94 | .type = PM_QOS_MAX, | 103 | .type = PM_QOS_MAX, |
95 | }; | 104 | }; |
96 | 105 | ||
@@ -136,6 +145,16 @@ static inline int pm_qos_get_value(struct pm_qos_object *o) | |||
136 | } | 145 | } |
137 | } | 146 | } |
138 | 147 | ||
148 | static inline s32 pm_qos_read_value(struct pm_qos_object *o) | ||
149 | { | ||
150 | return o->target_value; | ||
151 | } | ||
152 | |||
153 | static inline void pm_qos_set_value(struct pm_qos_object *o, s32 value) | ||
154 | { | ||
155 | o->target_value = value; | ||
156 | } | ||
157 | |||
139 | static void update_target(struct pm_qos_object *o, struct plist_node *node, | 158 | static void update_target(struct pm_qos_object *o, struct plist_node *node, |
140 | int del, int value) | 159 | int del, int value) |
141 | { | 160 | { |
@@ -160,6 +179,7 @@ static void update_target(struct pm_qos_object *o, struct plist_node *node, | |||
160 | plist_add(node, &o->requests); | 179 | plist_add(node, &o->requests); |
161 | } | 180 | } |
162 | curr_value = pm_qos_get_value(o); | 181 | curr_value = pm_qos_get_value(o); |
182 | pm_qos_set_value(o, curr_value); | ||
163 | spin_unlock_irqrestore(&pm_qos_lock, flags); | 183 | spin_unlock_irqrestore(&pm_qos_lock, flags); |
164 | 184 | ||
165 | if (prev_value != curr_value) | 185 | if (prev_value != curr_value) |
@@ -194,18 +214,11 @@ static int find_pm_qos_object_by_minor(int minor) | |||
194 | * pm_qos_request - returns current system wide qos expectation | 214 | * pm_qos_request - returns current system wide qos expectation |
195 | * @pm_qos_class: identification of which qos value is requested | 215 | * @pm_qos_class: identification of which qos value is requested |
196 | * | 216 | * |
197 | * This function returns the current target value in an atomic manner. | 217 | * This function returns the current target value. |
198 | */ | 218 | */ |
199 | int pm_qos_request(int pm_qos_class) | 219 | int pm_qos_request(int pm_qos_class) |
200 | { | 220 | { |
201 | unsigned long flags; | 221 | return pm_qos_read_value(pm_qos_array[pm_qos_class]); |
202 | int value; | ||
203 | |||
204 | spin_lock_irqsave(&pm_qos_lock, flags); | ||
205 | value = pm_qos_get_value(pm_qos_array[pm_qos_class]); | ||
206 | spin_unlock_irqrestore(&pm_qos_lock, flags); | ||
207 | |||
208 | return value; | ||
209 | } | 222 | } |
210 | EXPORT_SYMBOL_GPL(pm_qos_request); | 223 | EXPORT_SYMBOL_GPL(pm_qos_request); |
211 | 224 | ||