Lines Matching refs:ref
39 static unsigned long __percpu *percpu_count_ptr(struct percpu_ref *ref) in percpu_count_ptr() argument
42 (ref->percpu_count_ptr & ~__PERCPU_REF_ATOMIC_DEAD); in percpu_count_ptr()
59 int percpu_ref_init(struct percpu_ref *ref, percpu_ref_func_t *release, in percpu_ref_init() argument
66 ref->percpu_count_ptr = (unsigned long) in percpu_ref_init()
68 if (!ref->percpu_count_ptr) in percpu_ref_init()
71 ref->force_atomic = flags & PERCPU_REF_INIT_ATOMIC; in percpu_ref_init()
74 ref->percpu_count_ptr |= __PERCPU_REF_ATOMIC; in percpu_ref_init()
79 ref->percpu_count_ptr |= __PERCPU_REF_DEAD; in percpu_ref_init()
83 atomic_long_set(&ref->count, start_count); in percpu_ref_init()
85 ref->release = release; in percpu_ref_init()
86 ref->confirm_switch = NULL; in percpu_ref_init()
101 void percpu_ref_exit(struct percpu_ref *ref) in percpu_ref_exit() argument
103 unsigned long __percpu *percpu_count = percpu_count_ptr(ref); in percpu_ref_exit()
107 WARN_ON_ONCE(ref->confirm_switch); in percpu_ref_exit()
109 ref->percpu_count_ptr = __PERCPU_REF_ATOMIC_DEAD; in percpu_ref_exit()
116 struct percpu_ref *ref = container_of(rcu, struct percpu_ref, rcu); in percpu_ref_call_confirm_rcu() local
118 ref->confirm_switch(ref); in percpu_ref_call_confirm_rcu()
119 ref->confirm_switch = NULL; in percpu_ref_call_confirm_rcu()
123 percpu_ref_put(ref); in percpu_ref_call_confirm_rcu()
128 struct percpu_ref *ref = container_of(rcu, struct percpu_ref, rcu); in percpu_ref_switch_to_atomic_rcu() local
129 unsigned long __percpu *percpu_count = percpu_count_ptr(ref); in percpu_ref_switch_to_atomic_rcu()
137 atomic_long_read(&ref->count), (long)count); in percpu_ref_switch_to_atomic_rcu()
151 atomic_long_add((long)count - PERCPU_COUNT_BIAS, &ref->count); in percpu_ref_switch_to_atomic_rcu()
153 WARN_ONCE(atomic_long_read(&ref->count) <= 0, in percpu_ref_switch_to_atomic_rcu()
155 ref->release, atomic_long_read(&ref->count)); in percpu_ref_switch_to_atomic_rcu()
161 static void percpu_ref_noop_confirm_switch(struct percpu_ref *ref) in percpu_ref_noop_confirm_switch() argument
165 static void __percpu_ref_switch_to_atomic(struct percpu_ref *ref, in __percpu_ref_switch_to_atomic() argument
168 if (ref->percpu_count_ptr & __PERCPU_REF_ATOMIC) { in __percpu_ref_switch_to_atomic()
170 confirm_switch(ref); in __percpu_ref_switch_to_atomic()
175 ref->percpu_count_ptr |= __PERCPU_REF_ATOMIC; in __percpu_ref_switch_to_atomic()
181 ref->confirm_switch = confirm_switch ?: percpu_ref_noop_confirm_switch; in __percpu_ref_switch_to_atomic()
183 percpu_ref_get(ref); /* put after confirmation */ in __percpu_ref_switch_to_atomic()
184 call_rcu_sched(&ref->rcu, percpu_ref_switch_to_atomic_rcu); in __percpu_ref_switch_to_atomic()
187 static void __percpu_ref_switch_to_percpu(struct percpu_ref *ref) in __percpu_ref_switch_to_percpu() argument
189 unsigned long __percpu *percpu_count = percpu_count_ptr(ref); in __percpu_ref_switch_to_percpu()
194 if (!(ref->percpu_count_ptr & __PERCPU_REF_ATOMIC)) in __percpu_ref_switch_to_percpu()
197 atomic_long_add(PERCPU_COUNT_BIAS, &ref->count); in __percpu_ref_switch_to_percpu()
208 smp_store_release(&ref->percpu_count_ptr, in __percpu_ref_switch_to_percpu()
209 ref->percpu_count_ptr & ~__PERCPU_REF_ATOMIC); in __percpu_ref_switch_to_percpu()
212 static void __percpu_ref_switch_mode(struct percpu_ref *ref, in __percpu_ref_switch_mode() argument
222 wait_event_lock_irq(percpu_ref_switch_waitq, !ref->confirm_switch, in __percpu_ref_switch_mode()
225 if (ref->force_atomic || (ref->percpu_count_ptr & __PERCPU_REF_DEAD)) in __percpu_ref_switch_mode()
226 __percpu_ref_switch_to_atomic(ref, confirm_switch); in __percpu_ref_switch_mode()
228 __percpu_ref_switch_to_percpu(ref); in __percpu_ref_switch_mode()
251 void percpu_ref_switch_to_atomic(struct percpu_ref *ref, in percpu_ref_switch_to_atomic() argument
258 ref->force_atomic = true; in percpu_ref_switch_to_atomic()
259 __percpu_ref_switch_mode(ref, confirm_switch); in percpu_ref_switch_to_atomic()
273 void percpu_ref_switch_to_atomic_sync(struct percpu_ref *ref) in percpu_ref_switch_to_atomic_sync() argument
275 percpu_ref_switch_to_atomic(ref, NULL); in percpu_ref_switch_to_atomic_sync()
276 wait_event(percpu_ref_switch_waitq, !ref->confirm_switch); in percpu_ref_switch_to_atomic_sync()
298 void percpu_ref_switch_to_percpu(struct percpu_ref *ref) in percpu_ref_switch_to_percpu() argument
304 ref->force_atomic = false; in percpu_ref_switch_to_percpu()
305 __percpu_ref_switch_mode(ref, NULL); in percpu_ref_switch_to_percpu()
328 void percpu_ref_kill_and_confirm(struct percpu_ref *ref, in percpu_ref_kill_and_confirm() argument
335 WARN_ONCE(ref->percpu_count_ptr & __PERCPU_REF_DEAD, in percpu_ref_kill_and_confirm()
336 "%s called more than once on %pf!", __func__, ref->release); in percpu_ref_kill_and_confirm()
338 ref->percpu_count_ptr |= __PERCPU_REF_DEAD; in percpu_ref_kill_and_confirm()
339 __percpu_ref_switch_mode(ref, confirm_kill); in percpu_ref_kill_and_confirm()
340 percpu_ref_put(ref); in percpu_ref_kill_and_confirm()
357 void percpu_ref_reinit(struct percpu_ref *ref) in percpu_ref_reinit() argument
363 WARN_ON_ONCE(!percpu_ref_is_zero(ref)); in percpu_ref_reinit()
365 ref->percpu_count_ptr &= ~__PERCPU_REF_DEAD; in percpu_ref_reinit()
366 percpu_ref_get(ref); in percpu_ref_reinit()
367 __percpu_ref_switch_mode(ref, NULL); in percpu_ref_reinit()