aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKent Overstreet <koverstreet@google.com>2013-05-11 18:59:37 -0400
committerKent Overstreet <koverstreet@google.com>2013-06-26 20:09:16 -0400
commit6ded34d1a54c046a45db071d3cb7b37bd0a4a31f (patch)
tree1f2b7703d1be78e0ab510df54a487b746a8e2312
parent85b1492ee113486d871de7676a61f506a43ca475 (diff)
bcache: Improve lazy sorting
The old lazy sorting code was kind of hacky - rewrite in a way that mathematically makes more sense; the idea is that the size of the sets of keys in a btree node should increase by a more or less fixed ratio from smallest to biggest. Signed-off-by: Kent Overstreet <koverstreet@google.com>
-rw-r--r--drivers/md/bcache/bcache.h1
-rw-r--r--drivers/md/bcache/bset.c40
-rw-r--r--drivers/md/bcache/super.c2
3 files changed, 26 insertions, 17 deletions
diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
index 59c15e09e4dd..6fa5a1e33c49 100644
--- a/drivers/md/bcache/bcache.h
+++ b/drivers/md/bcache/bcache.h
@@ -828,6 +828,7 @@ struct cache_set {
828 */ 828 */
829 struct mutex sort_lock; 829 struct mutex sort_lock;
830 struct bset *sort; 830 struct bset *sort;
831 unsigned sort_crit_factor;
831 832
832 /* List of buckets we're currently writing data to */ 833 /* List of buckets we're currently writing data to */
833 struct list_head data_buckets; 834 struct list_head data_buckets;
diff --git a/drivers/md/bcache/bset.c b/drivers/md/bcache/bset.c
index e9399ed7f688..a0f190ac17a4 100644
--- a/drivers/md/bcache/bset.c
+++ b/drivers/md/bcache/bset.c
@@ -1092,33 +1092,39 @@ void bch_btree_sort_into(struct btree *b, struct btree *new)
1092 new->sets->size = 0; 1092 new->sets->size = 0;
1093} 1093}
1094 1094
1095#define SORT_CRIT (4096 / sizeof(uint64_t))
1096
1095void bch_btree_sort_lazy(struct btree *b) 1097void bch_btree_sort_lazy(struct btree *b)
1096{ 1098{
1097 if (b->nsets) { 1099 unsigned crit = SORT_CRIT;
1098 unsigned i, j, keys = 0, total; 1100 int i;
1099
1100 for (i = 0; i <= b->nsets; i++)
1101 keys += b->sets[i].data->keys;
1102 1101
1103 total = keys; 1102 /* Don't sort if nothing to do */
1103 if (!b->nsets)
1104 goto out;
1104 1105
1105 for (j = 0; j < b->nsets; j++) { 1106 /* If not a leaf node, always sort */
1106 if (keys * 2 < total || 1107 if (b->level) {
1107 keys < 1000) { 1108 bch_btree_sort(b);
1108 bch_btree_sort_partial(b, j); 1109 return;
1109 return; 1110 }
1110 }
1111 1111
1112 keys -= b->sets[j].data->keys; 1112 for (i = b->nsets - 1; i >= 0; --i) {
1113 } 1113 crit *= b->c->sort_crit_factor;
1114 1114
1115 /* Must sort if b->nsets == 3 or we'll overflow */ 1115 if (b->sets[i].data->keys < crit) {
1116 if (b->nsets >= (MAX_BSETS - 1) - b->level) { 1116 bch_btree_sort_partial(b, i);
1117 bch_btree_sort(b);
1118 return; 1117 return;
1119 } 1118 }
1120 } 1119 }
1121 1120
1121 /* Sort if we'd overflow */
1122 if (b->nsets + 1 == MAX_BSETS) {
1123 bch_btree_sort(b);
1124 return;
1125 }
1126
1127out:
1122 bset_build_written_tree(b); 1128 bset_build_written_tree(b);
1123} 1129}
1124 1130
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index f24c2e0cbb1c..3c8474161e8e 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -1375,6 +1375,8 @@ struct cache_set *bch_cache_set_alloc(struct cache_sb *sb)
1375 c->btree_pages = max_t(int, c->btree_pages / 4, 1375 c->btree_pages = max_t(int, c->btree_pages / 4,
1376 BTREE_MAX_PAGES); 1376 BTREE_MAX_PAGES);
1377 1377
1378 c->sort_crit_factor = int_sqrt(c->btree_pages);
1379
1378 mutex_init(&c->bucket_lock); 1380 mutex_init(&c->bucket_lock);
1379 mutex_init(&c->sort_lock); 1381 mutex_init(&c->sort_lock);
1380 spin_lock_init(&c->sort_time_lock); 1382 spin_lock_init(&c->sort_time_lock);