closures: Better memory barriers
atomic_(dec|sub)_return_release() are a thing now - use them. Also, delete the useless barrier in set_closure_fn(): it's redundant with the memory barrier in closure_put(0. Since closure_put() would now otherwise just have a release barrier, we also need a new barrier when the ref hits 0 - smp_acquire__after_ctrl_dep(). Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
cd063c8b9e
commit
2bce6368c4
2 changed files with 4 additions and 4 deletions
|
@ -233,8 +233,6 @@ static inline void set_closure_fn(struct closure *cl, closure_fn *fn,
|
|||
closure_set_ip(cl);
|
||||
cl->fn = fn;
|
||||
cl->wq = wq;
|
||||
/* between atomic_dec() in closure_put() */
|
||||
smp_mb__before_atomic();
|
||||
}
|
||||
|
||||
static inline void closure_queue(struct closure *cl)
|
||||
|
|
|
@ -21,6 +21,8 @@ static inline void closure_put_after_sub(struct closure *cl, int flags)
|
|||
BUG_ON(!r && (flags & ~CLOSURE_DESTRUCTOR));
|
||||
|
||||
if (!r) {
|
||||
smp_acquire__after_ctrl_dep();
|
||||
|
||||
if (cl->fn && !(flags & CLOSURE_DESTRUCTOR)) {
|
||||
atomic_set(&cl->remaining,
|
||||
CLOSURE_REMAINING_INITIALIZER);
|
||||
|
@ -43,7 +45,7 @@ static inline void closure_put_after_sub(struct closure *cl, int flags)
|
|||
/* For clearing flags with the same atomic op as a put */
|
||||
void closure_sub(struct closure *cl, int v)
|
||||
{
|
||||
closure_put_after_sub(cl, atomic_sub_return(v, &cl->remaining));
|
||||
closure_put_after_sub(cl, atomic_sub_return_release(v, &cl->remaining));
|
||||
}
|
||||
EXPORT_SYMBOL(closure_sub);
|
||||
|
||||
|
@ -52,7 +54,7 @@ EXPORT_SYMBOL(closure_sub);
|
|||
*/
|
||||
void closure_put(struct closure *cl)
|
||||
{
|
||||
closure_put_after_sub(cl, atomic_dec_return(&cl->remaining));
|
||||
closure_put_after_sub(cl, atomic_dec_return_release(&cl->remaining));
|
||||
}
|
||||
EXPORT_SYMBOL(closure_put);
|
||||
|
||||
|
|
Loading…
Reference in a new issue