[PATCH 3/3] bcache: make writeback inflight configurable in sysfs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Dongsheng Yang <dongsheng.yang@xxxxxxxxxxxx>

This commit introduce a new sysfs file:
/sys/block/bcache0/bcache/writeback_inflight (read only)
/sys/block/bcache0/bcache/writeback_inflight_max (read write)

(1) read the writeback_inflight will output the current inflight writeback op.
(2)read the writeback_inflight_max will output the max number of writeback inflight.
(3) write the writeback_inflight_max can set the max number of writeback inflight,
valid range is [1, INT_MAX).

E.g:
 $ ll /sys/block/bcache0/bcache/writeback_inflight*
-r--r--r-- 1 root root 4096 Oct 27 08:45 /sys/block/bcache0/bcache/writeback_inflight
-rw-r--r-- 1 root root 4096 Oct 27 08:45 /sys/block/bcache0/bcache/writeback_inflight_max
 $ cat /sys/block/bcache0/bcache/writeback_inflight
0
 $ cat /sys/block/bcache0/bcache/writeback_inflight_max
64
 $ echo 1024 > /sys/block/bcache0/bcache/writeback_inflight_max
 $ cat /sys/block/bcache0/bcache/writeback_inflight_max
1024

Signed-off-by: Dongsheng Yang <dongsheng.yang@xxxxxxxxxxxx>
Signed-off-by: mingzhe <mingzhe.zou@xxxxxxxxxxxx>
---
 drivers/md/bcache/bcache.h    |  6 ++++-
 drivers/md/bcache/sysfs.c     | 20 ++++++++++++++++
 drivers/md/bcache/writeback.c | 43 ++++++++++++++++++++++++++++++++---
 3 files changed, 65 insertions(+), 4 deletions(-)

diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
index f1ea639defbe..82a6a2d293d0 100644
--- a/drivers/md/bcache/bcache.h
+++ b/drivers/md/bcache/bcache.h
@@ -337,7 +337,11 @@ struct cached_dev {
 	struct delayed_work	writeback_rate_update;
 
 	/* Limit number of writeback bios in flight */
-	struct semaphore	in_flight;
+	atomic_t		wb_inflight;
+	unsigned long		wb_inflight_max;
+	spinlock_t		wb_inflight_lock;
+	wait_queue_head_t	wb_inflight_wait;
+
 	struct task_struct	*writeback_thread;
 	struct workqueue_struct	*writeback_write_wq;
 
diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c
index f3f8fce74fab..8d1a86249f99 100644
--- a/drivers/md/bcache/sysfs.c
+++ b/drivers/md/bcache/sysfs.c
@@ -120,6 +120,8 @@ rw_attribute(writeback_running);
 rw_attribute(writeback_percent);
 rw_attribute(writeback_delay);
 rw_attribute(writeback_rate);
+read_attribute(writeback_inflight);
+rw_attribute(writeback_inflight_max);
 rw_attribute(writeback_consider_fragment);
 
 rw_attribute(writeback_rate_update_seconds);
@@ -204,6 +206,8 @@ SHOW(__bch_cached_dev)
 	var_printf(writeback_consider_fragment,	"%i");
 	var_print(writeback_delay);
 	var_print(writeback_percent);
+	sysfs_printf(writeback_inflight, "%i", atomic_read(&dc->wb_inflight));
+	sysfs_printf(writeback_inflight_max, "%li", dc->wb_inflight_max);
 	sysfs_hprint(writeback_rate,
 		     wb ? atomic_long_read(&dc->writeback_rate.rate) << 9 : 0);
 	sysfs_printf(io_errors,		"%i", atomic_read(&dc->io_errors));
@@ -451,6 +455,20 @@ STORE(__cached_dev)
 	if (attr == &sysfs_detach && dc->disk.c)
 		bch_cached_dev_detach(dc);
 
+	if (attr == &sysfs_writeback_inflight_max) {
+		ssize_t ret;
+		unsigned long v;
+
+		ret = strtoul_safe_clamp(buf, v, 1, INT_MAX);
+		if (ret)
+			return ret;
+
+		spin_lock(&dc->wb_inflight_lock);
+		dc->wb_inflight_max = v;
+		spin_unlock(&dc->wb_inflight_lock);
+		wake_up(&dc->wb_inflight_wait);
+	}
+
 	if (attr == &sysfs_stop)
 		bcache_device_stop(&dc->disk);
 
@@ -517,6 +535,8 @@ static struct attribute *bch_cached_dev_attrs[] = {
 	&sysfs_writeback_running,
 	&sysfs_writeback_delay,
 	&sysfs_writeback_percent,
+	&sysfs_writeback_inflight,
+	&sysfs_writeback_inflight_max,
 	&sysfs_writeback_rate,
 	&sysfs_writeback_consider_fragment,
 	&sysfs_writeback_rate_update_seconds,
diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c
index 7f60800e9f5f..6c33c2ad2e8d 100644
--- a/drivers/md/bcache/writeback.c
+++ b/drivers/md/bcache/writeback.c
@@ -428,6 +428,7 @@ static void dirty_io_destructor(struct closure *cl)
 	kfree(io);
 }
 
+static void end_wb_inflight(struct cached_dev *dc);
 static void write_dirty_finish(struct closure *cl)
 {
 	struct dirty_io *io = container_of(cl, struct dirty_io, cl);
@@ -465,7 +466,7 @@ static void write_dirty_finish(struct closure *cl)
 	}
 
 	bch_keybuf_del(&dc->writeback_keys, w);
-	up(&dc->in_flight);
+	end_wb_inflight(dc);
 
 	closure_return_with_destructor(cl, dirty_io_destructor);
 }
