Skip to content

Commit

Permalink
bcache: Add a real GC_MARK_RECLAIMABLE
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Kent Overstreet committed Mar 18, 2014
1 parent c13f3af commit 4fe6a81
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 14 deletions.
5 changes: 3 additions & 2 deletions drivers/md/bcache/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ bool bch_bucket_add_unused(struct cache *ca, struct bucket *b)

static bool can_invalidate_bucket(struct cache *ca, struct bucket *b)
{
return GC_MARK(b) == GC_MARK_RECLAIMABLE &&
return (!GC_MARK(b) ||
GC_MARK(b) == GC_MARK_RECLAIMABLE) &&
!atomic_read(&b->pin) &&
can_inc_bucket_gen(b);
}
Expand Down Expand Up @@ -475,7 +476,7 @@ void bch_bucket_free(struct cache_set *c, struct bkey *k)
for (i = 0; i < KEY_PTRS(k); i++) {
struct bucket *b = PTR_BUCKET(c, k, i);

SET_GC_MARK(b, GC_MARK_RECLAIMABLE);
SET_GC_MARK(b, 0);
SET_GC_SECTORS_USED(b, 0);
bch_bucket_add_unused(PTR_CACHE(c, k, i), b);
}
Expand Down
6 changes: 3 additions & 3 deletions drivers/md/bcache/bcache.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,9 @@ struct bucket {
*/

BITMASK(GC_MARK, struct bucket, gc_mark, 0, 2);
#define GC_MARK_RECLAIMABLE 0
#define GC_MARK_DIRTY 1
#define GC_MARK_METADATA 2
#define GC_MARK_RECLAIMABLE 1
#define GC_MARK_DIRTY 2
#define GC_MARK_METADATA 3
#define GC_SECTORS_USED_SIZE 13
#define MAX_GC_SECTORS_USED (~(~0ULL << GC_SECTORS_USED_SIZE))
BITMASK(GC_SECTORS_USED, struct bucket, gc_mark, 2, GC_SECTORS_USED_SIZE);
Expand Down
18 changes: 12 additions & 6 deletions drivers/md/bcache/btree.c
Original file line number Diff line number Diff line change
Expand Up @@ -1160,6 +1160,8 @@ static uint8_t __bch_btree_mark_key(struct cache_set *c, int level,
SET_GC_MARK(g, GC_MARK_METADATA);
else if (KEY_DIRTY(k))
SET_GC_MARK(g, GC_MARK_DIRTY);
else if (!GC_MARK(g))
SET_GC_MARK(g, GC_MARK_RECLAIMABLE);

/* guard against overflow */
SET_GC_SECTORS_USED(g, min_t(unsigned,
Expand Down Expand Up @@ -1559,7 +1561,7 @@ static void btree_gc_start(struct cache_set *c)
for_each_bucket(b, ca) {
b->gc_gen = b->gen;
if (!atomic_read(&b->pin)) {
SET_GC_MARK(b, GC_MARK_RECLAIMABLE);
SET_GC_MARK(b, 0);
SET_GC_SECTORS_USED(b, 0);
}
}
Expand Down Expand Up @@ -1622,12 +1624,16 @@ size_t bch_btree_gc_finish(struct cache_set *c)
b->last_gc = b->gc_gen;
c->need_gc = max(c->need_gc, bucket_gc_gen(b));

if (!atomic_read(&b->pin) &&
GC_MARK(b) == GC_MARK_RECLAIMABLE) {
if (atomic_read(&b->pin))
continue;

BUG_ON(!GC_MARK(b) && GC_SECTORS_USED(b));

if (!GC_MARK(b) || GC_MARK(b) == GC_MARK_RECLAIMABLE)
available++;
if (!GC_SECTORS_USED(b))
bch_bucket_add_unused(ca, b);
}

if (!GC_MARK(b))
bch_bucket_add_unused(ca, b);
}
}

Expand Down
6 changes: 3 additions & 3 deletions drivers/md/bcache/extents.c
Original file line number Diff line number Diff line change
Expand Up @@ -499,9 +499,9 @@ static bool bch_extent_bad_expensive(struct btree *b, const struct bkey *k,

if (mutex_trylock(&b->c->bucket_lock)) {
if (b->c->gc_mark_valid &&
((GC_MARK(g) != GC_MARK_DIRTY &&
KEY_DIRTY(k)) ||
GC_MARK(g) == GC_MARK_METADATA))
(!GC_MARK(g) ||
GC_MARK(g) == GC_MARK_METADATA ||
(GC_MARK(g) != GC_MARK_DIRTY && KEY_DIRTY(k))))
goto err;

if (g->prio == BTREE_PRIO)
Expand Down

0 comments on commit 4fe6a81

Please sign in to comment.