summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2016-11-17 11:11:16 -0900
committerKent Overstreet <kent.overstreet@gmail.com>2016-11-23 14:09:23 -0900
commit47a6c1dc3c75dfa7df8fffaaef97dd531b73cb24 (patch)
tree88ba994f8ff824849268ee9e40d930c404b4b747
parentb10861fb39e7c7a5a56cdc87ccf63f2a7e1e1f15 (diff)
bcache: Kill btree write work item, flush via journal reclaim
-rw-r--r--drivers/md/bcache/bcache.h1
-rw-r--r--drivers/md/bcache/btree_cache.c2
-rw-r--r--drivers/md/bcache/btree_io.c14
-rw-r--r--drivers/md/bcache/btree_io.h1
-rw-r--r--drivers/md/bcache/btree_types.h2
-rw-r--r--drivers/md/bcache/btree_update.c8
-rw-r--r--drivers/md/bcache/journal.c29
-rw-r--r--drivers/md/bcache/journal_types.h6
-rw-r--r--drivers/md/bcache/super.c3
-rw-r--r--drivers/md/bcache/sysfs.c20
10 files changed, 34 insertions, 52 deletions
diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
index 3f604fcd8560..ae2efdeedd24 100644
--- a/drivers/md/bcache/bcache.h
+++ b/drivers/md/bcache/bcache.h
@@ -758,7 +758,6 @@ struct cache_set {
mempool_t btree_sort_pool;
struct journal journal;
- unsigned btree_flush_delay;
/* CACHING OTHER BLOCK DEVICES */
mempool_t search;
diff --git a/drivers/md/bcache/btree_cache.c b/drivers/md/bcache/btree_cache.c
index 52cd2105add4..3ae92ef40039 100644
--- a/drivers/md/bcache/btree_cache.c
+++ b/drivers/md/bcache/btree_cache.c
@@ -87,7 +87,6 @@ static struct btree *mca_bucket_alloc(struct cache_set *c, gfp_t gfp)
six_lock_init(&b->lock);
INIT_LIST_HEAD(&b->list);
- INIT_DELAYED_WORK(&b->work, btree_node_write_work);
b->c = c;
b->writes[1].index = 1;
INIT_LIST_HEAD(&b->write_blocked);
@@ -351,7 +350,6 @@ void bch_btree_cache_free(struct cache_set *c)
b = list_first_entry(&c->btree_cache_freed,
struct btree, list);
list_del(&b->list);
- cancel_delayed_work_sync(&b->work);
kfree(b);
}
diff --git a/drivers/md/bcache/btree_io.c b/drivers/md/bcache/btree_io.c
index 59ba43e604e1..4b03e6b32243 100644
--- a/drivers/md/bcache/btree_io.c
+++ b/drivers/md/bcache/btree_io.c
@@ -587,11 +587,6 @@ static void btree_node_write_done(struct closure *cl)
bch_journal_halt(&c->journal);
bch_btree_complete_write(c, b, w);
-
- if (btree_node_dirty(b) && c->btree_flush_delay)
- queue_delayed_work(system_freezable_wq, &b->work,
- c->btree_flush_delay * HZ);
-
closure_return_with_destructor(cl, btree_node_write_unlock);
}
@@ -634,8 +629,6 @@ static void do_btree_node_write(struct closure *cl)
BUG_ON(btree_bset_first(b)->seq != i->seq);
BUG_ON(BSET_BIG_ENDIAN(i) != CPU_BIG_ENDIAN);
- cancel_delayed_work(&b->work);
-
change_bit(BTREE_NODE_write_idx, &b->flags);
i->version = cpu_to_le16(BCACHE_BSET_VERSION);
@@ -812,13 +805,6 @@ void bch_btree_node_write_lazy(struct btree *b, struct btree_iter *iter)
bch_btree_node_write(b, NULL, iter);
}
-void btree_node_write_work(struct work_struct *w)
-{
- struct btree *b = container_of(to_delayed_work(w), struct btree, work);
-
- bch_btree_node_write_dirty(b, NULL);
-}
-
/*
* Write all dirty btree nodes to disk, including roots
*/
diff --git a/drivers/md/bcache/btree_io.h b/drivers/md/bcache/btree_io.h
index d061ac36f88e..9fe2ec488537 100644
--- a/drivers/md/bcache/btree_io.h
+++ b/drivers/md/bcache/btree_io.h
@@ -36,7 +36,6 @@ void __bch_btree_node_write(struct btree *, struct closure *, int);
void bch_btree_node_write(struct btree *, struct closure *,
struct btree_iter *);
void bch_btree_node_write_lazy(struct btree *, struct btree_iter *);
-void btree_node_write_work(struct work_struct *);
void bch_btree_flush(struct cache_set *);
void bch_btree_node_flush_journal_entries(struct cache_set *, struct btree *,
diff --git a/drivers/md/bcache/btree_types.h b/drivers/md/bcache/btree_types.h
index 1274b3b8c7de..fc6bfe0dad46 100644
--- a/drivers/md/bcache/btree_types.h
+++ b/drivers/md/bcache/btree_types.h
@@ -76,8 +76,6 @@ struct btree {
struct list_head list;
struct closure io;
- struct delayed_work work;
-
struct btree_write writes[2];
};
diff --git a/drivers/md/bcache/btree_update.c b/drivers/md/bcache/btree_update.c
index b845d82bb9e5..75d5ed086546 100644
--- a/drivers/md/bcache/btree_update.c
+++ b/drivers/md/bcache/btree_update.c
@@ -168,7 +168,6 @@ static void __btree_node_free(struct cache_set *c, struct btree *b,
if (btree_node_dirty(b))
bch_btree_complete_write(c, b, btree_current_write(b));
clear_btree_node_dirty(b);
- cancel_delayed_work(&b->work);
mca_hash_remove(c, b);
@@ -775,13 +774,8 @@ void bch_btree_journal_key(struct btree_iter *iter,
cpu_to_le64(bch_journal_res_seq(j, res));
}
- if (!btree_node_dirty(b)) {
+ if (!btree_node_dirty(b))
set_btree_node_dirty(b);
-
- if (c->btree_flush_delay)
- queue_delayed_work(system_freezable_wq, &b->work,
- c->btree_flush_delay * HZ);
- }
}
static void verify_keys_sorted(struct keylist *l)
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c
index d37130c70396..07a51df9ed58 100644
--- a/drivers/md/bcache/journal.c
+++ b/drivers/md/bcache/journal.c
@@ -1216,7 +1216,7 @@ static int journal_entry_open(struct journal *j)
if (!old.prev_buf_unwritten)
mod_delayed_work(system_freezable_wq,
&j->write_work,
- msecs_to_jiffies(j->delay_ms));
+ msecs_to_jiffies(j->write_delay_ms));
}
return ret;
@@ -1271,7 +1271,7 @@ void bch_journal_start(struct cache_set *c)
spin_unlock(&j->lock);
- queue_work(system_freezable_wq, &j->reclaim_work);
+ queue_delayed_work(system_freezable_wq, &j->reclaim_work, 0);
}
int bch_journal_replay(struct cache_set *c, struct list_head *list)
@@ -1597,14 +1597,15 @@ static bool should_discard_bucket(struct journal *j, struct journal_device *ja)
*/
static void journal_reclaim_work(struct work_struct *work)
{
- struct cache_set *c = container_of(work, struct cache_set,
- journal.reclaim_work);
+ struct cache_set *c = container_of(to_delayed_work(work),
+ struct cache_set, journal.reclaim_work);
struct journal *j = &c->journal;
struct cache *ca;
struct journal_entry_pin *pin;
u64 seq_to_flush = 0;
unsigned iter, nr, bucket_to_flush;
bool reclaim_lock_held = false;
+ bool flushed = false;
/*
* Advance last_idx to point to the oldest journal entry containing
@@ -1665,10 +1666,17 @@ static void journal_reclaim_work(struct work_struct *work)
seq_to_flush = max_t(s64, seq_to_flush,
(s64) j->seq - (j->pin.size >> 1));
- while ((pin = journal_get_next_pin(j, seq_to_flush))) {
+ /* Ensure we always flush at least one journal pin: */
+
+ while ((pin = journal_get_next_pin(j, flushed ? seq_to_flush : U64_MAX))) {
__set_current_state(TASK_RUNNING);
pin->flush(j, pin);
+ flushed = true;
}
+
+ if (flushed && !test_bit(CACHE_SET_RO, &c->flags))
+ queue_delayed_work(system_freezable_wq, &j->reclaim_work,
+ msecs_to_jiffies(j->reclaim_delay_ms));
}
/**
@@ -1844,13 +1852,13 @@ static void journal_write_done(struct closure *cl)
if (journal_entry_is_open(j))
mod_delayed_work(system_freezable_wq, &j->write_work,
test_bit(JOURNAL_NEED_WRITE, &j->flags)
- ? 0 : msecs_to_jiffies(j->delay_ms));
+ ? 0 : msecs_to_jiffies(j->write_delay_ms));
/*
* Updating last_seq_ondisk may let journal_reclaim_work() discard more
* buckets:
*/
- queue_work(system_freezable_wq, &j->reclaim_work);
+ mod_delayed_work(system_freezable_wq, &j->reclaim_work, 0);
}
static void journal_write(struct closure *cl)
@@ -2046,7 +2054,7 @@ retry:
* Direct reclaim - can't rely on reclaim from work item
* due to freezing..
*/
- journal_reclaim_work(&j->reclaim_work);
+ journal_reclaim_work(&j->reclaim_work.work);
trace_bcache_journal_full(c);
blocked:
@@ -2229,14 +2237,15 @@ int bch_journal_alloc(struct journal *j)
spin_lock_init(&j->pin_lock);
init_waitqueue_head(&j->wait);
INIT_DELAYED_WORK(&j->write_work, journal_write_work);
- INIT_WORK(&j->reclaim_work, journal_reclaim_work);
+ INIT_DELAYED_WORK(&j->reclaim_work, journal_reclaim_work);
mutex_init(&j->blacklist_lock);
INIT_LIST_HEAD(&j->seq_blacklist);
mutex_init(&j->reclaim_lock);
lockdep_init_map(&j->res_map, "journal res", &res_key, 0);
- j->delay_ms = 10;
+ j->write_delay_ms = 100;
+ j->reclaim_delay_ms = 100;
bkey_extent_init(&j->key);
diff --git a/drivers/md/bcache/journal_types.h b/drivers/md/bcache/journal_types.h
index b40a2dfae25a..032b02e78625 100644
--- a/drivers/md/bcache/journal_types.h
+++ b/drivers/md/bcache/journal_types.h
@@ -128,8 +128,6 @@ struct journal {
struct closure io;
struct delayed_work write_work;
- unsigned delay_ms;
-
/* Sequence number of most recent journal entry (last entry in @pin) */
u64 seq;
@@ -166,13 +164,15 @@ struct journal {
BKEY_PADDED(key);
- struct work_struct reclaim_work;
+ struct delayed_work reclaim_work;
/* protects advancing ja->last_idx: */
struct mutex reclaim_lock;
__le64 prio_buckets[MAX_CACHES_PER_SET];
unsigned nr_prio_buckets;
+ unsigned write_delay_ms;
+ unsigned reclaim_delay_ms;
u64 res_get_blocked_start;
u64 need_write_time;
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index c834c57b0274..e1080b9e6e66 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -709,6 +709,7 @@ static void __bch_cache_set_read_only(struct cache_set *c)
bch_journal_meta(&c->journal);
cancel_delayed_work_sync(&c->journal.write_work);
+ cancel_delayed_work_sync(&c->journal.reclaim_work);
}
static void bch_writes_disabled(struct percpu_ref *writes)
@@ -1111,8 +1112,6 @@ static struct cache_set *bch_cache_set_alloc(struct cache_sb *sb,
c->writeback_pages_max = (256 << 10) / PAGE_SIZE;
- c->btree_flush_delay = 30;
-
c->copy_gc_enabled = 1;
c->tiering_enabled = 1;
c->tiering_percent = 10;
diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c
index 1c5f9f6f9689..985be520df52 100644
--- a/drivers/md/bcache/sysfs.c
+++ b/drivers/md/bcache/sysfs.c
@@ -128,7 +128,9 @@ sysfs_pd_controller_attribute(writeback);
read_attribute(stripe_size);
read_attribute(partial_stripes_expensive);
-rw_attribute(journal_delay_ms);
+rw_attribute(journal_write_delay_ms);
+rw_attribute(journal_reclaim_delay_ms);
+
rw_attribute(discard);
rw_attribute(running);
rw_attribute(label);
@@ -146,7 +148,6 @@ sysfs_pd_controller_attribute(tiering);
sysfs_pd_controller_attribute(foreground_write);
-rw_attribute(btree_flush_delay);
rw_attribute(pd_controllers_update_seconds);
rw_attribute(foreground_target_percent);
@@ -647,7 +648,8 @@ SHOW(bch_cache_set)
sysfs_print(minor, c->minor);
- sysfs_print(journal_delay_ms, c->journal.delay_ms);
+ sysfs_print(journal_write_delay_ms, c->journal.write_delay_ms);
+ sysfs_print(journal_reclaim_delay_ms, c->journal.reclaim_delay_ms);
sysfs_hprint(block_size, block_bytes(c));
sysfs_print(block_size_bytes, block_bytes(c));
@@ -698,8 +700,6 @@ SHOW(bch_cache_set)
sysfs_print(tiering_percent, c->tiering_percent);
sysfs_pd_controller_show(tiering, &c->tiering_pd);
- sysfs_print(btree_flush_delay, c->btree_flush_delay);
-
sysfs_printf(meta_replicas_have, "%llu",
CACHE_SET_META_REPLICAS_HAVE(&c->disk_sb));
sysfs_printf(data_replicas_have, "%llu",
@@ -771,7 +771,9 @@ STORE(__bch_cache_set)
return size;
}
- sysfs_strtoul(journal_delay_ms, c->journal.delay_ms);
+ sysfs_strtoul(journal_write_delay_ms, c->journal.write_delay_ms);
+ sysfs_strtoul(journal_reclaim_delay_ms, c->journal.reclaim_delay_ms);
+
sysfs_strtoul(foreground_write_ratelimit_enabled,
c->foreground_write_ratelimit_enabled);
@@ -798,8 +800,6 @@ STORE(__bch_cache_set)
sysfs_pd_controller_store(foreground_write, &c->foreground_write_pd);
- sysfs_strtoul(btree_flush_delay, c->btree_flush_delay);
-
if (attr == &sysfs_journal_flush) {
bch_journal_meta_async(&c->journal, NULL);
@@ -875,7 +875,8 @@ STORE(bch_cache_set)
static struct attribute *bch_cache_set_files[] = {
&sysfs_unregister,
&sysfs_stop,
- &sysfs_journal_delay_ms,
+ &sysfs_journal_write_delay_ms,
+ &sysfs_journal_reclaim_delay_ms,
&sysfs_blockdev_volume_create,
&sysfs_add_device,
@@ -901,7 +902,6 @@ static struct attribute *bch_cache_set_files[] = {
&sysfs_meta_replicas_have,
&sysfs_data_replicas_have,
- &sysfs_btree_flush_delay,
&sysfs_foreground_target_percent,
&sysfs_tiering_percent,