@@ -554,6 +555,38 @@ static void read_dirty_submit(struct closure *cl)
 	continue_at(cl, write_dirty, io->dc->writeback_write_wq);
 }
 
+static void start_wb_inflight(struct cached_dev *dc)
+{
+	DEFINE_WAIT(w);
+
+	spin_lock(&dc->wb_inflight_lock);
+	if (atomic_read(&dc->wb_inflight) < dc->wb_inflight_max)
+		goto out;
+
+	do {
+		prepare_to_wait(&dc->wb_inflight_wait, &w,
+				TASK_UNINTERRUPTIBLE);
+
+		spin_unlock(&dc->wb_inflight_lock);
+		schedule();
+		spin_lock(&dc->wb_inflight_lock);
+	} while (atomic_read(&dc->wb_inflight) >= dc->wb_inflight_max);
+
+	finish_wait(&dc->wb_inflight_wait, &w);
+
+out:
+	BUG_ON(atomic_inc_return(&dc->wb_inflight) > dc->wb_inflight_max);
+	spin_unlock(&dc->wb_inflight_lock);
+}
+
+static void end_wb_inflight(struct cached_dev *dc)
+{
+	spin_lock(&dc->wb_inflight_lock);
+	BUG_ON(atomic_dec_return(&dc->wb_inflight) < 0);
+	spin_unlock(&dc->wb_inflight_lock);
+	wake_up(&dc->wb_inflight_wait);
+}
+
 static void read_dirty(struct cached_dev *dc)
 {
 	unsigned int delay = 0;
@@ -641,7 +674,7 @@ static void read_dirty(struct cached_dev *dc)
 
 			trace_bcache_writeback(&w->key);
 
-			down(&dc->in_flight);
+			start_wb_inflight(dc);
 
 			/*
 			 * The number of tokens in the token bucket
@@ -1124,7 +1157,11 @@ void bch_sectors_dirty_init(struct bcache_device *d)
 
 void bch_cached_dev_writeback_init(struct cached_dev *dc)
 {
-	sema_init(&dc->in_flight, 64);
+	atomic_set(&dc->wb_inflight, 0);
+	dc->wb_inflight_max = 64;
+	spin_lock_init(&dc->wb_inflight_lock);
+	init_waitqueue_head(&dc->wb_inflight_wait);
+
 	init_rwsem(&dc->writeback_lock);
 	bch_keybuf_init(&dc->writeback_keys);
 
-- 
2.17.1




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux ARM Kernel]     [Linux Filesystem Development]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux