aboutsummaryrefslogtreecommitdiffstats
path: root/lib/percpu_counter.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /lib/percpu_counter.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'lib/percpu_counter.c')
-rw-r--r--lib/percpu_counter.c34
1 files changed, 16 insertions, 18 deletions
diff --git a/lib/percpu_counter.c b/lib/percpu_counter.c
index ba6085d9c74..28f2c33c6b5 100644
--- a/lib/percpu_counter.c
+++ b/lib/percpu_counter.c
@@ -10,10 +10,8 @@
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/debugobjects.h> 11#include <linux/debugobjects.h>
12 12
13#ifdef CONFIG_HOTPLUG_CPU
14static LIST_HEAD(percpu_counters); 13static LIST_HEAD(percpu_counters);
15static DEFINE_SPINLOCK(percpu_counters_lock); 14static DEFINE_MUTEX(percpu_counters_lock);
16#endif
17 15
18#ifdef CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER 16#ifdef CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER
19 17
@@ -61,13 +59,13 @@ void percpu_counter_set(struct percpu_counter *fbc, s64 amount)
61{ 59{
62 int cpu; 60 int cpu;
63 61
64 raw_spin_lock(&fbc->lock); 62 spin_lock(&fbc->lock);
65 for_each_possible_cpu(cpu) { 63 for_each_possible_cpu(cpu) {
66 s32 *pcount = per_cpu_ptr(fbc->counters, cpu); 64 s32 *pcount = per_cpu_ptr(fbc->counters, cpu);
67 *pcount = 0; 65 *pcount = 0;
68 } 66 }
69 fbc->count = amount; 67 fbc->count = amount;
70 raw_spin_unlock(&fbc->lock); 68 spin_unlock(&fbc->lock);
71} 69}
72EXPORT_SYMBOL(percpu_counter_set); 70EXPORT_SYMBOL(percpu_counter_set);
73 71
@@ -78,10 +76,10 @@ void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch)
78 preempt_disable(); 76 preempt_disable();
79 count = __this_cpu_read(*fbc->counters) + amount; 77 count = __this_cpu_read(*fbc->counters) + amount;
80 if (count >= batch || count <= -batch) { 78 if (count >= batch || count <= -batch) {
81 raw_spin_lock(&fbc->lock); 79 spin_lock(&fbc->lock);
82 fbc->count += count; 80 fbc->count += count;
83 __this_cpu_write(*fbc->counters, 0); 81 __this_cpu_write(*fbc->counters, 0);
84 raw_spin_unlock(&fbc->lock); 82 spin_unlock(&fbc->lock);
85 } else { 83 } else {
86 __this_cpu_write(*fbc->counters, count); 84 __this_cpu_write(*fbc->counters, count);
87 } 85 }
@@ -98,13 +96,13 @@ s64 __percpu_counter_sum(struct percpu_counter *fbc)
98 s64 ret; 96 s64 ret;
99 int cpu; 97 int cpu;
100 98
101 raw_spin_lock(&fbc->lock); 99 spin_lock(&fbc->lock);
102 ret = fbc->count; 100 ret = fbc->count;
103 for_each_online_cpu(cpu) { 101 for_each_online_cpu(cpu) {
104 s32 *pcount = per_cpu_ptr(fbc->counters, cpu); 102 s32 *pcount = per_cpu_ptr(fbc->counters, cpu);
105 ret += *pcount; 103 ret += *pcount;
106 } 104 }
107 raw_spin_unlock(&fbc->lock); 105 spin_unlock(&fbc->lock);
108 return ret; 106 return ret;
109} 107}
110EXPORT_SYMBOL(__percpu_counter_sum); 108EXPORT_SYMBOL(__percpu_counter_sum);
@@ -112,7 +110,7 @@ EXPORT_SYMBOL(__percpu_counter_sum);
112int __percpu_counter_init(struct percpu_counter *fbc, s64 amount, 110int __percpu_counter_init(struct percpu_counter *fbc, s64 amount,
113 struct lock_class_key *key) 111 struct lock_class_key *key)
114{ 112{
115 raw_spin_lock_init(&fbc->lock); 113 spin_lock_init(&fbc->lock);
116 lockdep_set_class(&fbc->lock, key); 114 lockdep_set_class(&fbc->lock, key);
117 fbc->count = amount; 115 fbc->count = amount;
118 fbc->counters = alloc_percpu(s32); 116 fbc->counters = alloc_percpu(s32);
@@ -123,9 +121,9 @@ int __percpu_counter_init(struct percpu_counter *fbc, s64 amount,
123 121
124#ifdef CONFIG_HOTPLUG_CPU 122#ifdef CONFIG_HOTPLUG_CPU
125 INIT_LIST_HEAD(&fbc->list); 123 INIT_LIST_HEAD(&fbc->list);
126 spin_lock(&percpu_counters_lock); 124 mutex_lock(&percpu_counters_lock);
127 list_add(&fbc->list, &percpu_counters); 125 list_add(&fbc->list, &percpu_counters);
128 spin_unlock(&percpu_counters_lock); 126 mutex_unlock(&percpu_counters_lock);
129#endif 127#endif
130 return 0; 128 return 0;
131} 129}
@@ -139,9 +137,9 @@ void percpu_counter_destroy(struct percpu_counter *fbc)
139 debug_percpu_counter_deactivate(fbc); 137 debug_percpu_counter_deactivate(fbc);
140 138
141#ifdef CONFIG_HOTPLUG_CPU 139#ifdef CONFIG_HOTPLUG_CPU
142 spin_lock(&percpu_counters_lock); 140 mutex_lock(&percpu_counters_lock);
143 list_del(&fbc->list); 141 list_del(&fbc->list);
144 spin_unlock(&percpu_counters_lock); 142 mutex_unlock(&percpu_counters_lock);
145#endif 143#endif
146 free_percpu(fbc->counters); 144 free_percpu(fbc->counters);
147 fbc->counters = NULL; 145 fbc->counters = NULL;
@@ -170,18 +168,18 @@ static int __cpuinit percpu_counter_hotcpu_callback(struct notifier_block *nb,
170 return NOTIFY_OK; 168 return NOTIFY_OK;
171 169
172 cpu = (unsigned long)hcpu; 170 cpu = (unsigned long)hcpu;
173 spin_lock(&percpu_counters_lock); 171 mutex_lock(&percpu_counters_lock);
174 list_for_each_entry(fbc, &percpu_counters, list) { 172 list_for_each_entry(fbc, &percpu_counters, list) {
175 s32 *pcount; 173 s32 *pcount;
176 unsigned long flags; 174 unsigned long flags;
177 175
178 raw_spin_lock_irqsave(&fbc->lock, flags); 176 spin_lock_irqsave(&fbc->lock, flags);
179 pcount = per_cpu_ptr(fbc->counters, cpu); 177 pcount = per_cpu_ptr(fbc->counters, cpu);
180 fbc->count += *pcount; 178 fbc->count += *pcount;
181 *pcount = 0; 179 *pcount = 0;
182 raw_spin_unlock_irqrestore(&fbc->lock, flags); 180 spin_unlock_irqrestore(&fbc->lock, flags);
183 } 181 }
184 spin_unlock(&percpu_counters_lock); 182 mutex_unlock(&percpu_counters_lock);
185#endif 183#endif
186 return NOTIFY_OK; 184 return NOTIFY_OK;
187} 185}