Commit ae10fe01 authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: bucket_alloc_state

This refactoring puts our various allocation path counters into a
dedicated struct - the upcoming nocow patch is going to add another
counter.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 29cea6f4
...@@ -205,26 +205,24 @@ static struct open_bucket *__try_alloc_bucket(struct bch_fs *c, struct bch_dev * ...@@ -205,26 +205,24 @@ static struct open_bucket *__try_alloc_bucket(struct bch_fs *c, struct bch_dev *
u64 bucket, u64 bucket,
enum alloc_reserve reserve, enum alloc_reserve reserve,
struct bch_alloc_v4 *a, struct bch_alloc_v4 *a,
u64 *skipped_open, struct bucket_alloc_state *s,
u64 *skipped_need_journal_commit,
u64 *skipped_nouse,
struct closure *cl) struct closure *cl)
{ {
struct open_bucket *ob; struct open_bucket *ob;
if (unlikely(ca->buckets_nouse && test_bit(bucket, ca->buckets_nouse))) { if (unlikely(ca->buckets_nouse && test_bit(bucket, ca->buckets_nouse))) {
(*skipped_nouse)++; s->skipped_nouse++;
return NULL; return NULL;
} }
if (bch2_bucket_is_open(c, ca->dev_idx, bucket)) { if (bch2_bucket_is_open(c, ca->dev_idx, bucket)) {
(*skipped_open)++; s->skipped_open++;
return NULL; return NULL;
} }
if (bch2_bucket_needs_journal_commit(&c->buckets_waiting_for_journal, if (bch2_bucket_needs_journal_commit(&c->buckets_waiting_for_journal,
c->journal.flushed_seq_ondisk, ca->dev_idx, bucket)) { c->journal.flushed_seq_ondisk, ca->dev_idx, bucket)) {
(*skipped_need_journal_commit)++; s->skipped_need_journal_commit++;
return NULL; return NULL;
} }
...@@ -244,7 +242,7 @@ static struct open_bucket *__try_alloc_bucket(struct bch_fs *c, struct bch_dev * ...@@ -244,7 +242,7 @@ static struct open_bucket *__try_alloc_bucket(struct bch_fs *c, struct bch_dev *
/* Recheck under lock: */ /* Recheck under lock: */
if (bch2_bucket_is_open(c, ca->dev_idx, bucket)) { if (bch2_bucket_is_open(c, ca->dev_idx, bucket)) {
spin_unlock(&c->freelist_lock); spin_unlock(&c->freelist_lock);
(*skipped_open)++; s->skipped_open++;
return NULL; return NULL;
} }
...@@ -283,9 +281,7 @@ static struct open_bucket *__try_alloc_bucket(struct bch_fs *c, struct bch_dev * ...@@ -283,9 +281,7 @@ static struct open_bucket *__try_alloc_bucket(struct bch_fs *c, struct bch_dev *
static struct open_bucket *try_alloc_bucket(struct btree_trans *trans, struct bch_dev *ca, static struct open_bucket *try_alloc_bucket(struct btree_trans *trans, struct bch_dev *ca,
enum alloc_reserve reserve, u64 free_entry, enum alloc_reserve reserve, u64 free_entry,
u64 *skipped_open, struct bucket_alloc_state *s,
u64 *skipped_need_journal_commit,
u64 *skipped_nouse,
struct bkey_s_c freespace_k, struct bkey_s_c freespace_k,
struct closure *cl) struct closure *cl)
{ {
...@@ -343,11 +339,7 @@ static struct open_bucket *try_alloc_bucket(struct btree_trans *trans, struct bc ...@@ -343,11 +339,7 @@ static struct open_bucket *try_alloc_bucket(struct btree_trans *trans, struct bc
goto err; goto err;
} }
ob = __try_alloc_bucket(c, ca, b, reserve, &a, ob = __try_alloc_bucket(c, ca, b, reserve, &a, s, cl);
skipped_open,
skipped_need_journal_commit,
skipped_nouse,
cl);
if (!ob) if (!ob)
iter.path->preserve = false; iter.path->preserve = false;
err: err:
...@@ -393,10 +385,7 @@ static noinline struct open_bucket * ...@@ -393,10 +385,7 @@ static noinline struct open_bucket *
bch2_bucket_alloc_early(struct btree_trans *trans, bch2_bucket_alloc_early(struct btree_trans *trans,
struct bch_dev *ca, struct bch_dev *ca,
enum alloc_reserve reserve, enum alloc_reserve reserve,
u64 *buckets_seen, struct bucket_alloc_state *s,
u64 *skipped_open,
u64 *skipped_need_journal_commit,
u64 *skipped_nouse,
struct closure *cl) struct closure *cl)
{ {
struct btree_iter iter; struct btree_iter iter;
...@@ -422,13 +411,9 @@ bch2_bucket_alloc_early(struct btree_trans *trans, ...@@ -422,13 +411,9 @@ bch2_bucket_alloc_early(struct btree_trans *trans,
if (a.data_type != BCH_DATA_free) if (a.data_type != BCH_DATA_free)
continue; continue;
(*buckets_seen)++; s->buckets_seen++;
ob = __try_alloc_bucket(trans->c, ca, k.k->p.offset, reserve, &a, ob = __try_alloc_bucket(trans->c, ca, k.k->p.offset, reserve, &a, s, cl);
skipped_open,
skipped_need_journal_commit,
skipped_nouse,
cl);
if (ob) if (ob)
break; break;
} }
...@@ -447,10 +432,7 @@ bch2_bucket_alloc_early(struct btree_trans *trans, ...@@ -447,10 +432,7 @@ bch2_bucket_alloc_early(struct btree_trans *trans,
static struct open_bucket *bch2_bucket_alloc_freelist(struct btree_trans *trans, static struct open_bucket *bch2_bucket_alloc_freelist(struct btree_trans *trans,
struct bch_dev *ca, struct bch_dev *ca,
enum alloc_reserve reserve, enum alloc_reserve reserve,
u64 *buckets_seen, struct bucket_alloc_state *s,
u64 *skipped_open,
u64 *skipped_need_journal_commit,
u64 *skipped_nouse,
struct closure *cl) struct closure *cl)
{ {
struct btree_iter iter; struct btree_iter iter;
...@@ -476,14 +458,10 @@ static struct open_bucket *bch2_bucket_alloc_freelist(struct btree_trans *trans, ...@@ -476,14 +458,10 @@ static struct open_bucket *bch2_bucket_alloc_freelist(struct btree_trans *trans,
break; break;
} }
(*buckets_seen)++; s->buckets_seen++;
ob = try_alloc_bucket(trans, ca, reserve, ob = try_alloc_bucket(trans, ca, reserve,
alloc_cursor, alloc_cursor, s, k, cl);
skipped_open,
skipped_need_journal_commit,
skipped_nouse,
k, cl);
if (ob) { if (ob) {
iter.path->preserve = false; iter.path->preserve = false;
break; break;
...@@ -523,10 +501,7 @@ static struct open_bucket *bch2_bucket_alloc_trans(struct btree_trans *trans, ...@@ -523,10 +501,7 @@ static struct open_bucket *bch2_bucket_alloc_trans(struct btree_trans *trans,
struct open_bucket *ob = NULL; struct open_bucket *ob = NULL;
struct bch_dev_usage usage; struct bch_dev_usage usage;
u64 avail; u64 avail;
u64 buckets_seen = 0; struct bucket_alloc_state s = { 0 };
u64 skipped_open = 0;
u64 skipped_need_journal_commit = 0;
u64 skipped_nouse = 0;
bool waiting = false; bool waiting = false;
again: again:
usage = bch2_dev_usage_read(ca); usage = bch2_dev_usage_read(ca);
...@@ -565,20 +540,10 @@ static struct open_bucket *bch2_bucket_alloc_trans(struct btree_trans *trans, ...@@ -565,20 +540,10 @@ static struct open_bucket *bch2_bucket_alloc_trans(struct btree_trans *trans,
} }
ob = likely(ca->mi.freespace_initialized) ob = likely(ca->mi.freespace_initialized)
? bch2_bucket_alloc_freelist(trans, ca, reserve, ? bch2_bucket_alloc_freelist(trans, ca, reserve, &s, cl)
&buckets_seen, : bch2_bucket_alloc_early(trans, ca, reserve, &s, cl);
&skipped_open,
&skipped_need_journal_commit, if (s.skipped_need_journal_commit * 2 > avail)
&skipped_nouse,
cl)
: bch2_bucket_alloc_early(trans, ca, reserve,
&buckets_seen,
&skipped_open,
&skipped_need_journal_commit,
&skipped_nouse,
cl);
if (skipped_need_journal_commit * 2 > avail)
bch2_journal_flush_async(&c->journal, NULL); bch2_journal_flush_async(&c->journal, NULL);
err: err:
if (!ob) if (!ob)
...@@ -593,10 +558,7 @@ static struct open_bucket *bch2_bucket_alloc_trans(struct btree_trans *trans, ...@@ -593,10 +558,7 @@ static struct open_bucket *bch2_bucket_alloc_trans(struct btree_trans *trans,
avail, avail,
bch2_copygc_wait_amount(c), bch2_copygc_wait_amount(c),
c->copygc_wait - atomic64_read(&c->io_clock[WRITE].now), c->copygc_wait - atomic64_read(&c->io_clock[WRITE].now),
buckets_seen, &s,
skipped_open,
skipped_need_journal_commit,
skipped_nouse,
cl == NULL, cl == NULL,
""); "");
else else
...@@ -608,10 +570,7 @@ static struct open_bucket *bch2_bucket_alloc_trans(struct btree_trans *trans, ...@@ -608,10 +570,7 @@ static struct open_bucket *bch2_bucket_alloc_trans(struct btree_trans *trans,
avail, avail,
bch2_copygc_wait_amount(c), bch2_copygc_wait_amount(c),
c->copygc_wait - atomic64_read(&c->io_clock[WRITE].now), c->copygc_wait - atomic64_read(&c->io_clock[WRITE].now),
buckets_seen, &s,
skipped_open,
skipped_need_journal_commit,
skipped_nouse,
cl == NULL, cl == NULL,
bch2_err_str(PTR_ERR(ob))); bch2_err_str(PTR_ERR(ob)));
......
...@@ -8,6 +8,13 @@ ...@@ -8,6 +8,13 @@
#include "clock_types.h" #include "clock_types.h"
#include "fifo.h" #include "fifo.h"
struct bucket_alloc_state {
u64 buckets_seen;
u64 skipped_open;
u64 skipped_need_journal_commit;
u64 skipped_nouse;
};
struct ec_bucket_buf; struct ec_bucket_buf;
#define BCH_ALLOC_RESERVES() \ #define BCH_ALLOC_RESERVES() \
......
...@@ -518,15 +518,12 @@ DECLARE_EVENT_CLASS(bucket_alloc, ...@@ -518,15 +518,12 @@ DECLARE_EVENT_CLASS(bucket_alloc,
u64 avail, u64 avail,
u64 copygc_wait_amount, u64 copygc_wait_amount,
s64 copygc_waiting_for, s64 copygc_waiting_for,
u64 seen, struct bucket_alloc_state *s,
u64 open,
u64 need_journal_commit,
u64 nouse,
bool nonblocking, bool nonblocking,
const char *err), const char *err),
TP_ARGS(ca, alloc_reserve, user, bucket, free, avail, TP_ARGS(ca, alloc_reserve, user, bucket, free, avail,
copygc_wait_amount, copygc_waiting_for, copygc_wait_amount, copygc_waiting_for,
seen, open, need_journal_commit, nouse, nonblocking, err), s, nonblocking, err),
TP_STRUCT__entry( TP_STRUCT__entry(
__field(dev_t, dev ) __field(dev_t, dev )
...@@ -554,10 +551,10 @@ DECLARE_EVENT_CLASS(bucket_alloc, ...@@ -554,10 +551,10 @@ DECLARE_EVENT_CLASS(bucket_alloc,
__entry->avail = avail; __entry->avail = avail;
__entry->copygc_wait_amount = copygc_wait_amount; __entry->copygc_wait_amount = copygc_wait_amount;
__entry->copygc_waiting_for = copygc_waiting_for; __entry->copygc_waiting_for = copygc_waiting_for;
__entry->seen = seen; __entry->seen = s->buckets_seen;
__entry->open = open; __entry->open = s->skipped_open;
__entry->need_journal_commit = need_journal_commit; __entry->need_journal_commit = s->skipped_need_journal_commit;
__entry->nouse = nouse; __entry->nouse = s->skipped_nouse;
__entry->nonblocking = nonblocking; __entry->nonblocking = nonblocking;
strlcpy(__entry->err, err, sizeof(__entry->err)); strlcpy(__entry->err, err, sizeof(__entry->err));
), ),
...@@ -587,15 +584,12 @@ DEFINE_EVENT(bucket_alloc, bucket_alloc, ...@@ -587,15 +584,12 @@ DEFINE_EVENT(bucket_alloc, bucket_alloc,
u64 avail, u64 avail,
u64 copygc_wait_amount, u64 copygc_wait_amount,
s64 copygc_waiting_for, s64 copygc_waiting_for,
u64 seen, struct bucket_alloc_state *s,
u64 open,
u64 need_journal_commit,
u64 nouse,
bool nonblocking, bool nonblocking,
const char *err), const char *err),
TP_ARGS(ca, alloc_reserve, user, bucket, free, avail, TP_ARGS(ca, alloc_reserve, user, bucket, free, avail,
copygc_wait_amount, copygc_waiting_for, copygc_wait_amount, copygc_waiting_for,
seen, open, need_journal_commit, nouse, nonblocking, err) s, nonblocking, err)
); );
DEFINE_EVENT(bucket_alloc, bucket_alloc_fail, DEFINE_EVENT(bucket_alloc, bucket_alloc_fail,
...@@ -606,15 +600,12 @@ DEFINE_EVENT(bucket_alloc, bucket_alloc_fail, ...@@ -606,15 +600,12 @@ DEFINE_EVENT(bucket_alloc, bucket_alloc_fail,
u64 avail, u64 avail,
u64 copygc_wait_amount, u64 copygc_wait_amount,
s64 copygc_waiting_for, s64 copygc_waiting_for,
u64 seen, struct bucket_alloc_state *s,
u64 open,
u64 need_journal_commit,
u64 nouse,
bool nonblocking, bool nonblocking,
const char *err), const char *err),
TP_ARGS(ca, alloc_reserve, user, bucket, free, avail, TP_ARGS(ca, alloc_reserve, user, bucket, free, avail,
copygc_wait_amount, copygc_waiting_for, copygc_wait_amount, copygc_waiting_for,
seen, open, need_journal_commit, nouse, nonblocking, err) s, nonblocking, err)
); );
TRACE_EVENT(discard_buckets, TRACE_EVENT(discard_buckets,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment