bcachefs: Kill bch_write_op->btree_update_ready
authorKent Overstreet <kent.overstreet@linux.dev>
Sat, 11 Mar 2023 22:21:30 +0000 (17:21 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:57 +0000 (17:09 -0400)
This changes the write path to not add write ops to to the write_point's
list of pending work items until it's ready; this means we have to
change the lock protecting it to an irq-safe lock, but means
bch2_write_point_do_index_updates() no longer has to iterate over the
list, which is beneficial with the way the new BCH_WRITE_WAIT_FOR_EC
code works.

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

index 6bcc91e8ac96c6fc84806e5fde659d0bdd8ec2e9..6fd29966c1db53078458efbd9db995f52baa9fc1 100644 (file)
@@ -834,36 +834,30 @@ static void bch2_write_index(struct closure *cl)
        struct bch_write_op *op = container_of(cl, struct bch_write_op, cl);
        struct write_point *wp = op->wp;
        struct workqueue_struct *wq = index_update_wq(op);
+       unsigned long flags;
 
        if ((op->flags & BCH_WRITE_DONE) &&
            (op->flags & BCH_WRITE_MOVE))
                bch2_bio_free_pages_pool(op->c, &op->wbio.bio);
 
-       barrier();
-
-       /*
-        * We're not using wp->writes_lock here, so this is racey: that's ok,
-        * because this is just for diagnostic purposes, and we're running out
-        * of interrupt context here so if we were to take the log we'd have to
-        * switch to spin_lock_irq()/irqsave(), which is not free:
-        */
+       spin_lock_irqsave(&wp->writes_lock, flags);
        if (wp->state == WRITE_POINT_waiting_io)
                __wp_update_state(wp, WRITE_POINT_waiting_work);
+       list_add_tail(&op->wp_list, &wp->writes);
+       spin_unlock_irqrestore (&wp->writes_lock, flags);
 
-       op->btree_update_ready = true;
        queue_work(wq, &wp->index_update_work);
 }
 
 static inline void bch2_write_queue(struct bch_write_op *op, struct write_point *wp)
 {
-       op->btree_update_ready = false;
        op->wp = wp;
 
-       spin_lock(&wp->writes_lock);
-       list_add_tail(&op->wp_list, &wp->writes);
-       if (wp->state == WRITE_POINT_stopped)
+       if (wp->state == WRITE_POINT_stopped) {
+               spin_lock_irq(&wp->writes_lock);
                __wp_update_state(wp, WRITE_POINT_waiting_io);
-       spin_unlock(&wp->writes_lock);
+               spin_unlock_irq(&wp->writes_lock);
+       }
 }
 
 void bch2_write_point_do_index_updates(struct work_struct *work)
@@ -873,16 +867,12 @@ void bch2_write_point_do_index_updates(struct work_struct *work)
        struct bch_write_op *op;
 
        while (1) {
-               spin_lock(&wp->writes_lock);
-               list_for_each_entry(op, &wp->writes, wp_list)
-                       if (op->btree_update_ready) {
-                               list_del(&op->wp_list);
-                               goto unlock;
-                       }
-               op = NULL;
-unlock:
+               spin_lock_irq(&wp->writes_lock);
+               op = list_first_entry_or_null(&wp->writes, struct bch_write_op, wp_list);
+               if (op)
+                       list_del(&op->wp_list);
                wp_update_state(wp, op != NULL);
-               spin_unlock(&wp->writes_lock);
+               spin_unlock_irq(&wp->writes_lock);
 
                if (!op)
                        break;
@@ -1673,7 +1663,6 @@ static void __bch2_write(struct bch_write_op *op)
        }
 again:
        memset(&op->failed, 0, sizeof(op->failed));
-       op->btree_update_ready = false;
 
        do {
                struct bkey_i *key_to_write;
index 200af9e3e6b0cdf8f2c68993188d80cec3ac7b7b..4149291c0df6f153f8f7a147eed75487767efd18 100644 (file)
@@ -121,7 +121,7 @@ struct bch_write_op {
        unsigned                nr_replicas_required:4;
        unsigned                alloc_reserve:3;
        unsigned                incompressible:1;
-       unsigned                btree_update_ready:1;
+       unsigned                stripe_waited:1;
 
        struct bch_devs_list    devs_have;
        u16                     target;