bcachefs: Add missing barriers before wake_up_bit()
authorKent Overstreet <kent.overstreet@linux.dev>
Mon, 5 May 2025 18:13:21 +0000 (14:13 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Mon, 5 May 2025 18:19:10 +0000 (14:19 -0400)
wake_up() doesn't require a barrier - but wake_up_bit() does.

This only affected non x86, and primarily lead to lost wakeups after
btree node reads.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_io.c
fs/bcachefs/buckets.h
fs/bcachefs/ec.h

index 5fd4a58..60782f3 100644 (file)
@@ -41,6 +41,7 @@ void bch2_btree_node_io_unlock(struct btree *b)
 
        clear_btree_node_write_in_flight_inner(b);
        clear_btree_node_write_in_flight(b);
+       smp_mb__after_atomic();
        wake_up_bit(&b->flags, BTREE_NODE_write_in_flight);
 }
 
@@ -1400,6 +1401,7 @@ start:
 
        printbuf_exit(&buf);
        clear_btree_node_read_in_flight(b);
+       smp_mb__after_atomic();
        wake_up_bit(&b->flags, BTREE_NODE_read_in_flight);
 }
 
@@ -1595,6 +1597,7 @@ fsck_err:
        printbuf_exit(&buf);
 
        clear_btree_node_read_in_flight(b);
+       smp_mb__after_atomic();
        wake_up_bit(&b->flags, BTREE_NODE_read_in_flight);
 }
 
@@ -1721,6 +1724,7 @@ void bch2_btree_node_read(struct btree_trans *trans, struct btree *b,
                set_btree_node_read_error(b);
                bch2_btree_lost_data(c, b->c.btree_id);
                clear_btree_node_read_in_flight(b);
+               smp_mb__after_atomic();
                wake_up_bit(&b->flags, BTREE_NODE_read_in_flight);
                printbuf_exit(&buf);
                return;
@@ -2061,8 +2065,10 @@ static void __btree_node_write_done(struct bch_fs *c, struct btree *b, u64 start
 
        if (new & (1U << BTREE_NODE_write_in_flight))
                __bch2_btree_node_write(c, b, BTREE_WRITE_ALREADY_STARTED|type);
-       else
+       else {
+               smp_mb__after_atomic();
                wake_up_bit(&b->flags, BTREE_NODE_write_in_flight);
+       }
 }
 
 static void btree_node_write_done(struct bch_fs *c, struct btree *b, u64 start_time)
@@ -2175,6 +2181,7 @@ static void btree_node_write_endio(struct bio *bio)
        }
 
        clear_btree_node_write_in_flight_inner(b);
+       smp_mb__after_atomic();
        wake_up_bit(&b->flags, BTREE_NODE_write_in_flight_inner);
        INIT_WORK(&wb->work, btree_node_write_work);
        queue_work(c->btree_io_complete_wq, &wb->work);
index 8d75b27..af1532d 100644 (file)
@@ -44,6 +44,7 @@ static inline void bucket_unlock(struct bucket *b)
        BUILD_BUG_ON(!((union ulong_byte_assert) { .ulong = 1UL << BUCKET_LOCK_BITNR }).byte);
 
        clear_bit_unlock(BUCKET_LOCK_BITNR, (void *) &b->lock);
+       smp_mb__after_atomic();
        wake_up_bit((void *) &b->lock, BUCKET_LOCK_BITNR);
 }
 
index 62d27e0..51893e1 100644 (file)
@@ -160,6 +160,7 @@ static inline void gc_stripe_unlock(struct gc_stripe *s)
        BUILD_BUG_ON(!((union ulong_byte_assert) { .ulong = 1UL << BUCKET_LOCK_BITNR }).byte);
 
        clear_bit_unlock(BUCKET_LOCK_BITNR, (void *) &s->lock);
+       smp_mb__after_atomic();
        wake_up_bit((void *) &s->lock, BUCKET_LOCK_BITNR);
 }