Skip to content

Commit

Permalink
Merge branch 'bcache-for-3.13' of git://evilpiepirate.org/~kent/linux…
Browse files Browse the repository at this point in the history
…-bcache into for-linus

Kent writes:

Jens - small pile of bcache fixes. I've been slacking on the writeback
fixes but those definitely need to get into 3.13.
  • Loading branch information
Jens Axboe committed Dec 17, 2013
2 parents 8515736 + 16749c2 commit 60e53a6
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 66 deletions.
2 changes: 2 additions & 0 deletions drivers/md/bcache/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -421,9 +421,11 @@ long bch_bucket_alloc(struct cache *ca, unsigned watermark, bool wait)

if (watermark <= WATERMARK_METADATA) {
SET_GC_MARK(b, GC_MARK_METADATA);
SET_GC_MOVE(b, 0);
b->prio = BTREE_PRIO;
} else {
SET_GC_MARK(b, GC_MARK_RECLAIMABLE);
SET_GC_MOVE(b, 0);
b->prio = INITIAL_PRIO;
}

Expand Down
12 changes: 6 additions & 6 deletions drivers/md/bcache/bcache.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ struct bucket {
uint8_t disk_gen;
uint8_t last_gc; /* Most out of date gen in the btree */
uint8_t gc_gen;
uint16_t gc_mark;
uint16_t gc_mark; /* Bitfield used by GC. See below for field */
};

/*
Expand All @@ -209,7 +209,8 @@ BITMASK(GC_MARK, struct bucket, gc_mark, 0, 2);
#define GC_MARK_RECLAIMABLE 0
#define GC_MARK_DIRTY 1
#define GC_MARK_METADATA 2
BITMASK(GC_SECTORS_USED, struct bucket, gc_mark, 2, 14);
BITMASK(GC_SECTORS_USED, struct bucket, gc_mark, 2, 13);
BITMASK(GC_MOVE, struct bucket, gc_mark, 15, 1);

#include "journal.h"
#include "stats.h"
Expand Down Expand Up @@ -372,14 +373,14 @@ struct cached_dev {
unsigned char writeback_percent;
unsigned writeback_delay;

int writeback_rate_change;
int64_t writeback_rate_derivative;
uint64_t writeback_rate_target;
int64_t writeback_rate_proportional;
int64_t writeback_rate_derivative;
int64_t writeback_rate_change;

unsigned writeback_rate_update_seconds;
unsigned writeback_rate_d_term;
unsigned writeback_rate_p_term_inverse;
unsigned writeback_rate_d_smooth;
};

enum alloc_watermarks {
Expand Down Expand Up @@ -445,7 +446,6 @@ struct cache {
* call prio_write() to keep gens from wrapping.
*/
uint8_t need_save_prio;
unsigned gc_move_threshold;

/*
* If nonzero, we know we aren't going to find any buckets to invalidate
Expand Down
27 changes: 25 additions & 2 deletions drivers/md/bcache/btree.c
Original file line number Diff line number Diff line change
Expand Up @@ -1561,6 +1561,28 @@ size_t bch_btree_gc_finish(struct cache_set *c)
SET_GC_MARK(PTR_BUCKET(c, &c->uuid_bucket, i),
GC_MARK_METADATA);

/* don't reclaim buckets to which writeback keys point */
rcu_read_lock();
for (i = 0; i < c->nr_uuids; i++) {
struct bcache_device *d = c->devices[i];
struct cached_dev *dc;
struct keybuf_key *w, *n;
unsigned j;

if (!d || UUID_FLASH_ONLY(&c->uuids[i]))
continue;
dc = container_of(d, struct cached_dev, disk);

spin_lock(&dc->writeback_keys.lock);
rbtree_postorder_for_each_entry_safe(w, n,
&dc->writeback_keys.keys, node)
for (j = 0; j < KEY_PTRS(&w->key); j++)
SET_GC_MARK(PTR_BUCKET(c, &w->key, j),
GC_MARK_DIRTY);
spin_unlock(&dc->writeback_keys.lock);
}
rcu_read_unlock();

