diff options
author | Joe Thornber <ejt@redhat.com> | 2013-08-09 07:59:30 -0400 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2013-08-23 09:02:14 -0400 |
commit | 04f17c802f447e76d13ade5bb78fbbf34baef0f8 (patch) | |
tree | 4bca7fac638c13e0659824e566dbd8df58f148dc | |
parent | cd5acf0b445030cd8b5bfd818f464997652485e5 (diff) |
dm btree: prefetch child nodes when walking tree for a dm_btree_del
dm-btree now takes advantage of dm-bufio's ability to prefetch data via
dm_bm_prefetch(). Prior to this change many btree node visits were
causing a synchronous read.
Signed-off-by: Joe Thornber <ejt@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
-rw-r--r-- | drivers/md/persistent-data/dm-block-manager.c | 5 | ||||
-rw-r--r-- | drivers/md/persistent-data/dm-block-manager.h | 5 | ||||
-rw-r--r-- | drivers/md/persistent-data/dm-btree.c | 26 |
3 files changed, 31 insertions, 5 deletions
diff --git a/drivers/md/persistent-data/dm-block-manager.c b/drivers/md/persistent-data/dm-block-manager.c index 81b513890e2b..a7e8bf296388 100644 --- a/drivers/md/persistent-data/dm-block-manager.c +++ b/drivers/md/persistent-data/dm-block-manager.c | |||
@@ -615,6 +615,11 @@ int dm_bm_flush_and_unlock(struct dm_block_manager *bm, | |||
615 | } | 615 | } |
616 | EXPORT_SYMBOL_GPL(dm_bm_flush_and_unlock); | 616 | EXPORT_SYMBOL_GPL(dm_bm_flush_and_unlock); |
617 | 617 | ||
618 | void dm_bm_prefetch(struct dm_block_manager *bm, dm_block_t b) | ||
619 | { | ||
620 | dm_bufio_prefetch(bm->bufio, b, 1); | ||
621 | } | ||
622 | |||
618 | void dm_bm_set_read_only(struct dm_block_manager *bm) | 623 | void dm_bm_set_read_only(struct dm_block_manager *bm) |
619 | { | 624 | { |
620 | bm->read_only = true; | 625 | bm->read_only = true; |
diff --git a/drivers/md/persistent-data/dm-block-manager.h b/drivers/md/persistent-data/dm-block-manager.h index be5bff61be28..9a82083a66b6 100644 --- a/drivers/md/persistent-data/dm-block-manager.h +++ b/drivers/md/persistent-data/dm-block-manager.h | |||
@@ -108,6 +108,11 @@ int dm_bm_unlock(struct dm_block *b); | |||
108 | int dm_bm_flush_and_unlock(struct dm_block_manager *bm, | 108 | int dm_bm_flush_and_unlock(struct dm_block_manager *bm, |
109 | struct dm_block *superblock); | 109 | struct dm_block *superblock); |
110 | 110 | ||
111 | /* | ||
112 | * Request data be prefetched into the cache. | ||
113 | */ | ||
114 | void dm_bm_prefetch(struct dm_block_manager *bm, dm_block_t b); | ||
115 | |||
111 | /* | 116 | /* |
112 | * Switches the bm to a read only mode. Once read-only mode | 117 | * Switches the bm to a read only mode. Once read-only mode |
113 | * has been entered the following functions will return -EPERM. | 118 | * has been entered the following functions will return -EPERM. |
diff --git a/drivers/md/persistent-data/dm-btree.c b/drivers/md/persistent-data/dm-btree.c index e872996e098d..468e371ee9b2 100644 --- a/drivers/md/persistent-data/dm-btree.c +++ b/drivers/md/persistent-data/dm-btree.c | |||
@@ -161,6 +161,7 @@ struct frame { | |||
161 | }; | 161 | }; |
162 | 162 | ||
163 | struct del_stack { | 163 | struct del_stack { |
164 | struct dm_btree_info *info; | ||
164 | struct dm_transaction_manager *tm; | 165 | struct dm_transaction_manager *tm; |
165 | int top; | 166 | int top; |
166 | struct frame spine[MAX_SPINE_DEPTH]; | 167 | struct frame spine[MAX_SPINE_DEPTH]; |
@@ -183,6 +184,20 @@ static int unprocessed_frames(struct del_stack *s) | |||
183 | return s->top >= 0; | 184 | return s->top >= 0; |
184 | } | 185 | } |
185 | 186 | ||
187 | static void prefetch_children(struct del_stack *s, struct frame *f) | ||
188 | { | ||
189 | unsigned i; | ||
190 | struct dm_block_manager *bm = dm_tm_get_bm(s->tm); | ||
191 | |||
192 | for (i = 0; i < f->nr_children; i++) | ||
193 | dm_bm_prefetch(bm, value64(f->n, i)); | ||
194 | } | ||
195 | |||
196 | static bool is_internal_level(struct dm_btree_info *info, struct frame *f) | ||
197 | { | ||
198 | return f->level < (info->levels - 1); | ||
199 | } | ||
200 | |||
186 | static int push_frame(struct del_stack *s, dm_block_t b, unsigned level) | 201 | static int push_frame(struct del_stack *s, dm_block_t b, unsigned level) |
187 | { | 202 | { |
188 | int r; | 203 | int r; |
@@ -205,6 +220,7 @@ static int push_frame(struct del_stack *s, dm_block_t b, unsigned level) | |||
205 | dm_tm_dec(s->tm, b); | 220 | dm_tm_dec(s->tm, b); |
206 | 221 | ||
207 | else { | 222 | else { |
223 | uint32_t flags; | ||
208 | struct frame *f = s->spine + ++s->top; | 224 | struct frame *f = s->spine + ++s->top; |
209 | 225 | ||
210 | r = dm_tm_read_lock(s->tm, b, &btree_node_validator, &f->b); | 226 | r = dm_tm_read_lock(s->tm, b, &btree_node_validator, &f->b); |
@@ -217,6 +233,10 @@ static int push_frame(struct del_stack *s, dm_block_t b, unsigned level) | |||
217 | f->level = level; | 233 | f->level = level; |
218 | f->nr_children = le32_to_cpu(f->n->header.nr_entries); | 234 | f->nr_children = le32_to_cpu(f->n->header.nr_entries); |
219 | f->current_child = 0; | 235 | f->current_child = 0; |
236 | |||
237 | flags = le32_to_cpu(f->n->header.flags); | ||
238 | if (flags & INTERNAL_NODE || is_internal_level(s->info, f)) | ||
239 | prefetch_children(s, f); | ||
220 | } | 240 | } |
221 | 241 | ||
222 | return 0; | 242 | return 0; |
@@ -230,11 +250,6 @@ static void pop_frame(struct del_stack *s) | |||
230 | dm_tm_unlock(s->tm, f->b); | 250 | dm_tm_unlock(s->tm, f->b); |
231 | } | 251 | } |
232 | 252 | ||
233 | static bool is_internal_level(struct dm_btree_info *info, struct frame *f) | ||
234 | { | ||
235 | return f->level < (info->levels - 1); | ||
236 | } | ||
237 | |||
238 | int dm_btree_del(struct dm_btree_info *info, dm_block_t root) | 253 | int dm_btree_del(struct dm_btree_info *info, dm_block_t root) |
239 | { | 254 | { |
240 | int r; | 255 | int r; |
@@ -243,6 +258,7 @@ int dm_btree_del(struct dm_btree_info *info, dm_block_t root) | |||
243 | s = kmalloc(sizeof(*s), GFP_KERNEL); | 258 | s = kmalloc(sizeof(*s), GFP_KERNEL); |
244 | if (!s) | 259 | if (!s) |
245 | return -ENOMEM; | 260 | return -ENOMEM; |
261 | s->info = info; | ||
246 | s->tm = info->tm; | 262 | s->tm = info->tm; |
247 | s->top = -1; | 263 | s->top = -1; |
248 | 264 | ||