aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/fork.c42
-rw-r--r--kernel/pm_qos_params.c37
2 files changed, 35 insertions, 44 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index ca406d916713..0276c30401a0 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -484,20 +484,6 @@ static void mm_init_aio(struct mm_struct *mm)
484#endif 484#endif
485} 485}
486 486
487int mm_init_cpumask(struct mm_struct *mm, struct mm_struct *oldmm)
488{
489#ifdef CONFIG_CPUMASK_OFFSTACK
490 if (!alloc_cpumask_var(&mm->cpu_vm_mask_var, GFP_KERNEL))
491 return -ENOMEM;
492
493 if (oldmm)
494 cpumask_copy(mm_cpumask(mm), mm_cpumask(oldmm));
495 else
496 memset(mm_cpumask(mm), 0, cpumask_size());
497#endif
498 return 0;
499}
500
501static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) 487static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p)
502{ 488{
503 atomic_set(&mm->mm_users, 1); 489 atomic_set(&mm->mm_users, 1);
@@ -538,17 +524,8 @@ struct mm_struct * mm_alloc(void)
538 return NULL; 524 return NULL;
539 525
540 memset(mm, 0, sizeof(*mm)); 526 memset(mm, 0, sizeof(*mm));
541 mm = mm_init(mm, current); 527 mm_init_cpumask(mm);
542 if (!mm) 528 return mm_init(mm, current);
543 return NULL;
544
545 if (mm_init_cpumask(mm, NULL)) {
546 mm_free_pgd(mm);
547 free_mm(mm);
548 return NULL;
549 }
550
551 return mm;
552} 529}
553 530
554/* 531/*
@@ -559,7 +536,6 @@ struct mm_struct * mm_alloc(void)
559void __mmdrop(struct mm_struct *mm) 536void __mmdrop(struct mm_struct *mm)
560{ 537{
561 BUG_ON(mm == &init_mm); 538 BUG_ON(mm == &init_mm);
562 free_cpumask_var(mm->cpu_vm_mask_var);
563 mm_free_pgd(mm); 539 mm_free_pgd(mm);
564 destroy_context(mm); 540 destroy_context(mm);
565 mmu_notifier_mm_destroy(mm); 541 mmu_notifier_mm_destroy(mm);
@@ -753,6 +729,7 @@ struct mm_struct *dup_mm(struct task_struct *tsk)
753 goto fail_nomem; 729 goto fail_nomem;
754 730
755 memcpy(mm, oldmm, sizeof(*mm)); 731 memcpy(mm, oldmm, sizeof(*mm));
732 mm_init_cpumask(mm);
756 733
757 /* Initializing for Swap token stuff */ 734 /* Initializing for Swap token stuff */
758 mm->token_priority = 0; 735 mm->token_priority = 0;
@@ -765,9 +742,6 @@ struct mm_struct *dup_mm(struct task_struct *tsk)
765 if (!mm_init(mm, tsk)) 742 if (!mm_init(mm, tsk))
766 goto fail_nomem; 743 goto fail_nomem;
767 744
768 if (mm_init_cpumask(mm, oldmm))
769 goto fail_nocpumask;
770
771 if (init_new_context(tsk, mm)) 745 if (init_new_context(tsk, mm))
772 goto fail_nocontext; 746 goto fail_nocontext;
773 747
@@ -794,9 +768,6 @@ fail_nomem:
794 return NULL; 768 return NULL;
795 769
796fail_nocontext: 770fail_nocontext:
797 free_cpumask_var(mm->cpu_vm_mask_var);
798
799fail_nocpumask:
800 /* 771 /*
801 * If init_new_context() failed, we cannot use mmput() to free the mm 772 * If init_new_context() failed, we cannot use mmput() to free the mm
802 * because it calls destroy_context() 773 * because it calls destroy_context()
@@ -1591,6 +1562,13 @@ void __init proc_caches_init(void)
1591 fs_cachep = kmem_cache_create("fs_cache", 1562 fs_cachep = kmem_cache_create("fs_cache",
1592 sizeof(struct fs_struct), 0, 1563 sizeof(struct fs_struct), 0,
1593 SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); 1564 SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL);
1565 /*
1566 * FIXME! The "sizeof(struct mm_struct)" currently includes the
1567 * whole struct cpumask for the OFFSTACK case. We could change
1568 * this to *only* allocate as much of it as required by the
1569 * maximum number of CPU's we can ever have. The cpumask_allocation
1570 * is at the end of the structure, exactly for that reason.
1571 */
1594 mm_cachep = kmem_cache_create("mm_struct", 1572 mm_cachep = kmem_cache_create("mm_struct",
1595 sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN, 1573 sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN,
1596 SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); 1574 SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL);
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 */
57struct pm_qos_object { 62struct 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
148static inline s32 pm_qos_read_value(struct pm_qos_object *o)
149{
150 return o->target_value;
151}
152
153static inline void pm_qos_set_value(struct pm_qos_object *o, s32 value)
154{
155 o->target_value = value;
156}
157
139static void update_target(struct pm_qos_object *o, struct plist_node *node, 158static 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 */
199int pm_qos_request(int pm_qos_class) 219int 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}
210EXPORT_SYMBOL_GPL(pm_qos_request); 223EXPORT_SYMBOL_GPL(pm_qos_request);
211 224