diff options
author | Takashi Iwai <tiwai@suse.de> | 2019-09-14 18:24:57 +0300 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2019-09-14 18:26:10 +0300 |
commit | d3f9990f1b48514b33342612b51fad238592d774 (patch) | |
tree | 9ad5ae81ba3e820e91a09e2675b7c98675bd809e /lib/percpu-refcount.c | |
parent | e1a00b5b253a4f97216b9a33199a863987075162 (diff) | |
parent | 7711fb7dac1ab77fd1b4d948f4647a569e4a1ae2 (diff) | |
download | linux-d3f9990f1b48514b33342612b51fad238592d774.tar.xz |
Merge branch 'for-next' into for-linus
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'lib/percpu-refcount.c')
-rw-r--r-- | lib/percpu-refcount.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/lib/percpu-refcount.c b/lib/percpu-refcount.c index 071a76c7bac0..4f6c6ebbbbde 100644 --- a/lib/percpu-refcount.c +++ b/lib/percpu-refcount.c @@ -70,11 +70,14 @@ int percpu_ref_init(struct percpu_ref *ref, percpu_ref_func_t *release, return -ENOMEM; ref->force_atomic = flags & PERCPU_REF_INIT_ATOMIC; + ref->allow_reinit = flags & PERCPU_REF_ALLOW_REINIT; - if (flags & (PERCPU_REF_INIT_ATOMIC | PERCPU_REF_INIT_DEAD)) + if (flags & (PERCPU_REF_INIT_ATOMIC | PERCPU_REF_INIT_DEAD)) { ref->percpu_count_ptr |= __PERCPU_REF_ATOMIC; - else + ref->allow_reinit = true; + } else { start_count += PERCPU_COUNT_BIAS; + } if (flags & PERCPU_REF_INIT_DEAD) ref->percpu_count_ptr |= __PERCPU_REF_DEAD; @@ -120,6 +123,9 @@ static void percpu_ref_call_confirm_rcu(struct rcu_head *rcu) ref->confirm_switch = NULL; wake_up_all(&percpu_ref_switch_waitq); + if (!ref->allow_reinit) + percpu_ref_exit(ref); + /* drop ref from percpu_ref_switch_to_atomic() */ percpu_ref_put(ref); } @@ -195,6 +201,9 @@ static void __percpu_ref_switch_to_percpu(struct percpu_ref *ref) if (!(ref->percpu_count_ptr & __PERCPU_REF_ATOMIC)) return; + if (WARN_ON_ONCE(!ref->allow_reinit)) + return; + atomic_long_add(PERCPU_COUNT_BIAS, &ref->count); /* |