diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/fork.c | 42 | ||||
| -rw-r--r-- | kernel/pm_qos_params.c | 37 |
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 | ||
| 487 | int 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 | |||
| 501 | static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) | 487 | static 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) | |||
| 559 | void __mmdrop(struct mm_struct *mm) | 536 | void __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 | ||
| 796 | fail_nocontext: | 770 | fail_nocontext: |
| 797 | free_cpumask_var(mm->cpu_vm_mask_var); | ||
| 798 | |||
| 799 | fail_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 | */ | ||
| 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 | ||