for_each_cache(ca, c, i) {
uint64_t *i;

Expand Down Expand Up @@ -1817,7 +1839,8 @@ static bool fix_overlapping_extents(struct btree *b, struct bkey *insert,
if (KEY_START(k) > KEY_START(insert) + sectors_found)
goto check_failed;

if (KEY_PTRS(replace_key) != KEY_PTRS(k))
if (KEY_PTRS(k) != KEY_PTRS(replace_key) ||
KEY_DIRTY(k) != KEY_DIRTY(replace_key))
goto check_failed;

/* skip past gen */
Expand Down Expand Up @@ -2217,7 +2240,7 @@ struct btree_insert_op {
struct bkey *replace_key;
};

int btree_insert_fn(struct btree_op *b_op, struct btree *b)
static int btree_insert_fn(struct btree_op *b_op, struct btree *b)
{
struct btree_insert_op *op = container_of(b_op,
struct btree_insert_op, op);
Expand Down
21 changes: 15 additions & 6 deletions drivers/md/bcache/movinggc.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,9 @@ static bool moving_pred(struct keybuf *buf, struct bkey *k)
unsigned i;

for (i = 0; i < KEY_PTRS(k); i++) {
struct cache *ca = PTR_CACHE(c, k, i);
struct bucket *g = PTR_BUCKET(c, k, i);

if (GC_SECTORS_USED(g) < ca->gc_move_threshold)
if (GC_MOVE(g))
return true;
}

Expand Down Expand Up @@ -65,11 +64,16 @@ static void write_moving_finish(struct closure *cl)

static void read_moving_endio(struct bio *bio, int error)
{
struct bbio *b = container_of(bio, struct bbio, bio);
struct moving_io *io = container_of(bio->bi_private,
struct moving_io, cl);

if (error)
io->op.error = error;
else if (!KEY_DIRTY(&b->key) &&
ptr_stale(io->op.c, &b->key, 0)) {
io->op.error = -EINTR;
}

bch_bbio_endio(io->op.c, bio, error, "reading data to move");
}
Expand Down Expand Up @@ -141,6 +145,11 @@ static void read_moving(struct cache_set *c)
if (!w)
break;

if (ptr_stale(c, &w->key, 0)) {
bch_keybuf_del(&c->moving_gc_keys, w);
continue;
}

io = kzalloc(sizeof(struct moving_io) + sizeof(struct bio_vec)
* DIV_ROUND_UP(KEY_SIZE(&w->key), PAGE_SECTORS),
GFP_KERNEL);
Expand Down Expand Up @@ -184,7 +193,8 @@ static bool bucket_cmp(struct bucket *l, struct bucket *r)

static unsigned bucket_heap_top(struct cache *ca)
{
return GC_SECTORS_USED(heap_peek(&ca->heap));
struct bucket *b;
return (b = heap_peek(&ca->heap)) ? GC_SECTORS_USED(b) : 0;
}

void bch_moving_gc(struct cache_set *c)
Expand Down Expand Up @@ -226,9 +236,8 @@ void bch_moving_gc(struct cache_set *c)
sectors_to_move -= GC_SECTORS_USED(b);
}

ca->gc_move_threshold = bucket_heap_top(ca);

pr_debug("threshold %u", ca->gc_move_threshold);
while (heap_pop(&ca->heap, b, bucket_cmp))
SET_GC_MOVE(b, 1);
}

mutex_unlock(&c->bucket_lock);
Expand Down
2 changes: 1 addition & 1 deletion drivers/md/bcache/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -1676,7 +1676,7 @@ static void run_cache_set(struct cache_set *c)
static bool can_attach_cache(struct cache *ca, struct cache_set *c)
{
return ca->sb.block_size == c->sb.block_size &&
ca->sb.bucket_size == c->sb.block_size &&
ca->sb.bucket_size == c->sb.bucket_size &&
ca->sb.nr_in_set == c->sb.nr_in_set;
}

Expand Down
50 changes: 29 additions & 21 deletions drivers/md/bcache/sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ rw_attribute(writeback_rate);
rw_attribute(writeback_rate_update_seconds);
rw_attribute(writeback_rate_d_term);
rw_attribute(writeback_rate_p_term_inverse);
rw_attribute(writeback_rate_d_smooth);
read_attribute(writeback_rate_debug);

read_attribute(stripe_size);
Expand Down Expand Up @@ -129,31 +128,41 @@ SHOW(__bch_cached_dev)
var_printf(writeback_running, "%i");
var_print(writeback_delay);
var_print(writeback_percent);
sysfs_print(writeback_rate, dc->writeback_rate.rate);
sysfs_hprint(writeback_rate, dc->writeback_rate.rate << 9);

var_print(writeback_rate_update_seconds);
var_print(writeback_rate_d_term);
var_print(writeback_rate_p_term_inverse);
var_print(writeback_rate_d_smooth);

if (attr == &sysfs_writeback_rate_debug) {
char rate[20];
char dirty[20];
char derivative[20];
char target[20];
bch_hprint(dirty,
bcache_dev_sectors_dirty(&dc->disk) << 9);
bch_hprint(derivative, dc->writeback_rate_derivative << 9);
char proportional[20];
char derivative[20];
char change[20];
s64 next_io;

bch_hprint(rate, dc->writeback_rate.rate << 9);
bch_hprint(dirty, bcache_dev_sectors_dirty(&dc->disk) << 9);
bch_hprint(target, dc->writeback_rate_target << 9);
bch_hprint(proportional,dc->writeback_rate_proportional << 9);
bch_hprint(derivative, dc->writeback_rate_derivative << 9);
bch_hprint(change, dc->writeback_rate_change << 9);

next_io = div64_s64(dc->writeback_rate.next - local_clock(),
NSEC_PER_MSEC);

return sprintf(buf,
"rate:\t\t%u\n"
"change:\t\t%i\n"
"rate:\t\t%s/sec\n"
"dirty:\t\t%s\n"
"target:\t\t%s\n"
"proportional:\t%s\n"
"derivative:\t%s\n"
"target:\t\t%s\n",
dc->writeback_rate.rate,
dc->writeback_rate_change,
dirty, derivative, target);
"change:\t\t%s/sec\n"
"next io:\t%llims\n",
rate, dirty, target, proportional,
derivative, change, next_io);
}

