bcachefs: Put open_buckets in a hashtable
This is so that the copygc code doesn't have to refer to bucket_mark.owned_by_allocator - assisting in getting rid of the in memory bucket array. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
This commit is contained in:
committed by
Kent Overstreet
parent
abe19d458e
commit
9ddffaf83b
@ -43,6 +43,29 @@
|
||||
* reference _after_ doing the index update that makes its allocation reachable.
|
||||
*/
|
||||
|
||||
static void bch2_open_bucket_hash_add(struct bch_fs *c, struct open_bucket *ob)
|
||||
{
|
||||
open_bucket_idx_t idx = ob - c->open_buckets;
|
||||
open_bucket_idx_t *slot = open_bucket_hashslot(c, ob->dev, ob->bucket);
|
||||
|
||||
ob->hash = *slot;
|
||||
*slot = idx;
|
||||
}
|
||||
|
||||
static void bch2_open_bucket_hash_remove(struct bch_fs *c, struct open_bucket *ob)
|
||||
{
|
||||
open_bucket_idx_t idx = ob - c->open_buckets;
|
||||
open_bucket_idx_t *slot = open_bucket_hashslot(c, ob->dev, ob->bucket);
|
||||
|
||||
while (*slot != idx) {
|
||||
BUG_ON(!*slot);
|
||||
slot = &c->open_buckets[*slot].hash;
|
||||
}
|
||||
|
||||
*slot = ob->hash;
|
||||
ob->hash = 0;
|
||||
}
|
||||
|
||||
void __bch2_open_bucket_put(struct bch_fs *c, struct open_bucket *ob)
|
||||
{
|
||||
struct bch_dev *ca = bch_dev_bkey_exists(c, ob->dev);
|
||||
@ -63,6 +86,8 @@ void __bch2_open_bucket_put(struct bch_fs *c, struct open_bucket *ob)
|
||||
percpu_up_read(&c->mark_lock);
|
||||
|
||||
spin_lock(&c->freelist_lock);
|
||||
bch2_open_bucket_hash_remove(c, ob);
|
||||
|
||||
ob->freelist = c->open_buckets_freelist;
|
||||
c->open_buckets_freelist = ob - c->open_buckets;
|
||||
|
||||
@ -100,7 +125,6 @@ static struct open_bucket *bch2_open_bucket_alloc(struct bch_fs *c)
|
||||
return ob;
|
||||
}
|
||||
|
||||
|
||||
static void open_bucket_free_unused(struct bch_fs *c,
|
||||
struct write_point *wp,
|
||||
struct open_bucket *ob)
|
||||
@ -253,6 +277,9 @@ out:
|
||||
ob->bucket = b;
|
||||
spin_unlock(&ob->lock);
|
||||
|
||||
ca->nr_open_buckets++;
|
||||
bch2_open_bucket_hash_add(c, ob);
|
||||
|
||||
if (c->blocked_allocate_open_bucket) {
|
||||
bch2_time_stats_update(
|
||||
&c->times[BCH_TIME_blocked_allocate_open_bucket],
|
||||
@ -267,7 +294,6 @@ out:
|
||||
c->blocked_allocate = 0;
|
||||
}
|
||||
|
||||
ca->nr_open_buckets++;
|
||||
spin_unlock(&c->freelist_lock);
|
||||
|
||||
bch2_wake_allocator(ca);
|
||||
|
@ -91,6 +91,30 @@ static inline void bch2_open_bucket_get(struct bch_fs *c,
|
||||
}
|
||||
}
|
||||
|
||||
static inline open_bucket_idx_t *open_bucket_hashslot(struct bch_fs *c,
|
||||
unsigned dev, u64 bucket)
|
||||
{
|
||||
return c->open_buckets_hash +
|
||||
(jhash_3words(dev, bucket, bucket >> 32, 0) &
|
||||
(OPEN_BUCKETS_COUNT - 1));
|
||||
}
|
||||
|
||||
static inline bool bch2_bucket_is_open(struct bch_fs *c, unsigned dev, u64 bucket)
|
||||
{
|
||||
open_bucket_idx_t slot = *open_bucket_hashslot(c, dev, bucket);
|
||||
|
||||
while (slot) {
|
||||
struct open_bucket *ob = &c->open_buckets[slot];
|
||||
|
||||
if (ob->dev == dev && ob->bucket == bucket)
|
||||
return true;
|
||||
|
||||
slot = ob->hash;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int bch2_bucket_alloc_set(struct bch_fs *, struct open_buckets *,
|
||||
struct dev_stripe_state *, struct bch_devs_mask *,
|
||||
unsigned, unsigned *, bool *, enum alloc_reserve,
|
||||
|
@ -37,12 +37,16 @@ typedef FIFO(long) alloc_fifo;
|
||||
#define WRITE_POINT_HASH_NR 32
|
||||
#define WRITE_POINT_MAX 32
|
||||
|
||||
/*
|
||||
* 0 is never a valid open_bucket_idx_t:
|
||||
*/
|
||||
typedef u16 open_bucket_idx_t;
|
||||
|
||||
struct open_bucket {
|
||||
spinlock_t lock;
|
||||
atomic_t pin;
|
||||
open_bucket_idx_t freelist;
|
||||
open_bucket_idx_t hash;
|
||||
|
||||
/*
|
||||
* When an open bucket has an ec_stripe attached, this is the index of
|
||||
|
@ -756,10 +756,12 @@ struct bch_fs {
|
||||
struct closure_waitlist freelist_wait;
|
||||
u64 blocked_allocate;
|
||||
u64 blocked_allocate_open_bucket;
|
||||
|
||||
open_bucket_idx_t open_buckets_freelist;
|
||||
open_bucket_idx_t open_buckets_nr_free;
|
||||
struct closure_waitlist open_buckets_wait;
|
||||
struct open_bucket open_buckets[OPEN_BUCKETS_COUNT];
|
||||
open_bucket_idx_t open_buckets_hash[OPEN_BUCKETS_COUNT];
|
||||
|
||||
struct write_point btree_write_point;
|
||||
struct write_point rebalance_write_point;
|
||||
|
Reference in New Issue
Block a user