Message ID | 20200715143015.14957-13-colyli@suse.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | bcache: extend bucket size to 32bit width | expand |
On 7/15/20 4:30 PM, colyli@suse.de wrote: > From: Coly Li <colyli@suse.de> > > Currently the bcache internal btree node occupies a whole bucket. When > loading the btree node from cache device into memory, mca_data_alloc() > will call bch_btree_keys_alloc() to allocate memory for the whole bucket > size, ilog2(b->c->btree_pages) is send to bch_btree_keys_alloc() as the > parameter 'page_order'. > > c->btree_pages is set as bucket_pages() in bch_cache_set_alloc(), for > bucket size > 8MB, ilog2(b->c->btree_pages) is 12 for 4KB page size. By > default the maximum page order __get_free_pages() accepts is MAX_ORDER > (11), in this condition bch_btree_keys_alloc() will always fail. > > Because of other over-page-order allocation failure fails the cache > device registration, such btree node allocation failure wasn't observed > during runtime. After other blocking page allocation failures for bucket > size > 8MB, this btree node allocation issue may trigger potentical risk > e.g. infinite dead-loop to retry btree node allocation after failure. > > This patch fixes the potential problem by setting c->btree_pages to > meta_bucket_pages() in bch_cache_set_alloc(). In the condition that > bucket size > 8MB, meta_bucket_pages() will always return a number which > won't exceed the maximum page order of the buddy allocator. > > Signed-off-by: Coly Li <colyli@suse.de> > --- > drivers/md/bcache/super.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c > index b1d8388ef57d..02901d0ae8e2 100644 > --- a/drivers/md/bcache/super.c > +++ b/drivers/md/bcache/super.c > @@ -1867,7 +1867,7 @@ struct cache_set *bch_cache_set_alloc(struct cache_sb *sb) > c->nr_uuids = meta_bucket_bytes(&c->sb) / sizeof(struct uuid_entry); > c->devices_max_used = 0; > atomic_set(&c->attached_dev_nr, 0); > - c->btree_pages = bucket_pages(c); > + c->btree_pages = meta_bucket_pages(&c->sb); > if (c->btree_pages > BTREE_MAX_PAGES) > c->btree_pages = max_t(int, c->btree_pages / 4, > BTREE_MAX_PAGES); > Reviewed-by: Hannes Reinecke <hare@suse.de> Cheers, Hannes
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index b1d8388ef57d..02901d0ae8e2 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -1867,7 +1867,7 @@ struct cache_set *bch_cache_set_alloc(struct cache_sb *sb) c->nr_uuids = meta_bucket_bytes(&c->sb) / sizeof(struct uuid_entry); c->devices_max_used = 0; atomic_set(&c->attached_dev_nr, 0); - c->btree_pages = bucket_pages(c); + c->btree_pages = meta_bucket_pages(&c->sb); if (c->btree_pages > BTREE_MAX_PAGES) c->btree_pages = max_t(int, c->btree_pages / 4, BTREE_MAX_PAGES);