bcache: fix uninterruptible sleep in writeback thread
There were two issues here: - writeback thread did not start until the device first became dirty - writeback thread used uninterruptible sleep once running Without this patch I see kernel warnings printed and a load average of 1.52 after booting my test VM. With this patch the warnings are gone and the load average is near 0.00 as expected. Signed-off-by: Kent Overstreet <kmo@daterainc.com>
This commit is contained in:
parent
c5aa4a3157
commit
9e5c353510
|
@ -1042,6 +1042,9 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c)
|
|||
*/
|
||||
atomic_set(&dc->count, 1);
|
||||
|
||||
if (bch_cached_dev_writeback_start(dc))
|
||||
return -ENOMEM;
|
||||
|
||||
if (BDEV_STATE(&dc->sb) == BDEV_STATE_DIRTY) {
|
||||
bch_sectors_dirty_init(dc);
|
||||
atomic_set(&dc->has_dirty, 1);
|
||||
|
|
|
@ -239,7 +239,7 @@ static void read_dirty(struct cached_dev *dc)
|
|||
if (KEY_START(&w->key) != dc->last_read ||
|
||||
jiffies_to_msecs(delay) > 50)
|
||||
while (!kthread_should_stop() && delay)
|
||||
delay = schedule_timeout_uninterruptible(delay);
|
||||
delay = schedule_timeout_interruptible(delay);
|
||||
|
||||
dc->last_read = KEY_OFFSET(&w->key);
|
||||
|
||||
|
@ -436,7 +436,7 @@ static int bch_writeback_thread(void *arg)
|
|||
while (delay &&
|
||||
!kthread_should_stop() &&
|
||||
!test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags))
|
||||
delay = schedule_timeout_uninterruptible(delay);
|
||||
delay = schedule_timeout_interruptible(delay);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -478,7 +478,7 @@ void bch_sectors_dirty_init(struct cached_dev *dc)
|
|||
dc->disk.sectors_dirty_last = bcache_dev_sectors_dirty(&dc->disk);
|
||||
}
|
||||
|
||||
int bch_cached_dev_writeback_init(struct cached_dev *dc)
|
||||
void bch_cached_dev_writeback_init(struct cached_dev *dc)
|
||||
{
|
||||
sema_init(&dc->in_flight, 64);
|
||||
init_rwsem(&dc->writeback_lock);
|
||||
|
@ -494,14 +494,20 @@ int bch_cached_dev_writeback_init(struct cached_dev *dc)
|
|||
dc->writeback_rate_d_term = 30;
|
||||
dc->writeback_rate_p_term_inverse = 6000;
|
||||
|
||||
INIT_DELAYED_WORK(&dc->writeback_rate_update, update_writeback_rate);
|
||||
}
|
||||
|
||||
int bch_cached_dev_writeback_start(struct cached_dev *dc)
|
||||
{
|
||||
dc->writeback_thread = kthread_create(bch_writeback_thread, dc,
|
||||
"bcache_writeback");
|
||||
if (IS_ERR(dc->writeback_thread))
|
||||
return PTR_ERR(dc->writeback_thread);
|
||||
|
||||
INIT_DELAYED_WORK(&dc->writeback_rate_update, update_writeback_rate);
|
||||
schedule_delayed_work(&dc->writeback_rate_update,
|
||||
dc->writeback_rate_update_seconds * HZ);
|
||||
|
||||
bch_writeback_queue(dc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -85,6 +85,7 @@ static inline void bch_writeback_add(struct cached_dev *dc)
|
|||
void bcache_dev_sectors_dirty_add(struct cache_set *, unsigned, uint64_t, int);
|
||||
|
||||
void bch_sectors_dirty_init(struct cached_dev *dc);
|
||||
int bch_cached_dev_writeback_init(struct cached_dev *);
|
||||
void bch_cached_dev_writeback_init(struct cached_dev *);
|
||||
int bch_cached_dev_writeback_start(struct cached_dev *);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue