diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2022-03-16 14:45:26 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2022-03-16 17:19:53 -0400 |
commit | e9e6f337d1bfb5a2750b9e74c14c7b91c0055cad (patch) | |
tree | 73234ae097cb1401339459b17dbb01e694d5633d | |
parent | 7b6fc21abe08da38be7f3f48e5eefbf8a6b54775 (diff) |
fixup! bcachefs: Introduce a separate journal watermark for copygc
-rw-r--r-- | fs/bcachefs/btree_key_cache.c | 2 | ||||
-rw-r--r-- | fs/bcachefs/btree_update_interior.c | 4 | ||||
-rw-r--r-- | fs/bcachefs/btree_update_leaf.c | 2 | ||||
-rw-r--r-- | fs/bcachefs/journal.c | 49 | ||||
-rw-r--r-- | fs/bcachefs/journal.h | 13 | ||||
-rw-r--r-- | fs/bcachefs/journal_reclaim.c | 6 | ||||
-rw-r--r-- | fs/bcachefs/journal_types.h | 46 | ||||
-rw-r--r-- | fs/bcachefs/movinggc.c | 2 | ||||
-rw-r--r-- | fs/bcachefs/recovery.c | 2 |
9 files changed, 78 insertions, 48 deletions
diff --git a/fs/bcachefs/btree_key_cache.c b/fs/bcachefs/btree_key_cache.c index e48bbc6af33f..f5a942b6bbf7 100644 --- a/fs/bcachefs/btree_key_cache.c +++ b/fs/bcachefs/btree_key_cache.c @@ -421,7 +421,7 @@ static int btree_key_cache_flush_pos(struct btree_trans *trans, BTREE_INSERT_NOFAIL| BTREE_INSERT_USE_RESERVE| (ck->journal.seq == journal_last_seq(j) - ? JOURNAL_WATERMARK_RESERVED + ? JOURNAL_WATERMARK_reserved : 0)| commit_flags); if (ret) { diff --git a/fs/bcachefs/btree_update_interior.c b/fs/bcachefs/btree_update_interior.c index 832aed81cd39..c2232f8185c5 100644 --- a/fs/bcachefs/btree_update_interior.c +++ b/fs/bcachefs/btree_update_interior.c @@ -606,7 +606,7 @@ static void btree_update_nodes_written(struct btree_update *as) BTREE_INSERT_NOFAIL| BTREE_INSERT_NOCHECK_RW| BTREE_INSERT_JOURNAL_RECLAIM| - JOURNAL_WATERMARK_RESERVED, + JOURNAL_WATERMARK_reserved, btree_update_nodes_written_trans(&trans, as)); bch2_trans_exit(&trans); @@ -1956,7 +1956,7 @@ static int __bch2_btree_node_update_key(struct btree_trans *trans, BTREE_INSERT_NOCHECK_RW| BTREE_INSERT_USE_RESERVE| BTREE_INSERT_JOURNAL_RECLAIM| - JOURNAL_WATERMARK_RESERVED); + JOURNAL_WATERMARK_reserved); if (ret) goto err; diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c index d2354c8fb1a5..7b63277d9146 100644 --- a/fs/bcachefs/btree_update_leaf.c +++ b/fs/bcachefs/btree_update_leaf.c @@ -984,7 +984,7 @@ int bch2_trans_commit_error(struct btree_trans *trans, bch2_trans_unlock(trans); if ((trans->flags & BTREE_INSERT_JOURNAL_RECLAIM) && - !(trans->flags & JOURNAL_WATERMARK_RESERVED)) { + !(trans->flags & JOURNAL_WATERMARK_reserved)) { trans->restarted = true; ret = -EAGAIN; break; diff --git a/fs/bcachefs/journal.c b/fs/bcachefs/journal.c index a8d374144d53..6d91a2c8f6b5 100644 --- a/fs/bcachefs/journal.c +++ b/fs/bcachefs/journal.c @@ -20,6 +20,18 @@ #include <trace/events/bcachefs.h> +#define x(n) #n, +static const char * const bch2_journal_watermarks[] = { + JOURNAL_WATERMARKS() + NULL +}; + +static const char * const bch2_journal_errors[] = { + JOURNAL_ERRORS() + NULL +}; +#undef x + static inline bool journal_seq_unwritten(struct journal *j, u64 seq) { return seq > j->seq_ondisk; @@ -208,19 +220,19 @@ static int journal_entry_open(struct journal *j) BUG_ON(BCH_SB_CLEAN(c->disk_sb.sb)); if (j->blocked) - return cur_entry_blocked; + return JOURNAL_ERR_blocked; if (j->cur_entry_error) return j->cur_entry_error; if (bch2_journal_error(j)) - return cur_entry_insufficient_devices; /* -EROFS */ + return JOURNAL_ERR_insufficient_devices; /* -EROFS */ if (!fifo_free(&j->pin)) - return cur_entry_journal_pin_full; + return JOURNAL_ERR_journal_pin_full; if (nr_unwritten_journal_entries(j) == ARRAY_SIZE(j->buf) - 1) - return cur_entry_max_in_flight; + return JOURNAL_ERR_max_in_flight; BUG_ON(!j->cur_entry_sectors); @@ -239,7 +251,7 @@ static int journal_entry_open(struct journal *j) u64s = clamp_t(int, u64s, 0, JOURNAL_ENTRY_CLOSED_VAL - 1); if (u64s <= 0) - return cur_entry_journal_full; + return JOURNAL_ERR_journal_full; if (fifo_empty(&j->pin) && j->reclaim_thread) wake_up_process(j->reclaim_thread); @@ -360,7 +372,7 @@ retry: * Don't want to close current journal entry, just need to * invoke reclaim: */ - ret = cur_entry_journal_full; + ret = JOURNAL_ERR_journal_full; goto unlock; } @@ -378,10 +390,10 @@ retry: __journal_entry_close(j, JOURNAL_ENTRY_CLOSED_VAL); ret = journal_entry_open(j); - if (ret == cur_entry_max_in_flight) + if (ret == JOURNAL_ERR_max_in_flight) trace_journal_entry_full(c); unlock: - if ((ret && ret != cur_entry_insufficient_devices) && + if ((ret && ret != JOURNAL_ERR_insufficient_devices) && !j->res_get_blocked_start) { j->res_get_blocked_start = local_clock() ?: 1; trace_journal_full(c); @@ -393,14 +405,15 @@ unlock: if (!ret) goto retry; - if ((ret == cur_entry_journal_full || - ret == cur_entry_journal_pin_full) && + if ((ret == JOURNAL_ERR_journal_full || + ret == JOURNAL_ERR_journal_pin_full) && !can_discard && !nr_unwritten_journal_entries(j) && - (flags & JOURNAL_WATERMARK_RESERVED)) { + (flags & JOURNAL_WATERMARK_MASK) == JOURNAL_WATERMARK_reserved) { struct printbuf buf = PRINTBUF; - bch_err(c, "Journal stuck! Hava a pre-reservation but journal full"); + bch_err(c, "Journal stuck! Hava a pre-reservation but journal full (ret %s)", + bch2_journal_errors[ret]); bch2_journal_debug_to_text(&buf, j); bch_err(c, "%s", buf.buf); @@ -418,8 +431,8 @@ unlock: * Journal is full - can't rely on reclaim from work item due to * freezing: */ - if ((ret == cur_entry_journal_full || - ret == cur_entry_journal_pin_full) && + if ((ret == JOURNAL_ERR_journal_full || + ret == JOURNAL_ERR_journal_pin_full) && !(flags & JOURNAL_RES_GET_NONBLOCK)) { if (can_discard) { bch2_journal_do_discards(j); @@ -432,7 +445,7 @@ unlock: } } - return ret == cur_entry_insufficient_devices ? -EROFS : -EAGAIN; + return ret == JOURNAL_ERR_insufficient_devices ? -EROFS : -EAGAIN; } /* @@ -1226,14 +1239,14 @@ void __bch2_journal_debug_to_text(struct printbuf *out, struct journal *j) rcu_read_lock(); s = READ_ONCE(j->reservations); - pr_buf(out, "dirty journal entries:\t%llu\n", fifo_used(&j->pin)); + pr_buf(out, "dirty journal entries:\t%llu/%llu\n",fifo_used(&j->pin), j->pin.size); pr_buf(out, "seq:\t\t\t%llu\n", journal_cur_seq(j)); pr_buf(out, "seq_ondisk:\t\t%llu\n", j->seq_ondisk); pr_buf(out, "last_seq:\t\t%llu\n", journal_last_seq(j)); pr_buf(out, "last_seq_ondisk:\t%llu\n", j->last_seq_ondisk); pr_buf(out, "flushed_seq_ondisk:\t%llu\n", j->flushed_seq_ondisk); pr_buf(out, "prereserved:\t\t%u/%u\n", j->prereserved.reserved, j->prereserved.remaining); - pr_buf(out, "watermark:\t\t%u\n", j->watermark); + pr_buf(out, "watermark:\t\t%u\n", bch2_journal_watermarks[j->watermark]); pr_buf(out, "each entry reserved:\t%u\n", j->entry_u64s_reserved); pr_buf(out, "nr flush writes:\t%llu\n", j->nr_flush_writes); pr_buf(out, "nr noflush writes:\t%llu\n", j->nr_noflush_writes); @@ -1243,7 +1256,7 @@ void __bch2_journal_debug_to_text(struct printbuf *out, struct journal *j) pr_buf(out, "reclaim runs in:\t%u ms\n", time_after(j->next_reclaim, now) ? jiffies_to_msecs(j->next_reclaim - jiffies) : 0); pr_buf(out, "current entry sectors:\t%u\n", j->cur_entry_sectors); - pr_buf(out, "current entry error:\t%u\n", j->cur_entry_error); + pr_buf(out, "current entry error:\t%s\n", bch2_journal_errors[j->cur_entry_error]); pr_buf(out, "current entry:\t\t"); switch (s.cur_entry_offset) { diff --git a/fs/bcachefs/journal.h b/fs/bcachefs/journal.h index 15e3075c5583..e7321c327d9d 100644 --- a/fs/bcachefs/journal.h +++ b/fs/bcachefs/journal.h @@ -295,6 +295,7 @@ static inline void bch2_journal_res_put(struct journal *j, int bch2_journal_res_get_slowpath(struct journal *, struct journal_res *, unsigned); +/* First two bits for JOURNAL_WATERMARK: */ #define JOURNAL_RES_GET_NONBLOCK (1 << 2) #define JOURNAL_RES_GET_CHECK (1 << 3) @@ -373,17 +374,17 @@ out: static inline void journal_set_watermark(struct journal *j) { union journal_preres_state s = READ_ONCE(j->prereserved); - unsigned watermark = JOURNAL_WATERMARK_ANY; + unsigned watermark = JOURNAL_WATERMARK_any; if (fifo_free(&j->pin) < j->pin.size / 4) - watermark = max_t(unsigned, watermark, JOURNAL_WATERMARK_COPYGC); + watermark = max_t(unsigned, watermark, JOURNAL_WATERMARK_copygc); if (fifo_free(&j->pin) < j->pin.size / 8) - watermark = max_t(unsigned, watermark, JOURNAL_WATERMARK_RESERVED); + watermark = max_t(unsigned, watermark, JOURNAL_WATERMARK_reserved); if (s.reserved > s.remaining) - watermark = max_t(unsigned, watermark, JOURNAL_WATERMARK_COPYGC); + watermark = max_t(unsigned, watermark, JOURNAL_WATERMARK_copygc); if (!s.remaining) - watermark = max_t(unsigned, watermark, JOURNAL_WATERMARK_RESERVED); + watermark = max_t(unsigned, watermark, JOURNAL_WATERMARK_reserved); if (watermark == j->watermark) return; @@ -432,7 +433,7 @@ static inline int bch2_journal_preres_get_fast(struct journal *j, old.v = new.v = v; ret = 0; - if ((flags & JOURNAL_WATERMARK_RESERVED) || + if ((flags & JOURNAL_WATERMARK_reserved) || new.reserved + d < new.remaining) { new.reserved += d; ret = 1; diff --git a/fs/bcachefs/journal_reclaim.c b/fs/bcachefs/journal_reclaim.c index df28fe4a5757..6f1bad522949 100644 --- a/fs/bcachefs/journal_reclaim.c +++ b/fs/bcachefs/journal_reclaim.c @@ -195,7 +195,7 @@ void bch2_journal_space_available(struct journal *j) j->can_discard = can_discard; if (nr_online < c->opts.metadata_replicas_required) { - ret = cur_entry_insufficient_devices; + ret = JOURNAL_ERR_insufficient_devices; goto out; } @@ -217,9 +217,9 @@ void bch2_journal_space_available(struct journal *j) printbuf_exit(&buf); bch2_fatal_error(c); - ret = cur_entry_journal_stuck; + ret = JOURNAL_ERR_journal_stuck; } else if (!j->space[journal_space_discarded].next_entry) - ret = cur_entry_journal_full; + ret = JOURNAL_ERR_journal_full; if ((j->space[journal_space_clean_ondisk].next_entry < j->space[journal_space_clean_ondisk].total) && diff --git a/fs/bcachefs/journal_types.h b/fs/bcachefs/journal_types.h index 1609fdd670e3..a6cdb885ad41 100644 --- a/fs/bcachefs/journal_types.h +++ b/fs/bcachefs/journal_types.h @@ -147,6 +147,35 @@ enum { JOURNAL_MAY_SKIP_FLUSH, }; +#define JOURNAL_WATERMARKS() \ + x(any) \ + x(copygc) \ + x(reserved) + +enum journal_watermark { +#define x(n) JOURNAL_WATERMARK_##n, + JOURNAL_WATERMARKS() +#undef x +}; + +#define JOURNAL_WATERMARK_MASK 3 + +/* Reasons we may fail to get a journal reservation: */ +#define JOURNAL_ERRORS() \ + x(ok) \ + x(blocked) \ + x(max_in_flight) \ + x(journal_full) \ + x(journal_pin_full) \ + x(journal_stuck) \ + x(insufficient_devices) + +enum journal_errors { +#define x(n) JOURNAL_ERR_##n, + JOURNAL_ERRORS() +#undef x +}; + /* Embedded in struct bch_fs */ struct journal { /* Fastpath stuff up front: */ @@ -154,12 +183,7 @@ struct journal { unsigned long flags; union journal_res_state reservations; - enum journal_watermark { -#define JOURNAL_WATERMARK_MASK 3 - JOURNAL_WATERMARK_ANY, - JOURNAL_WATERMARK_COPYGC, - JOURNAL_WATERMARK_RESERVED, - } watermark; + enum journal_watermark watermark; /* Max size of current journal entry */ unsigned cur_entry_u64s; @@ -169,15 +193,7 @@ struct journal { * 0, or -ENOSPC if waiting on journal reclaim, or -EROFS if * insufficient devices: */ - enum { - cur_entry_ok, - cur_entry_blocked, - cur_entry_max_in_flight, - cur_entry_journal_full, - cur_entry_journal_pin_full, - cur_entry_journal_stuck, - cur_entry_insufficient_devices, - } cur_entry_error; + enum journal_errors cur_entry_error; union journal_preres_state prereserved; diff --git a/fs/bcachefs/movinggc.c b/fs/bcachefs/movinggc.c index 897244ff6570..4f32d38649c8 100644 --- a/fs/bcachefs/movinggc.c +++ b/fs/bcachefs/movinggc.c @@ -91,7 +91,7 @@ static enum data_cmd copygc_pred(struct bch_fs *c, void *arg, data_opts->target = io_opts->background_target; data_opts->nr_replicas = 1; data_opts->btree_insert_flags = BTREE_INSERT_USE_RESERVE| - JOURNAL_WATERMARK_COPYGC; + JOURNAL_WATERMARK_copygc; data_opts->rewrite_dev = p.ptr.dev; if (p.has_ec) diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c index e60af9b481d2..66492dde7930 100644 --- a/fs/bcachefs/recovery.c +++ b/fs/bcachefs/recovery.c @@ -564,7 +564,7 @@ static int bch2_journal_replay(struct bch_fs *c) BTREE_INSERT_LAZY_RW| BTREE_INSERT_NOFAIL| (!k->allocated - ? BTREE_INSERT_JOURNAL_REPLAY|JOURNAL_WATERMARK_RESERVED + ? BTREE_INSERT_JOURNAL_REPLAY|JOURNAL_WATERMARK_reserved : 0), bch2_journal_replay_key(&trans, k)); if (ret) { |