]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - linux/closure.c
Disable pristine-tar option in gbp.conf, since there is no pristine-tar branch.
[bcachefs-tools-debian] / linux / closure.c
index b38ded00b9b052869e5ffab9873d0faffe955422..c16540552d61bc14121b034a9d6e302045ff0dc5 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/closure.h>
 #include <linux/debugfs.h>
 #include <linux/export.h>
+#include <linux/rcupdate.h>
 #include <linux/seq_file.h>
 #include <linux/sched/debug.h>
 
@@ -20,6 +21,10 @@ 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();
+
+               cl->closure_get_happened = false;
+
                if (cl->fn && !(flags & CLOSURE_DESTRUCTOR)) {
                        atomic_set(&cl->remaining,
                                   CLOSURE_REMAINING_INITIALIZER);
@@ -31,7 +36,7 @@ static inline void closure_put_after_sub(struct closure *cl, int flags)
                        closure_debug_destroy(cl);
 
                        if (destructor)
-                               destructor(cl);
+                               destructor(&cl->work);
 
                        if (parent)
                                closure_put(parent);
@@ -42,7 +47,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);
 
@@ -51,7 +56,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);
 
@@ -89,6 +94,7 @@ bool closure_wait(struct closure_waitlist *waitlist, struct closure *cl)
        if (atomic_read(&cl->remaining) & CLOSURE_WAITING)
                return false;
 
+       cl->closure_get_happened = true;
        closure_set_waiting(cl, _RET_IP_);
        atomic_add(CLOSURE_WAITING + 1, &cl->remaining);
        llist_add(&cl->list, &waitlist->list);
@@ -102,8 +108,9 @@ struct closure_syncer {
        int                     done;
 };
 
-static void closure_sync_fn(struct closure *cl)
+static CLOSURE_CALLBACK(closure_sync_fn)
 {
+       struct closure *cl = container_of(ws, struct closure, work);
        struct closure_syncer *s = cl->s;
        struct task_struct *p;