mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-09 12:33:18 -04:00
bcachefs: Increase JOURNAL_BUF_NR
Increase journal pipelining. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
@@ -456,6 +456,7 @@ BCH_DEBUG_PARAMS_DEBUG()
|
||||
x(blocked_journal_low_on_space) \
|
||||
x(blocked_journal_low_on_pin) \
|
||||
x(blocked_journal_max_in_flight) \
|
||||
x(blocked_journal_max_open) \
|
||||
x(blocked_key_cache_flush) \
|
||||
x(blocked_allocate) \
|
||||
x(blocked_allocate_open_bucket) \
|
||||
|
||||
@@ -56,7 +56,12 @@ static void bch2_journal_buf_to_text(struct printbuf *out, struct journal *j, u6
|
||||
prt_printf(out, "seq:\t%llu\n", seq);
|
||||
printbuf_indent_add(out, 2);
|
||||
|
||||
prt_printf(out, "refcount:\t%u\n", journal_state_count(s, i));
|
||||
if (!buf->write_started)
|
||||
prt_printf(out, "refcount:\t%u\n", journal_state_count(s, i & JOURNAL_STATE_BUF_MASK));
|
||||
|
||||
struct closure *cl = &buf->io;
|
||||
int r = atomic_read(&cl->remaining);
|
||||
prt_printf(out, "io:\t%pS r %i\n", cl->fn, r & CLOSURE_REMAINING_MASK);
|
||||
|
||||
if (buf->data) {
|
||||
prt_printf(out, "size:\t");
|
||||
@@ -200,7 +205,8 @@ void bch2_journal_do_writes(struct journal *j)
|
||||
if (w->write_started)
|
||||
continue;
|
||||
|
||||
if (!journal_state_count(j->reservations, idx)) {
|
||||
if (!journal_state_seq_count(j, j->reservations, seq)) {
|
||||
j->seq_write_started = seq;
|
||||
w->write_started = true;
|
||||
closure_call(&w->io, bch2_journal_write, j->wq, NULL);
|
||||
}
|
||||
@@ -396,6 +402,9 @@ static int journal_entry_open(struct journal *j)
|
||||
if (nr_unwritten_journal_entries(j) == ARRAY_SIZE(j->buf))
|
||||
return JOURNAL_ERR_max_in_flight;
|
||||
|
||||
if (atomic64_read(&j->seq) - j->seq_write_started == JOURNAL_STATE_BUF_NR)
|
||||
return JOURNAL_ERR_max_open;
|
||||
|
||||
if (journal_cur_seq(j) >= JOURNAL_SEQ_MAX) {
|
||||
bch_err(c, "cannot start: journal seq overflow");
|
||||
if (bch2_fs_emergency_read_only_locked(c))
|
||||
@@ -477,7 +486,7 @@ static int journal_entry_open(struct journal *j)
|
||||
|
||||
new.idx++;
|
||||
BUG_ON(journal_state_count(new, new.idx));
|
||||
BUG_ON(new.idx != (journal_cur_seq(j) & JOURNAL_BUF_MASK));
|
||||
BUG_ON(new.idx != (journal_cur_seq(j) & JOURNAL_STATE_BUF_MASK));
|
||||
|
||||
journal_state_inc(&new);
|
||||
|
||||
@@ -638,6 +647,23 @@ static int __journal_res_get(struct journal *j, struct journal_res *res,
|
||||
count_event(c, journal_entry_full);
|
||||
}
|
||||
|
||||
if (ret == JOURNAL_ERR_max_open &&
|
||||
track_event_change(&c->times[BCH_TIME_blocked_journal_max_open], true) &&
|
||||
trace_journal_entry_full_enabled()) {
|
||||
struct printbuf buf = PRINTBUF;
|
||||
|
||||
bch2_printbuf_make_room(&buf, 4096);
|
||||
|
||||
spin_lock(&j->lock);
|
||||
prt_printf(&buf, "seq %llu\n", journal_cur_seq(j));
|
||||
bch2_journal_bufs_to_text(&buf, j);
|
||||
spin_unlock(&j->lock);
|
||||
|
||||
trace_journal_entry_full(c, buf.buf);
|
||||
printbuf_exit(&buf);
|
||||
count_event(c, journal_entry_full);
|
||||
}
|
||||
|
||||
/*
|
||||
* Journal is full - can't rely on reclaim from work item due to
|
||||
* freezing:
|
||||
@@ -1041,7 +1067,7 @@ static struct journal_buf *__bch2_next_write_buffer_flush_journal_buf(struct jou
|
||||
*blocked = true;
|
||||
}
|
||||
|
||||
ret = journal_state_count(s, idx) > open
|
||||
ret = journal_state_count(s, idx & JOURNAL_STATE_BUF_MASK) > open
|
||||
? ERR_PTR(-EAGAIN)
|
||||
: buf;
|
||||
break;
|
||||
@@ -1398,6 +1424,7 @@ int bch2_fs_journal_start(struct journal *j, u64 cur_seq)
|
||||
j->replay_journal_seq_end = cur_seq;
|
||||
j->last_seq_ondisk = last_seq;
|
||||
j->flushed_seq_ondisk = cur_seq - 1;
|
||||
j->seq_write_started = cur_seq - 1;
|
||||
j->seq_ondisk = cur_seq - 1;
|
||||
j->pin.front = last_seq;
|
||||
j->pin.back = cur_seq;
|
||||
|
||||
@@ -121,11 +121,6 @@ static inline void journal_wake(struct journal *j)
|
||||
closure_wake_up(&j->async_wait);
|
||||
}
|
||||
|
||||
static inline struct journal_buf *journal_cur_buf(struct journal *j)
|
||||
{
|
||||
return j->buf + j->reservations.idx;
|
||||
}
|
||||
|
||||
/* Sequence number of oldest dirty journal entry */
|
||||
|
||||
static inline u64 journal_last_seq(struct journal *j)
|
||||
@@ -143,6 +138,15 @@ static inline u64 journal_last_unwritten_seq(struct journal *j)
|
||||
return j->seq_ondisk + 1;
|
||||
}
|
||||
|
||||
static inline struct journal_buf *journal_cur_buf(struct journal *j)
|
||||
{
|
||||
unsigned idx = (journal_cur_seq(j) &
|
||||
JOURNAL_BUF_MASK &
|
||||
~JOURNAL_STATE_BUF_MASK) + j->reservations.idx;
|
||||
|
||||
return j->buf + idx;
|
||||
}
|
||||
|
||||
static inline int journal_state_count(union journal_res_state s, int idx)
|
||||
{
|
||||
switch (idx) {
|
||||
@@ -154,6 +158,15 @@ static inline int journal_state_count(union journal_res_state s, int idx)
|
||||
BUG();
|
||||
}
|
||||
|
||||
static inline int journal_state_seq_count(struct journal *j,
|
||||
union journal_res_state s, u64 seq)
|
||||
{
|
||||
if (journal_cur_seq(j) - seq <= JOURNAL_STATE_BUF_NR)
|
||||
return journal_state_count(s, seq & JOURNAL_STATE_BUF_MASK);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void journal_state_inc(union journal_res_state *s)
|
||||
{
|
||||
s->buf0_count += s->idx == 0;
|
||||
@@ -269,7 +282,7 @@ void bch2_journal_buf_put_final(struct journal *, u64);
|
||||
|
||||
static inline void __bch2_journal_buf_put(struct journal *j, u64 seq)
|
||||
{
|
||||
unsigned idx = seq & JOURNAL_BUF_MASK;
|
||||
unsigned idx = seq & JOURNAL_STATE_BUF_MASK;
|
||||
union journal_res_state s;
|
||||
|
||||
s = journal_state_buf_put(j, idx);
|
||||
@@ -279,7 +292,7 @@ static inline void __bch2_journal_buf_put(struct journal *j, u64 seq)
|
||||
|
||||
static inline void bch2_journal_buf_put(struct journal *j, u64 seq)
|
||||
{
|
||||
unsigned idx = seq & JOURNAL_BUF_MASK;
|
||||
unsigned idx = seq & JOURNAL_STATE_BUF_MASK;
|
||||
union journal_res_state s;
|
||||
|
||||
s = journal_state_buf_put(j, idx);
|
||||
@@ -365,9 +378,7 @@ static inline int journal_res_get_fast(struct journal *j,
|
||||
res->ref = true;
|
||||
res->offset = old.cur_entry_offset;
|
||||
res->seq = journal_cur_seq(j);
|
||||
res->seq -= (res->seq - old.idx) & JOURNAL_BUF_MASK;
|
||||
|
||||
EBUG_ON(res->seq != le64_to_cpu(j->buf[old.idx].data->seq));
|
||||
res->seq -= (res->seq - old.idx) & JOURNAL_STATE_BUF_MASK;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -394,6 +405,7 @@ static inline int bch2_journal_res_get(struct journal *j, struct journal_res *re
|
||||
(flags & JOURNAL_RES_GET_NONBLOCK) != 0,
|
||||
NULL, _THIS_IP_);
|
||||
EBUG_ON(!res->ref);
|
||||
BUG_ON(!res->seq);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,11 @@
|
||||
/* btree write buffer steals 8 bits for its own purposes: */
|
||||
#define JOURNAL_SEQ_MAX ((1ULL << 56) - 1)
|
||||
|
||||
#define JOURNAL_BUF_BITS 2
|
||||
#define JOURNAL_STATE_BUF_BITS 2
|
||||
#define JOURNAL_STATE_BUF_NR (1U << JOURNAL_STATE_BUF_BITS)
|
||||
#define JOURNAL_STATE_BUF_MASK (JOURNAL_STATE_BUF_NR - 1)
|
||||
|
||||
#define JOURNAL_BUF_BITS 4
|
||||
#define JOURNAL_BUF_NR (1U << JOURNAL_BUF_BITS)
|
||||
#define JOURNAL_BUF_MASK (JOURNAL_BUF_NR - 1)
|
||||
|
||||
@@ -153,6 +157,7 @@ enum journal_flags {
|
||||
x(retry) \
|
||||
x(blocked) \
|
||||
x(max_in_flight) \
|
||||
x(max_open) \
|
||||
x(journal_full) \
|
||||
x(journal_pin_full) \
|
||||
x(journal_stuck) \
|
||||
@@ -238,6 +243,7 @@ struct journal {
|
||||
/* Sequence number of most recent journal entry (last entry in @pin) */
|
||||
atomic64_t seq;
|
||||
|
||||
u64 seq_write_started;
|
||||
/* seq, last_seq from the most recent journal entry successfully written */
|
||||
u64 seq_ondisk;
|
||||
u64 flushed_seq_ondisk;
|
||||
|
||||
Reference in New Issue
Block a user