mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 18:13:41 +02:00
bcachefs: Debug asserts for ca->ref
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
f295298b8c
commit
552aa54865
|
|
@ -537,7 +537,13 @@ struct io_count {
|
|||
|
||||
struct bch_dev {
|
||||
struct kobject kobj;
|
||||
#ifdef CONFIG_BCACHEFS_DEBUG
|
||||
atomic_long_t ref;
|
||||
bool dying;
|
||||
unsigned long last_put;
|
||||
#else
|
||||
struct percpu_ref ref;
|
||||
#endif
|
||||
struct completion ref_completion;
|
||||
struct percpu_ref io_ref;
|
||||
struct completion io_ref_completion;
|
||||
|
|
|
|||
|
|
@ -107,12 +107,25 @@ static inline struct bch_dev *__bch2_next_dev(struct bch_fs *c, struct bch_dev *
|
|||
|
||||
static inline void bch2_dev_get(struct bch_dev *ca)
|
||||
{
|
||||
#ifdef CONFIG_BCACHEFS_DEBUG
|
||||
BUG_ON(atomic_long_inc_return(&ca->ref) <= 1L);
|
||||
#else
|
||||
percpu_ref_get(&ca->ref);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void __bch2_dev_put(struct bch_dev *ca)
|
||||
{
|
||||
#ifdef CONFIG_BCACHEFS_DEBUG
|
||||
long r = atomic_long_dec_return(&ca->ref);
|
||||
if (r < (long) !ca->dying)
|
||||
panic("bch_dev->ref underflow, last put: %pS\n", (void *) ca->last_put);
|
||||
ca->last_put = _THIS_IP_;
|
||||
if (!r)
|
||||
complete(&ca->ref_completion);
|
||||
#else
|
||||
percpu_ref_put(&ca->ref);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void bch2_dev_put(struct bch_dev *ca)
|
||||
|
|
|
|||
|
|
@ -656,6 +656,7 @@ void bch2_fs_free(struct bch_fs *c)
|
|||
struct bch_dev *ca = rcu_dereference_protected(c->devs[i], true);
|
||||
|
||||
if (ca) {
|
||||
EBUG_ON(atomic_long_read(&ca->ref) != 1);
|
||||
bch2_free_super(&ca->disk_sb);
|
||||
bch2_dev_free(ca);
|
||||
}
|
||||
|
|
@ -1200,7 +1201,9 @@ static void bch2_dev_free(struct bch_dev *ca)
|
|||
bch2_time_stats_quantiles_exit(&ca->io_latency[READ]);
|
||||
|
||||
percpu_ref_exit(&ca->io_ref);
|
||||
#ifndef CONFIG_BCACHEFS_DEBUG
|
||||
percpu_ref_exit(&ca->ref);
|
||||
#endif
|
||||
kobject_put(&ca->kobj);
|
||||
}
|
||||
|
||||
|
|
@ -1227,12 +1230,14 @@ static void __bch2_dev_offline(struct bch_fs *c, struct bch_dev *ca)
|
|||
bch2_dev_journal_exit(ca);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_BCACHEFS_DEBUG
|
||||
static void bch2_dev_ref_complete(struct percpu_ref *ref)
|
||||
{
|
||||
struct bch_dev *ca = container_of(ref, struct bch_dev, ref);
|
||||
|
||||
complete(&ca->ref_completion);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void bch2_dev_io_ref_complete(struct percpu_ref *ref)
|
||||
{
|
||||
|
|
@ -1301,9 +1306,14 @@ static struct bch_dev *__bch2_dev_alloc(struct bch_fs *c,
|
|||
ca->nr_btree_reserve = DIV_ROUND_UP(BTREE_NODE_RESERVE,
|
||||
ca->mi.bucket_size / btree_sectors(c));
|
||||
|
||||
if (percpu_ref_init(&ca->ref, bch2_dev_ref_complete,
|
||||
0, GFP_KERNEL) ||
|
||||
percpu_ref_init(&ca->io_ref, bch2_dev_io_ref_complete,
|
||||
#ifndef CONFIG_BCACHEFS_DEBUG
|
||||
if (percpu_ref_init(&ca->ref, bch2_dev_ref_complete, 0, GFP_KERNEL))
|
||||
goto err;
|
||||
#else
|
||||
atomic_long_set(&ca->ref, 1);
|
||||
#endif
|
||||
|
||||
if (percpu_ref_init(&ca->io_ref, bch2_dev_io_ref_complete,
|
||||
PERCPU_REF_INIT_DEAD, GFP_KERNEL) ||
|
||||
!(ca->sb_read_scratch = (void *) __get_free_page(GFP_KERNEL)) ||
|
||||
bch2_dev_buckets_alloc(c, ca) ||
|
||||
|
|
@ -1665,7 +1675,12 @@ int bch2_dev_remove(struct bch_fs *c, struct bch_dev *ca, int flags)
|
|||
rcu_assign_pointer(c->devs[ca->dev_idx], NULL);
|
||||
mutex_unlock(&c->sb_lock);
|
||||
|
||||
#ifndef CONFIG_BCACHEFS_DEBUG
|
||||
percpu_ref_kill(&ca->ref);
|
||||
#else
|
||||
ca->dying = true;
|
||||
bch2_dev_put(ca);
|
||||
#endif
|
||||
wait_for_completion(&ca->ref_completion);
|
||||
|
||||
bch2_dev_free(ca);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user