Skip to content

Commit 0c34e7f

Browse files
author
Kent Overstreet
committed
bcachefs: Tweak bch2_data_update_init() for stack usage
- Separate out a slowpath for bkey_nocow_lock() - Don't call bch2_bkey_ptrs_c() or loop over pointers more than necessary Signed-off-by: Kent Overstreet <[email protected]>
1 parent 56e5c7f commit 0c34e7f

File tree

1 file changed

+67
-44
lines changed

1 file changed

+67
-44
lines changed

fs/bcachefs/data_update.c

Lines changed: 67 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -66,37 +66,46 @@ static void bkey_nocow_unlock(struct bch_fs *c, struct bkey_s_c k)
6666
}
6767
}
6868

69-
static bool bkey_nocow_lock(struct bch_fs *c, struct moving_context *ctxt, struct bkey_s_c k)
69+
static noinline_for_stack
70+
bool __bkey_nocow_lock(struct bch_fs *c, struct moving_context *ctxt, struct bkey_ptrs_c ptrs,
71+
const struct bch_extent_ptr *start)
7072
{
71-
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
73+
if (!ctxt) {
74+
bkey_for_each_ptr(ptrs, ptr) {
75+
if (ptr == start)
76+
break;
77+
78+
struct bch_dev *ca = bch2_dev_have_ref(c, ptr->dev);
79+
struct bpos bucket = PTR_BUCKET_POS(ca, ptr);
80+
bch2_bucket_nocow_unlock(&c->nocow_locks, bucket, 0);
81+
}
82+
return false;
83+
}
7284

85+
__bkey_for_each_ptr(start, ptrs.end, ptr) {
86+
struct bch_dev *ca = bch2_dev_have_ref(c, ptr->dev);
87+
struct bpos bucket = PTR_BUCKET_POS(ca, ptr);
88+
89+
bool locked;
90+
move_ctxt_wait_event(ctxt,
91+
(locked = bch2_bucket_nocow_trylock(&c->nocow_locks, bucket, 0)) ||
92+
list_empty(&ctxt->ios));
93+
if (!locked)
94+
bch2_bucket_nocow_lock(&c->nocow_locks, bucket, 0);
95+
}
96+
return true;
97+
}
98+
99+
static bool bkey_nocow_lock(struct bch_fs *c, struct moving_context *ctxt, struct bkey_ptrs_c ptrs)
100+
{
73101
bkey_for_each_ptr(ptrs, ptr) {
74102
struct bch_dev *ca = bch2_dev_have_ref(c, ptr->dev);
75103
struct bpos bucket = PTR_BUCKET_POS(ca, ptr);
76104

77-
if (ctxt) {
78-
bool locked;
79-
80-
move_ctxt_wait_event(ctxt,
81-
(locked = bch2_bucket_nocow_trylock(&c->nocow_locks, bucket, 0)) ||
82-
list_empty(&ctxt->ios));
83-
84-
if (!locked)
85-
bch2_bucket_nocow_lock(&c->nocow_locks, bucket, 0);
86-
} else {
87-
if (!bch2_bucket_nocow_trylock(&c->nocow_locks, bucket, 0)) {
88-
bkey_for_each_ptr(ptrs, ptr2) {
89-
if (ptr2 == ptr)
90-
break;
91-
92-
ca = bch2_dev_have_ref(c, ptr2->dev);
93-
bucket = PTR_BUCKET_POS(ca, ptr2);
94-
bch2_bucket_nocow_unlock(&c->nocow_locks, bucket, 0);
95-
}
96-
return false;
97-
}
98-
}
105+
if (!bch2_bucket_nocow_trylock(&c->nocow_locks, bucket, 0))
106+
return __bkey_nocow_lock(c, ctxt, ptrs, ptr);
99107
}
108+
100109
return true;
101110
}
102111

@@ -523,8 +532,9 @@ void bch2_data_update_exit(struct data_update *update)
523532
bch2_bkey_buf_exit(&update->k, c);
524533
}
525534

526-
static int bch2_update_unwritten_extent(struct btree_trans *trans,
527-
struct data_update *update)
535+
static noinline_for_stack
536+
int bch2_update_unwritten_extent(struct btree_trans *trans,
537+
struct data_update *update)
528538
{
529539
struct bch_fs *c = update->op.c;
530540
struct bkey_i_extent *e;
@@ -716,18 +726,10 @@ int bch2_extent_drop_ptrs(struct btree_trans *trans,
716726
bch2_trans_commit(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc);
717727
}
718728

719-
int bch2_data_update_bios_init(struct data_update *m, struct bch_fs *c,
720-
struct bch_io_opts *io_opts)
729+
static int __bch2_data_update_bios_init(struct data_update *m, struct bch_fs *c,
730+
struct bch_io_opts *io_opts,
731+
unsigned buf_bytes)
721732
{
722-
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(bkey_i_to_s_c(m->k.k));
723-
const union bch_extent_entry *entry;
724-
struct extent_ptr_decoded p;
725-
726-
/* write path might have to decompress data: */
727-
unsigned buf_bytes = 0;
728-
bkey_for_each_ptr_decode(&m->k.k->k, ptrs, p, entry)
729-
buf_bytes = max_t(unsigned, buf_bytes, p.crc.uncompressed_size << 9);
730-
731733
unsigned nr_vecs = DIV_ROUND_UP(buf_bytes, PAGE_SIZE);
732734

733735
m->bvecs = kmalloc_array(nr_vecs, sizeof*(m->bvecs), GFP_KERNEL);
@@ -751,6 +753,21 @@ int bch2_data_update_bios_init(struct data_update *m, struct bch_fs *c,
751753
return 0;
752754
}
753755

756+
int bch2_data_update_bios_init(struct data_update *m, struct bch_fs *c,
757+
struct bch_io_opts *io_opts)
758+
{
759+
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(bkey_i_to_s_c(m->k.k));
760+
const union bch_extent_entry *entry;
761+
struct extent_ptr_decoded p;
762+
763+
/* write path might have to decompress data: */
764+
unsigned buf_bytes = 0;
765+
bkey_for_each_ptr_decode(&m->k.k->k, ptrs, p, entry)
766+
buf_bytes = max_t(unsigned, buf_bytes, p.crc.uncompressed_size << 9);
767+
768+
return __bch2_data_update_bios_init(m, c, io_opts, buf_bytes);
769+
}
770+
754771
static int can_write_extent(struct bch_fs *c, struct data_update *m)
755772
{
756773
if ((m->op.flags & BCH_WRITE_alloc_nowait) &&
@@ -802,10 +819,6 @@ int bch2_data_update_init(struct btree_trans *trans,
802819
struct bkey_s_c k)
803820
{
804821
struct bch_fs *c = trans->c;
805-
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
806-
const union bch_extent_entry *entry;
807-
struct extent_ptr_decoded p;
808-
unsigned reserve_sectors = k.k->size * data_opts.extra_replicas;
809822
int ret = 0;
810823

811824
/*
@@ -842,6 +855,13 @@ int bch2_data_update_init(struct btree_trans *trans,
842855

843856
unsigned durability_have = 0, durability_removing = 0;
844857

858+
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(bkey_i_to_s_c(m->k.k));
859+
const union bch_extent_entry *entry;
860+
struct extent_ptr_decoded p;
861+
unsigned reserve_sectors = k.k->size * data_opts.extra_replicas;
862+
unsigned buf_bytes = 0;
863+
bool unwritten = false;
864+
845865
unsigned ptr_bit = 1;
846866
bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
847867
if (!p.ptr.cached) {
@@ -872,6 +892,9 @@ int bch2_data_update_init(struct btree_trans *trans,
872892
if (p.crc.compression_type == BCH_COMPRESSION_TYPE_incompressible)
873893
m->op.incompressible = true;
874894

895+
buf_bytes = max_t(unsigned, buf_bytes, p.crc.uncompressed_size << 9);
896+
unwritten |= p.ptr.unwritten;
897+
875898
ptr_bit <<= 1;
876899
}
877900

@@ -946,18 +969,18 @@ int bch2_data_update_init(struct btree_trans *trans,
946969
}
947970

948971
if (c->opts.nocow_enabled &&
949-
!bkey_nocow_lock(c, ctxt, k)) {
972+
!bkey_nocow_lock(c, ctxt, ptrs)) {
950973
ret = -BCH_ERR_nocow_lock_blocked;
951974
goto out_put_dev_refs;
952975
}
953976

954-
if (bkey_extent_is_unwritten(k)) {
977+
if (unwritten) {
955978
ret = bch2_update_unwritten_extent(trans, m) ?:
956979
-BCH_ERR_data_update_done_unwritten;
957980
goto out_nocow_unlock;
958981
}
959982

960-
ret = bch2_data_update_bios_init(m, c, io_opts);
983+
ret = __bch2_data_update_bios_init(m, c, io_opts, buf_bytes);
961984
if (ret)
962985
goto out_nocow_unlock;
963986

0 commit comments

Comments
 (0)