aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@suse.de>2010-07-05 16:53:06 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2010-07-18 20:00:34 -0400
commit82f682514a5df89ffb3890627eebf0897b7a84ec (patch)
tree27a3dba7a179102ac5bfdd5935679bd2abd3f70f
parent5f279845f9d684661563894d44729a0c706375b4 (diff)
pm_qos: Get rid of the allocation in pm_qos_add_request()
All current users of pm_qos_add_request() have the ability to supply the memory required by the pm_qos routines, so make them do this and eliminate the kmalloc() with pm_qos_add_request(). This has the double benefit of making the call never fail and allowing it to be called from atomic context. Signed-off-by: James Bottomley <James.Bottomley@suse.de> Signed-off-by: mark gross <markgross@thegnar.org> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
-rw-r--r--drivers/net/e1000e/netdev.c17
-rw-r--r--drivers/net/igbvf/netdev.c9
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c12
-rw-r--r--include/linux/netdevice.h2
-rw-r--r--include/linux/pm_qos_params.h13
-rw-r--r--include/sound/pcm.h2
-rw-r--r--kernel/pm_qos_params.c67
-rw-r--r--sound/core/pcm_native.c13
8 files changed, 74 insertions, 61 deletions
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 57a7e41da69e..9f13b660b801 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -2901,10 +2901,10 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
2901 * dropped transactions. 2901 * dropped transactions.
2902 */ 2902 */
2903 pm_qos_update_request( 2903 pm_qos_update_request(
2904 adapter->netdev->pm_qos_req, 55); 2904 &adapter->netdev->pm_qos_req, 55);
2905 } else { 2905 } else {
2906 pm_qos_update_request( 2906 pm_qos_update_request(
2907 adapter->netdev->pm_qos_req, 2907 &adapter->netdev->pm_qos_req,
2908 PM_QOS_DEFAULT_VALUE); 2908 PM_QOS_DEFAULT_VALUE);
2909 } 2909 }
2910 } 2910 }
@@ -3196,9 +3196,9 @@ int e1000e_up(struct e1000_adapter *adapter)
3196 3196
3197 /* DMA latency requirement to workaround early-receive/jumbo issue */ 3197 /* DMA latency requirement to workaround early-receive/jumbo issue */
3198 if (adapter->flags & FLAG_HAS_ERT) 3198 if (adapter->flags & FLAG_HAS_ERT)
3199 adapter->netdev->pm_qos_req = 3199 pm_qos_add_request(&adapter->netdev->pm_qos_req,
3200 pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY, 3200 PM_QOS_CPU_DMA_LATENCY,
3201 PM_QOS_DEFAULT_VALUE); 3201 PM_QOS_DEFAULT_VALUE);
3202 3202
3203 /* hardware has been reset, we need to reload some things */ 3203 /* hardware has been reset, we need to reload some things */
3204 e1000_configure(adapter); 3204 e1000_configure(adapter);
@@ -3263,11 +3263,8 @@ void e1000e_down(struct e1000_adapter *adapter)
3263 e1000_clean_tx_ring(adapter); 3263 e1000_clean_tx_ring(adapter);
3264 e1000_clean_rx_ring(adapter); 3264 e1000_clean_rx_ring(adapter);
3265 3265
3266 if (adapter->flags & FLAG_HAS_ERT) { 3266 if (adapter->flags & FLAG_HAS_ERT)
3267 pm_qos_remove_request( 3267 pm_qos_remove_request(&adapter->netdev->pm_qos_req);
3268 adapter->netdev->pm_qos_req);
3269 adapter->netdev->pm_qos_req = NULL;
3270 }
3271 3268
3272 /* 3269 /*
3273 * TODO: for power management, we could drop the link and 3270 * TODO: for power management, we could drop the link and
diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c
index 5e2b2a8c56c6..add6197d3bcb 100644
--- a/drivers/net/igbvf/netdev.c
+++ b/drivers/net/igbvf/netdev.c
@@ -48,7 +48,7 @@
48#define DRV_VERSION "1.0.0-k0" 48#define DRV_VERSION "1.0.0-k0"
49char igbvf_driver_name[] = "igbvf"; 49char igbvf_driver_name[] = "igbvf";
50const char igbvf_driver_version[] = DRV_VERSION; 50const char igbvf_driver_version[] = DRV_VERSION;
51struct pm_qos_request_list *igbvf_driver_pm_qos_req; 51static struct pm_qos_request_list igbvf_driver_pm_qos_req;
52static const char igbvf_driver_string[] = 52static const char igbvf_driver_string[] =
53 "Intel(R) Virtual Function Network Driver"; 53 "Intel(R) Virtual Function Network Driver";
54static const char igbvf_copyright[] = "Copyright (c) 2009 Intel Corporation."; 54static const char igbvf_copyright[] = "Copyright (c) 2009 Intel Corporation.";
@@ -2902,8 +2902,8 @@ static int __init igbvf_init_module(void)
2902 printk(KERN_INFO "%s\n", igbvf_copyright); 2902 printk(KERN_INFO "%s\n", igbvf_copyright);
2903 2903
2904 ret = pci_register_driver(&igbvf_driver); 2904 ret = pci_register_driver(&igbvf_driver);
2905 igbvf_driver_pm_qos_req = pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY, 2905 pm_qos_add_request(&igbvf_driver_pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
2906 PM_QOS_DEFAULT_VALUE); 2906 PM_QOS_DEFAULT_VALUE);
2907 2907
2908 return ret; 2908 return ret;
2909} 2909}
@@ -2918,8 +2918,7 @@ module_init(igbvf_init_module);
2918static void __exit igbvf_exit_module(void) 2918static void __exit igbvf_exit_module(void)
2919{ 2919{
2920 pci_unregister_driver(&igbvf_driver); 2920 pci_unregister_driver(&igbvf_driver);
2921 pm_qos_remove_request(igbvf_driver_pm_qos_req); 2921 pm_qos_remove_request(&igbvf_driver_pm_qos_req);
2922 igbvf_driver_pm_qos_req = NULL;
2923} 2922}
2924module_exit(igbvf_exit_module); 2923module_exit(igbvf_exit_module);
2925 2924
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 0bd4dfa59a8a..7f0d98b885bc 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -174,7 +174,7 @@ that only one external action is invoked at a time.
174#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver" 174#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver"
175#define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation" 175#define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation"
176 176
177struct pm_qos_request_list *ipw2100_pm_qos_req; 177struct pm_qos_request_list ipw2100_pm_qos_req;
178 178
179/* Debugging stuff */ 179/* Debugging stuff */
180#ifdef CONFIG_IPW2100_DEBUG 180#ifdef CONFIG_IPW2100_DEBUG
@@ -1741,7 +1741,7 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1741 /* the ipw2100 hardware really doesn't want power management delays 1741 /* the ipw2100 hardware really doesn't want power management delays
1742 * longer than 175usec 1742 * longer than 175usec
1743 */ 1743 */
1744 pm_qos_update_request(ipw2100_pm_qos_req, 175); 1744 pm_qos_update_request(&ipw2100_pm_qos_req, 175);
1745 1745
1746 /* If the interrupt is enabled, turn it off... */ 1746 /* If the interrupt is enabled, turn it off... */
1747 spin_lock_irqsave(&priv->low_lock, flags); 1747 spin_lock_irqsave(&priv->low_lock, flags);
@@ -1889,7 +1889,7 @@ static void ipw2100_down(struct ipw2100_priv *priv)
1889 ipw2100_disable_interrupts(priv); 1889 ipw2100_disable_interrupts(priv);
1890 spin_unlock_irqrestore(&priv->low_lock, flags); 1890 spin_unlock_irqrestore(&priv->low_lock, flags);
1891 1891
1892 pm_qos_update_request(ipw2100_pm_qos_req, PM_QOS_DEFAULT_VALUE); 1892 pm_qos_update_request(&ipw2100_pm_qos_req, PM_QOS_DEFAULT_VALUE);
1893 1893
1894 /* We have to signal any supplicant if we are disassociating */ 1894 /* We have to signal any supplicant if we are disassociating */
1895 if (associated) 1895 if (associated)
@@ -6669,8 +6669,8 @@ static int __init ipw2100_init(void)
6669 if (ret) 6669 if (ret)
6670 goto out; 6670 goto out;
6671 6671
6672 ipw2100_pm_qos_req = pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY, 6672 pm_qos_add_request(&ipw2100_pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
6673 PM_QOS_DEFAULT_VALUE); 6673 PM_QOS_DEFAULT_VALUE);
6674#ifdef CONFIG_IPW2100_DEBUG 6674#ifdef CONFIG_IPW2100_DEBUG
6675 ipw2100_debug_level = debug; 6675 ipw2100_debug_level = debug;
6676 ret = driver_create_file(&ipw2100_pci_driver.driver, 6676 ret = driver_create_file(&ipw2100_pci_driver.driver,
@@ -6692,7 +6692,7 @@ static void __exit ipw2100_exit(void)
6692 &driver_attr_debug_level); 6692 &driver_attr_debug_level);
6693#endif 6693#endif
6694 pci_unregister_driver(&ipw2100_pci_driver); 6694 pci_unregister_driver(&ipw2100_pci_driver);
6695 pm_qos_remove_request(ipw2100_pm_qos_req); 6695 pm_qos_remove_request(&ipw2100_pm_qos_req);
6696} 6696}
6697 6697
6698module_init(ipw2100_init); 6698module_init(ipw2100_init);
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index b21e4054c12c..2f22119b4b08 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -779,7 +779,7 @@ struct net_device {
779 */ 779 */
780 char name[IFNAMSIZ]; 780 char name[IFNAMSIZ];
781 781
782 struct pm_qos_request_list *pm_qos_req; 782 struct pm_qos_request_list pm_qos_req;
783 783
784 /* device name hash chain */ 784 /* device name hash chain */
785 struct hlist_node name_hlist; 785 struct hlist_node name_hlist;
diff --git a/include/linux/pm_qos_params.h b/include/linux/pm_qos_params.h
index 8ba440e5eb7f..77cbddb3784c 100644
--- a/include/linux/pm_qos_params.h
+++ b/include/linux/pm_qos_params.h
@@ -1,8 +1,10 @@
1#ifndef _LINUX_PM_QOS_PARAMS_H
2#define _LINUX_PM_QOS_PARAMS_H
1/* interface for the pm_qos_power infrastructure of the linux kernel. 3/* interface for the pm_qos_power infrastructure of the linux kernel.
2 * 4 *
3 * Mark Gross <mgross@linux.intel.com> 5 * Mark Gross <mgross@linux.intel.com>
4 */ 6 */
5#include <linux/list.h> 7#include <linux/plist.h>
6#include <linux/notifier.h> 8#include <linux/notifier.h>
7#include <linux/miscdevice.h> 9#include <linux/miscdevice.h>
8 10
@@ -14,9 +16,12 @@
14#define PM_QOS_NUM_CLASSES 4 16#define PM_QOS_NUM_CLASSES 4
15#define PM_QOS_DEFAULT_VALUE -1 17#define PM_QOS_DEFAULT_VALUE -1
16 18
17struct pm_qos_request_list; 19struct pm_qos_request_list {
20 struct plist_node list;
21 int pm_qos_class;
22};
18 23
19struct pm_qos_request_list *pm_qos_add_request(int pm_qos_class, s32 value); 24void pm_qos_add_request(struct pm_qos_request_list *l, int pm_qos_class, s32 value);
20void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req, 25void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
21 s32 new_value); 26 s32 new_value);
22void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req); 27void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req);
@@ -24,4 +29,6 @@ void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req);
24int pm_qos_request(int pm_qos_class); 29int pm_qos_request(int pm_qos_class);
25int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier); 30int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier);
26int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier); 31int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier);
32int pm_qos_request_active(struct pm_qos_request_list *req);
27 33
34#endif
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index dd76cdede64d..6e3a29732dc4 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -366,7 +366,7 @@ struct snd_pcm_substream {
366 int number; 366 int number;
367 char name[32]; /* substream name */ 367 char name[32]; /* substream name */
368 int stream; /* stream (direction) */ 368 int stream; /* stream (direction) */
369 struct pm_qos_request_list *latency_pm_qos_req; /* pm_qos request */ 369 struct pm_qos_request_list latency_pm_qos_req; /* pm_qos request */
370 size_t buffer_bytes_max; /* limit ring buffer size */ 370 size_t buffer_bytes_max; /* limit ring buffer size */
371 struct snd_dma_buffer dma_buffer; 371 struct snd_dma_buffer dma_buffer;
372 unsigned int dma_buf_id; 372 unsigned int dma_buf_id;
diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c
index db8e51d7f392..996a4dec5f96 100644
--- a/kernel/pm_qos_params.c
+++ b/kernel/pm_qos_params.c
@@ -30,7 +30,6 @@
30/*#define DEBUG*/ 30/*#define DEBUG*/
31 31
32#include <linux/pm_qos_params.h> 32#include <linux/pm_qos_params.h>
33#include <linux/plist.h>
34#include <linux/sched.h> 33#include <linux/sched.h>
35#include <linux/spinlock.h> 34#include <linux/spinlock.h>
36#include <linux/slab.h> 35#include <linux/slab.h>
@@ -49,11 +48,6 @@
49 * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock 48 * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock
50 * held, taken with _irqsave. One lock to rule them all 49 * held, taken with _irqsave. One lock to rule them all
51 */ 50 */
52struct pm_qos_request_list {
53 struct plist_node list;
54 int pm_qos_class;
55};
56
57enum pm_qos_type { 51enum pm_qos_type {
58 PM_QOS_MAX, /* return the largest value */ 52 PM_QOS_MAX, /* return the largest value */
59 PM_QOS_MIN /* return the smallest value */ 53 PM_QOS_MIN /* return the smallest value */
@@ -210,6 +204,12 @@ int pm_qos_request(int pm_qos_class)
210} 204}
211EXPORT_SYMBOL_GPL(pm_qos_request); 205EXPORT_SYMBOL_GPL(pm_qos_request);
212 206
207int pm_qos_request_active(struct pm_qos_request_list *req)
208{
209 return req->pm_qos_class != 0;
210}
211EXPORT_SYMBOL_GPL(pm_qos_request_active);
212
213/** 213/**
214 * pm_qos_add_request - inserts new qos request into the list 214 * pm_qos_add_request - inserts new qos request into the list
215 * @pm_qos_class: identifies which list of qos request to us 215 * @pm_qos_class: identifies which list of qos request to us
@@ -221,25 +221,23 @@ EXPORT_SYMBOL_GPL(pm_qos_request);
221 * element as a handle for use in updating and removal. Call needs to save 221 * element as a handle for use in updating and removal. Call needs to save
222 * this handle for later use. 222 * this handle for later use.
223 */ 223 */
224struct pm_qos_request_list *pm_qos_add_request(int pm_qos_class, s32 value) 224void pm_qos_add_request(struct pm_qos_request_list *dep,
225 int pm_qos_class, s32 value)
225{ 226{
226 struct pm_qos_request_list *dep; 227 struct pm_qos_object *o = pm_qos_array[pm_qos_class];
227 228 int new_value;
228 dep = kzalloc(sizeof(struct pm_qos_request_list), GFP_KERNEL);
229 if (dep) {
230 struct pm_qos_object *o = pm_qos_array[pm_qos_class];
231 int new_value;
232
233 if (value == PM_QOS_DEFAULT_VALUE)
234 new_value = o->default_value;
235 else
236 new_value = value;
237 plist_node_init(&dep->list, new_value);
238 dep->pm_qos_class = pm_qos_class;
239 update_target(o, &dep->list, 0, PM_QOS_DEFAULT_VALUE);
240 }
241 229
242 return dep; 230 if (pm_qos_request_active(dep)) {
231 WARN(1, KERN_ERR "pm_qos_add_request() called for already added request\n");
232 return;
233 }
234 if (value == PM_QOS_DEFAULT_VALUE)
235 new_value = o->default_value;
236 else
237 new_value = value;
238 plist_node_init(&dep->list, new_value);
239 dep->pm_qos_class = pm_qos_class;
240 update_target(o, &dep->list, 0, PM_QOS_DEFAULT_VALUE);
243} 241}
244EXPORT_SYMBOL_GPL(pm_qos_add_request); 242EXPORT_SYMBOL_GPL(pm_qos_add_request);
245 243
@@ -262,6 +260,11 @@ void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
262 if (!pm_qos_req) /*guard against callers passing in null */ 260 if (!pm_qos_req) /*guard against callers passing in null */
263 return; 261 return;
264 262
263 if (!pm_qos_request_active(pm_qos_req)) {
264 WARN(1, KERN_ERR "pm_qos_update_request() called for unknown object\n");
265 return;
266 }
267
265 o = pm_qos_array[pm_qos_req->pm_qos_class]; 268 o = pm_qos_array[pm_qos_req->pm_qos_class];
266 269
267 if (new_value == PM_QOS_DEFAULT_VALUE) 270 if (new_value == PM_QOS_DEFAULT_VALUE)
@@ -290,9 +293,14 @@ void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req)
290 return; 293 return;
291 /* silent return to keep pcm code cleaner */ 294 /* silent return to keep pcm code cleaner */
292 295
296 if (!pm_qos_request_active(pm_qos_req)) {
297 WARN(1, KERN_ERR "pm_qos_remove_request() called for unknown object\n");
298 return;
299 }
300
293 o = pm_qos_array[pm_qos_req->pm_qos_class]; 301 o = pm_qos_array[pm_qos_req->pm_qos_class];
294 update_target(o, &pm_qos_req->list, 1, PM_QOS_DEFAULT_VALUE); 302 update_target(o, &pm_qos_req->list, 1, PM_QOS_DEFAULT_VALUE);
295 kfree(pm_qos_req); 303 memset(pm_qos_req, 0, sizeof(*pm_qos_req));
296} 304}
297EXPORT_SYMBOL_GPL(pm_qos_remove_request); 305EXPORT_SYMBOL_GPL(pm_qos_remove_request);
298 306
@@ -340,8 +348,12 @@ static int pm_qos_power_open(struct inode *inode, struct file *filp)
340 348
341 pm_qos_class = find_pm_qos_object_by_minor(iminor(inode)); 349 pm_qos_class = find_pm_qos_object_by_minor(iminor(inode));
342 if (pm_qos_class >= 0) { 350 if (pm_qos_class >= 0) {
343 filp->private_data = (void *) pm_qos_add_request(pm_qos_class, 351 struct pm_qos_request_list *req = kzalloc(GFP_KERNEL, sizeof(*req));
344 PM_QOS_DEFAULT_VALUE); 352 if (!req)
353 return -ENOMEM;
354
355 pm_qos_add_request(req, pm_qos_class, PM_QOS_DEFAULT_VALUE);
356 filp->private_data = req;
345 357
346 if (filp->private_data) 358 if (filp->private_data)
347 return 0; 359 return 0;
@@ -353,8 +365,9 @@ static int pm_qos_power_release(struct inode *inode, struct file *filp)
353{ 365{
354 struct pm_qos_request_list *req; 366 struct pm_qos_request_list *req;
355 367
356 req = (struct pm_qos_request_list *)filp->private_data; 368 req = filp->private_data;
357 pm_qos_remove_request(req); 369 pm_qos_remove_request(req);
370 kfree(req);
358 371
359 return 0; 372 return 0;
360} 373}
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 303ac04ff6e4..a3b2a6479246 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -451,13 +451,11 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
451 snd_pcm_timer_resolution_change(substream); 451 snd_pcm_timer_resolution_change(substream);
452 runtime->status->state = SNDRV_PCM_STATE_SETUP; 452 runtime->status->state = SNDRV_PCM_STATE_SETUP;
453 453
454 if (substream->latency_pm_qos_req) { 454 if (pm_qos_request_active(&substream->latency_pm_qos_req))
455 pm_qos_remove_request(substream->latency_pm_qos_req); 455 pm_qos_remove_request(&substream->latency_pm_qos_req);
456 substream->latency_pm_qos_req = NULL;
457 }
458 if ((usecs = period_to_usecs(runtime)) >= 0) 456 if ((usecs = period_to_usecs(runtime)) >= 0)
459 substream->latency_pm_qos_req = pm_qos_add_request( 457 pm_qos_add_request(&substream->latency_pm_qos_req,
460 PM_QOS_CPU_DMA_LATENCY, usecs); 458 PM_QOS_CPU_DMA_LATENCY, usecs);
461 return 0; 459 return 0;
462 _error: 460 _error:
463 /* hardware might be unuseable from this time, 461 /* hardware might be unuseable from this time,
@@ -512,8 +510,7 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
512 if (substream->ops->hw_free) 510 if (substream->ops->hw_free)
513 result = substream->ops->hw_free(substream); 511 result = substream->ops->hw_free(substream);
514 runtime->status->state = SNDRV_PCM_STATE_OPEN; 512 runtime->status->state = SNDRV_PCM_STATE_OPEN;
515 pm_qos_remove_request(substream->latency_pm_qos_req); 513 pm_qos_remove_request(&substream->latency_pm_qos_req);
516 substream->latency_pm_qos_req = NULL;
517 return result; 514 return result;
518} 515}
519 516