sysfs_hprint(dirty_data,
Expand Down Expand Up @@ -189,6 +198,7 @@ STORE(__cached_dev)
struct kobj_uevent_env *env;

#define d_strtoul(var) sysfs_strtoul(var, dc->var)
#define d_strtoul_nonzero(var) sysfs_strtoul_clamp(var, dc->var, 1, INT_MAX)
#define d_strtoi_h(var) sysfs_hatoi(var, dc->var)

sysfs_strtoul(data_csum, dc->disk.data_csum);
Expand All @@ -197,16 +207,15 @@ STORE(__cached_dev)
d_strtoul(writeback_metadata);
d_strtoul(writeback_running);
d_strtoul(writeback_delay);
sysfs_strtoul_clamp(writeback_rate,
dc->writeback_rate.rate, 1, 1000000);

sysfs_strtoul_clamp(writeback_percent, dc->writeback_percent, 0, 40);

d_strtoul(writeback_rate_update_seconds);
sysfs_strtoul_clamp(writeback_rate,
dc->writeback_rate.rate, 1, INT_MAX);

d_strtoul_nonzero(writeback_rate_update_seconds);
d_strtoul(writeback_rate_d_term);
d_strtoul(writeback_rate_p_term_inverse);
sysfs_strtoul_clamp(writeback_rate_p_term_inverse,
dc->writeback_rate_p_term_inverse, 1, INT_MAX);
d_strtoul(writeback_rate_d_smooth);
d_strtoul_nonzero(writeback_rate_p_term_inverse);

d_strtoi_h(sequential_cutoff);
d_strtoi_h(readahead);
Expand Down Expand Up @@ -313,7 +322,6 @@ static struct attribute *bch_cached_dev_files[] = {
&sysfs_writeback_rate_update_seconds,
&sysfs_writeback_rate_d_term,
&sysfs_writeback_rate_p_term_inverse,
&sysfs_writeback_rate_d_smooth,
&sysfs_writeback_rate_debug,
&sysfs_dirty_data,
&sysfs_stripe_size,
Expand Down
8 changes: 7 additions & 1 deletion drivers/md/bcache/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,13 @@ uint64_t bch_next_delay(struct bch_ratelimit *d, uint64_t done)
{
uint64_t now = local_clock();

d->next += div_u64(done, d->rate);
d->next += div_u64(done * NSEC_PER_SEC, d->rate);

if (time_before64(now + NSEC_PER_SEC, d->next))
d->next = now + NSEC_PER_SEC;

if (time_after64(now - NSEC_PER_SEC * 2, d->next))
d->next = now - NSEC_PER_SEC * 2;

return time_after64(d->next, now)
? div_u64(d->next - now, NSEC_PER_SEC / HZ)
Expand Down
2 changes: 1 addition & 1 deletion drivers/md/bcache/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ do { \
_r; \
})

#define heap_peek(h) ((h)->size ? (h)->data[0] : NULL)
#define heap_peek(h) ((h)->used ? (h)->data[0] : NULL)

#define heap_full(h) ((h)->used == (h)->size)

Expand Down
Loading

0 comments on commit 60e53a6

Please sign in to comment.