Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

percpu_counter: make percpu_counters_lock irq-safe

percpu_counter is scheduled to grow @gfp support to allow atomic
initialization. This patch makes percpu_counters_lock irq-safe so
that it can be safely used from atomic contexts.

Signed-off-by: Tejun Heo <tj@kernel.org>

Tejun Heo ebd8fef3 1a4d7607

+10 -6
+10 -6
lib/percpu_counter.c
··· 115 115 int __percpu_counter_init(struct percpu_counter *fbc, s64 amount, 116 116 struct lock_class_key *key) 117 117 { 118 + unsigned long flags __maybe_unused; 119 + 118 120 raw_spin_lock_init(&fbc->lock); 119 121 lockdep_set_class(&fbc->lock, key); 120 122 fbc->count = amount; ··· 128 126 129 127 #ifdef CONFIG_HOTPLUG_CPU 130 128 INIT_LIST_HEAD(&fbc->list); 131 - spin_lock(&percpu_counters_lock); 129 + spin_lock_irqsave(&percpu_counters_lock, flags); 132 130 list_add(&fbc->list, &percpu_counters); 133 - spin_unlock(&percpu_counters_lock); 131 + spin_unlock_irqrestore(&percpu_counters_lock, flags); 134 132 #endif 135 133 return 0; 136 134 } ··· 138 136 139 137 void percpu_counter_destroy(struct percpu_counter *fbc) 140 138 { 139 + unsigned long flags __maybe_unused; 140 + 141 141 if (!fbc->counters) 142 142 return; 143 143 144 144 debug_percpu_counter_deactivate(fbc); 145 145 146 146 #ifdef CONFIG_HOTPLUG_CPU 147 - spin_lock(&percpu_counters_lock); 147 + spin_lock_irqsave(&percpu_counters_lock, flags); 148 148 list_del(&fbc->list); 149 - spin_unlock(&percpu_counters_lock); 149 + spin_unlock_irqrestore(&percpu_counters_lock, flags); 150 150 #endif 151 151 free_percpu(fbc->counters); 152 152 fbc->counters = NULL; ··· 177 173 return NOTIFY_OK; 178 174 179 175 cpu = (unsigned long)hcpu; 180 - spin_lock(&percpu_counters_lock); 176 + spin_lock_irq(&percpu_counters_lock); 181 177 list_for_each_entry(fbc, &percpu_counters, list) { 182 178 s32 *pcount; 183 179 unsigned long flags; ··· 188 184 *pcount = 0; 189 185 raw_spin_unlock_irqrestore(&fbc->lock, flags); 190 186 } 191 - spin_unlock(&percpu_counters_lock); 187 + spin_unlock_irq(&percpu_counters_lock); 192 188 #endif 193 189 return NOTIFY_OK; 194 190 }