On Fri, 16 Jun 2017, tang.junhui@xxxxxxxxxx wrote: > > Hello Eric > > > > 3.10 is pretty old... I'm not sure what to suggest. Is there a > > writeback-gc race? > > This issue also exists in new version(such as 4.10 branch), > > When we test in the high branch, this problem is more easily to appear, > > so I am sure this bug still exists in bcache current code. Hi Tang, Try the patch below and see if that solves the problem. Also, see this thread: https://www.spinics.net/lists/linux-bcache/msg04620.html -- Eric Wheeler -------- Forwarded Message -------- Subject: [PATCH] md/bcache: Fix a deadlock while calculating writeback rate Date: Sun, 7 May 2017 17:52:22 +0200 From: Phillipp Röll <phillipp.roell@xxxxxxxxxxxxxx> To: bcache@xxxxxxxxxxxxxxxxxx CC: Phillipp Röll <phillipp.roell@xxxxxxxxxxxxxx> A bcache foreground write holds a read lock on the writeback_lock rwsem. In order to complete and release the lock after the actual write, it needs to update the index, which runs out of a workqueue. If the bch_writeback_thread is starting to write back dirty data while the foreground write still holds the lock, it tries to get a write lock on the writeback lock, thus blocking until the foreground write completes. If at this moment a workqueue worker starts an update of the write- back rate, while foreground write completions are queued behind it, the update thread will try to get a read lock, which blocks, because the writeback thread is trying to get a write lock. This blocks the foreground writes behind it and locks up all writeback and foreground writes. Removing the read lock from the writeback rate update thread is the simplest solution: the worst thing that will happen when the scan for dirty data is inconsistent is a wrong P-factor in the PID controller. Signed-off-by: Phillipp Röll <phillipp.roell@xxxxxxxxxxxxxx> --- drivers/md/bcache/writeback.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c index 6ac2e48..90da3bd 100644 --- a/drivers/md/bcache/writeback.c +++ b/drivers/md/bcache/writeback.c @@ -75,14 +75,10 @@ static void update_writeback_rate(struct work_struct *work) struct cached_dev, writeback_rate_update); - down_read(&dc->writeback_lock); - if (atomic_read(&dc->has_dirty) && dc->writeback_percent) __update_writeback_rate(dc); - up_read(&dc->writeback_lock); - schedule_delayed_work(&dc->writeback_rate_update, dc->writeback_rate_update_seconds * HZ); } -- 2.10.0