Commit 4fe6a816707aace9e8e297b708411c5930537793
1 parent
c13f3af924
Exists in
master
and in
13 other branches
bcache: Add a real GC_MARK_RECLAIMABLE
This means the garbage collection code can better check for data and metadata pointers to the same buckets. Signed-off-by: Kent Overstreet <kmo@daterainc.com>
Showing 4 changed files with 21 additions and 14 deletions Side-by-side Diff
drivers/md/bcache/alloc.c
... | ... | @@ -155,7 +155,8 @@ |
155 | 155 | |
156 | 156 | static bool can_invalidate_bucket(struct cache *ca, struct bucket *b) |
157 | 157 | { |
158 | - return GC_MARK(b) == GC_MARK_RECLAIMABLE && | |
158 | + return (!GC_MARK(b) || | |
159 | + GC_MARK(b) == GC_MARK_RECLAIMABLE) && | |
159 | 160 | !atomic_read(&b->pin) && |
160 | 161 | can_inc_bucket_gen(b); |
161 | 162 | } |
... | ... | @@ -475,7 +476,7 @@ |
475 | 476 | for (i = 0; i < KEY_PTRS(k); i++) { |
476 | 477 | struct bucket *b = PTR_BUCKET(c, k, i); |
477 | 478 | |
478 | - SET_GC_MARK(b, GC_MARK_RECLAIMABLE); | |
479 | + SET_GC_MARK(b, 0); | |
479 | 480 | SET_GC_SECTORS_USED(b, 0); |
480 | 481 | bch_bucket_add_unused(PTR_CACHE(c, k, i), b); |
481 | 482 | } |
drivers/md/bcache/bcache.h
... | ... | @@ -207,9 +207,9 @@ |
207 | 207 | */ |
208 | 208 | |
209 | 209 | BITMASK(GC_MARK, struct bucket, gc_mark, 0, 2); |
210 | -#define GC_MARK_RECLAIMABLE 0 | |
211 | -#define GC_MARK_DIRTY 1 | |
212 | -#define GC_MARK_METADATA 2 | |
210 | +#define GC_MARK_RECLAIMABLE 1 | |
211 | +#define GC_MARK_DIRTY 2 | |
212 | +#define GC_MARK_METADATA 3 | |
213 | 213 | #define GC_SECTORS_USED_SIZE 13 |
214 | 214 | #define MAX_GC_SECTORS_USED (~(~0ULL << GC_SECTORS_USED_SIZE)) |
215 | 215 | BITMASK(GC_SECTORS_USED, struct bucket, gc_mark, 2, GC_SECTORS_USED_SIZE); |
drivers/md/bcache/btree.c
... | ... | @@ -1160,6 +1160,8 @@ |
1160 | 1160 | SET_GC_MARK(g, GC_MARK_METADATA); |
1161 | 1161 | else if (KEY_DIRTY(k)) |
1162 | 1162 | SET_GC_MARK(g, GC_MARK_DIRTY); |
1163 | + else if (!GC_MARK(g)) | |
1164 | + SET_GC_MARK(g, GC_MARK_RECLAIMABLE); | |
1163 | 1165 | |
1164 | 1166 | /* guard against overflow */ |
1165 | 1167 | SET_GC_SECTORS_USED(g, min_t(unsigned, |
... | ... | @@ -1559,7 +1561,7 @@ |
1559 | 1561 | for_each_bucket(b, ca) { |
1560 | 1562 | b->gc_gen = b->gen; |
1561 | 1563 | if (!atomic_read(&b->pin)) { |
1562 | - SET_GC_MARK(b, GC_MARK_RECLAIMABLE); | |
1564 | + SET_GC_MARK(b, 0); | |
1563 | 1565 | SET_GC_SECTORS_USED(b, 0); |
1564 | 1566 | } |
1565 | 1567 | } |
1566 | 1568 | |
... | ... | @@ -1622,12 +1624,16 @@ |
1622 | 1624 | b->last_gc = b->gc_gen; |
1623 | 1625 | c->need_gc = max(c->need_gc, bucket_gc_gen(b)); |
1624 | 1626 | |
1625 | - if (!atomic_read(&b->pin) && | |
1626 | - GC_MARK(b) == GC_MARK_RECLAIMABLE) { | |
1627 | + if (atomic_read(&b->pin)) | |
1628 | + continue; | |
1629 | + | |
1630 | + BUG_ON(!GC_MARK(b) && GC_SECTORS_USED(b)); | |
1631 | + | |
1632 | + if (!GC_MARK(b) || GC_MARK(b) == GC_MARK_RECLAIMABLE) | |
1627 | 1633 | available++; |
1628 | - if (!GC_SECTORS_USED(b)) | |
1629 | - bch_bucket_add_unused(ca, b); | |
1630 | - } | |
1634 | + | |
1635 | + if (!GC_MARK(b)) | |
1636 | + bch_bucket_add_unused(ca, b); | |
1631 | 1637 | } |
1632 | 1638 | } |
1633 | 1639 |
drivers/md/bcache/extents.c
... | ... | @@ -499,9 +499,9 @@ |
499 | 499 | |
500 | 500 | if (mutex_trylock(&b->c->bucket_lock)) { |
501 | 501 | if (b->c->gc_mark_valid && |
502 | - ((GC_MARK(g) != GC_MARK_DIRTY && | |
503 | - KEY_DIRTY(k)) || | |
504 | - GC_MARK(g) == GC_MARK_METADATA)) | |
502 | + (!GC_MARK(g) || | |
503 | + GC_MARK(g) == GC_MARK_METADATA || | |
504 | + (GC_MARK(g) != GC_MARK_DIRTY && KEY_DIRTY(k)))) | |
505 | 505 | goto err; |
506 | 506 | |
507 | 507 | if (g->prio == BTREE_PRIO) |