On 2018/10/23 下午9:42, Shenghui Wang wrote: > We have the following define for btree iterator: > struct btree_iter { > size_t size, used; > #ifdef CONFIG_BCACHE_DEBUG > struct btree_keys *b; > #endif > struct btree_iter_set { > struct bkey *k, *end; > } data[MAX_BSETS]; > }; > > We can see that the length of data[] field is static MAX_BSETS, which is > defined as 4 currently. > > But a btree node on disk could have too many bsets for an iterator to fit > on the stack - maybe far more that MAX_BSETS. Have to dynamically allocate > space to host more btree_iter_sets. > > bch_cache_set_alloc() will make sure the pool cache_set->fill_iter can > allocate an iterator equipped with enough room that can host > (sb.bucket_size / sb.block_size) > btree_iter_sets, which is more than static MAX_BSETS. > > bch_btree_node_read_done() will use that pool to allocate one iterator, to > host many bsets in one btree node. > > Add more comment around cache_set->fill_iter to make code less confusing. > > Signed-off-by: Shenghui Wang <shhuiw@xxxxxxxxxxx> Hi Shenghui, Thanks for the document, it is informative and helpful. Except for the bch_debug_init() change, the patch is OK to me. Thanks. Coly Li > --- > drivers/md/bcache/bcache.h | 8 ++++++-- > drivers/md/bcache/btree.c | 5 +++++ > 2 files changed, 11 insertions(+), 2 deletions(-) > > diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h > index b61b83bbcfff..a7ad04c597fc 100644 > --- a/drivers/md/bcache/bcache.h > +++ b/drivers/md/bcache/bcache.h > @@ -658,7 +658,11 @@ struct cache_set { > > /* > * A btree node on disk could have too many bsets for an iterator to fit > - * on the stack - have to dynamically allocate them > + * on the stack - have to dynamically allocate them. > + * bch_cache_set_alloc() will make sure the pool can allocate iterators > + * equipped with enough room that can host > + * (sb.bucket_size / sb.block_size) > + * btree_iter_sets, which is more than static MAX_BSETS. > */ > mempool_t fill_iter; > > @@ -1004,7 +1008,7 @@ void bch_open_buckets_free(struct cache_set *c); > int bch_cache_allocator_start(struct cache *ca); > > void bch_debug_exit(void); > -void bch_debug_init(void); > +void bch_debug_init(struct kobject *kobj); > void bch_request_exit(void); > int bch_request_init(void); > > diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c > index 3f4211b5cd33..23cb1dc7296b 100644 > --- a/drivers/md/bcache/btree.c > +++ b/drivers/md/bcache/btree.c > @@ -207,6 +207,11 @@ void bch_btree_node_read_done(struct btree *b) > struct bset *i = btree_bset_first(b); > struct btree_iter *iter; > > + /* > + * c->fill_iter can allocate an iterator with more memory space > + * than static MAX_BSETS. > + * See the comment arount cache_set->fill_iter. > + */ > iter = mempool_alloc(&b->c->fill_iter, GFP_NOIO); > iter->size = b->c->sb.bucket_size / b->c->sb.block_size; > iter->used = 0; >