linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] f2fs: use IPU for cold files
@ 2017-08-08  1:42 Jaegeuk Kim
  2017-08-08  1:42 ` [PATCH 2/2] f2fs: introduce gc_urgent mode for background GC Jaegeuk Kim
  2017-08-08  2:57 ` [PATCH 1/2] f2fs: use IPU for cold files Chao Yu
  0 siblings, 2 replies; 7+ messages in thread
From: Jaegeuk Kim @ 2017-08-08  1:42 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel, linux-f2fs-devel; +Cc: Jaegeuk Kim

We expect cold files write data sequentially, but sometimes some of small data
can be updated, which incurs fragmentation.
Let's avoid that.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 fs/f2fs/segment.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
index 6b871b492fd5..7f700e54b77d 100644
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -577,6 +577,10 @@ static inline bool need_inplace_update_policy(struct inode *inode,
 	if (test_opt(sbi, LFS))
 		return false;
 
+	/* if this is cold file, we should overwrite to avoid fragmentation */
+	if (file_is_cold(inode))
+		return true;
+
 	if (policy & (0x1 << F2FS_IPU_FORCE))
 		return true;
 	if (policy & (0x1 << F2FS_IPU_SSR) && need_SSR(sbi))
-- 
2.13.0.rc1.294.g07d810a77f-goog

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/2] f2fs: introduce gc_urgent mode for background GC
  2017-08-08  1:42 [PATCH 1/2] f2fs: use IPU for cold files Jaegeuk Kim
@ 2017-08-08  1:42 ` Jaegeuk Kim
  2017-08-08  3:09   ` [PATCH 2/2 v2] " Jaegeuk Kim
                     ` (2 more replies)
  2017-08-08  2:57 ` [PATCH 1/2] f2fs: use IPU for cold files Chao Yu
  1 sibling, 3 replies; 7+ messages in thread
From: Jaegeuk Kim @ 2017-08-08  1:42 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel, linux-f2fs-devel; +Cc: Jaegeuk Kim

This patch adds a sysfs entry to control urgent mode for background GC.
If this is set, background GC thread conducts GC with gc_urgent_sleep_time
all the time.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 Documentation/ABI/testing/sysfs-fs-f2fs | 12 ++++++++++++
 fs/f2fs/gc.c                            | 17 +++++++++++++++--
 fs/f2fs/gc.h                            |  4 ++++
 fs/f2fs/sysfs.c                         |  9 +++++++++
 4 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
index c579ce5e0ef5..11b7f4ebea7c 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -139,3 +139,15 @@ Date:		June 2017
 Contact:	"Chao Yu" <yuchao0@huawei.com>
 Description:
 		 Controls current reserved blocks in system.
+
+What:		/sys/fs/f2fs/<disk>/gc_urgent
+Date:		August 2017
+Contact:	"Jaegeuk Kim" <jaegeuk@kernel.org>
+Description:
+		 Do background GC agressively
+
+What:		/sys/fs/f2fs/<disk>/gc_urgent_sleep_time
+Date:		August 2017
+Contact:	"Jaegeuk Kim" <jaegeuk@kernel.org>
+Description:
+		 Controls sleep time of GC urgent mode
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 620dca443b29..8da7c14a9d29 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -35,9 +35,14 @@ static int gc_thread_func(void *data)
 	set_freezable();
 	do {
 		wait_event_interruptible_timeout(*wq,
-				kthread_should_stop() || freezing(current),
+				kthread_should_stop() || freezing(current) ||
+				gc_th->gc_wake,
 				msecs_to_jiffies(wait_ms));
 
+		/* give it a try one time */
+		if (gc_th->gc_wake)
+			gc_th->gc_wake = 0;
+
 		if (try_to_freeze())
 			continue;
 		if (kthread_should_stop())
@@ -74,6 +79,11 @@ static int gc_thread_func(void *data)
 		if (!mutex_trylock(&sbi->gc_mutex))
 			goto next;
 
+		if (gc_th->gc_urgent) {
+			wait_ms = gc_th->urgent_sleep_time;
+			goto do_gc;
+		}
+
 		if (!is_idle(sbi)) {
 			increase_sleep_time(gc_th, &wait_ms);
 			mutex_unlock(&sbi->gc_mutex);
@@ -84,7 +94,7 @@ static int gc_thread_func(void *data)
 			decrease_sleep_time(gc_th, &wait_ms);
 		else
 			increase_sleep_time(gc_th, &wait_ms);
-
+do_gc:
 		stat_inc_bggc_count(sbi);
 
 		/* if return value is not zero, no victim was selected */
@@ -115,11 +125,14 @@ int start_gc_thread(struct f2fs_sb_info *sbi)
 		goto out;
 	}
 
+	gc_th->urgent_sleep_time = DEF_GC_THREAD_URGENT_SLEEP_TIME;
 	gc_th->min_sleep_time = DEF_GC_THREAD_MIN_SLEEP_TIME;
 	gc_th->max_sleep_time = DEF_GC_THREAD_MAX_SLEEP_TIME;
 	gc_th->no_gc_sleep_time = DEF_GC_THREAD_NOGC_SLEEP_TIME;
 
 	gc_th->gc_idle = 0;
+	gc_th->gc_urgent = 0;
+	gc_th->gc_wake= 0;
 
 	sbi->gc_thread = gc_th;
 	init_waitqueue_head(&sbi->gc_thread->gc_wait_queue_head);
diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h
index a993967dcdb9..57a9000ce3af 100644
--- a/fs/f2fs/gc.h
+++ b/fs/f2fs/gc.h
@@ -13,6 +13,7 @@
 						 * whether IO subsystem is idle
 						 * or not
 						 */
+#define DEF_GC_THREAD_URGENT_SLEEP_TIME	500	/* 500 ms */
 #define DEF_GC_THREAD_MIN_SLEEP_TIME	30000	/* milliseconds */
 #define DEF_GC_THREAD_MAX_SLEEP_TIME	60000
 #define DEF_GC_THREAD_NOGC_SLEEP_TIME	300000	/* wait 5 min */
@@ -27,12 +28,15 @@ struct f2fs_gc_kthread {
 	wait_queue_head_t gc_wait_queue_head;
 
 	/* for gc sleep time */
+	unsigned int urgent_sleep_time;
 	unsigned int min_sleep_time;
 	unsigned int max_sleep_time;
 	unsigned int no_gc_sleep_time;
 
 	/* for changing gc mode */
 	unsigned int gc_idle;
+	unsigned int gc_urgent;
+	unsigned int gc_wake;
 };
 
 struct gc_inode_list {
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 4e5a95e9e666..b769a3d776de 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -161,6 +161,10 @@ static ssize_t f2fs_sbi_store(struct f2fs_attr *a,
 
 	if (!strcmp(a->attr.name, "iostat_enable") && *ui == 0)
 		f2fs_reset_iostat(sbi);
+	if (!strcmp(a->attr.name, "gc_urgent") && t == 1 && sbi->gc_thread) {
+		sbi->gc_thread->gc_wake = 1;
+		wake_up_interruptible_all(&sbi->gc_thread->gc_wait_queue_head);
+	}
 
 	return count;
 }
@@ -240,10 +244,13 @@ static struct f2fs_attr f2fs_attr_##_name = {			\
 	.id	= _id,						\
 }
 
+F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_urgent_sleep_time,
+							urgent_sleep_time);
 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time);
 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time);
 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time);
 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_idle, gc_idle);
+F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_urgent, gc_urgent);
 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments);
 F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_small_discards, max_discards);
 F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, discard_granularity, discard_granularity);
@@ -281,10 +288,12 @@ F2FS_FEATURE_RO_ATTR(inode_checksum, FEAT_INODE_CHECKSUM);
 
 #define ATTR_LIST(name) (&f2fs_attr_##name.attr)
 static struct attribute *f2fs_attrs[] = {
+	ATTR_LIST(gc_urgent_sleep_time),
 	ATTR_LIST(gc_min_sleep_time),
 	ATTR_LIST(gc_max_sleep_time),
 	ATTR_LIST(gc_no_gc_sleep_time),
 	ATTR_LIST(gc_idle),
+	ATTR_LIST(gc_urgent),
 	ATTR_LIST(reclaim_segments),
 	ATTR_LIST(max_small_discards),
 	ATTR_LIST(discard_granularity),
-- 
2.13.0.rc1.294.g07d810a77f-goog

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/2] f2fs: use IPU for cold files
  2017-08-08  1:42 [PATCH 1/2] f2fs: use IPU for cold files Jaegeuk Kim
  2017-08-08  1:42 ` [PATCH 2/2] f2fs: introduce gc_urgent mode for background GC Jaegeuk Kim
@ 2017-08-08  2:57 ` Chao Yu
  1 sibling, 0 replies; 7+ messages in thread
From: Chao Yu @ 2017-08-08  2:57 UTC (permalink / raw)
  To: Jaegeuk Kim, linux-kernel, linux-fsdevel, linux-f2fs-devel

On 2017/8/8 9:42, Jaegeuk Kim wrote:
> We expect cold files write data sequentially, but sometimes some of small data
> can be updated, which incurs fragmentation.
> Let's avoid that.
> 
> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>

Reviewed-by: Chao Yu <yuchao0@huawei.com>

Thanks,

> ---
>  fs/f2fs/segment.h | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
> index 6b871b492fd5..7f700e54b77d 100644
> --- a/fs/f2fs/segment.h
> +++ b/fs/f2fs/segment.h
> @@ -577,6 +577,10 @@ static inline bool need_inplace_update_policy(struct inode *inode,
>  	if (test_opt(sbi, LFS))
>  		return false;
>  
> +	/* if this is cold file, we should overwrite to avoid fragmentation */
> +	if (file_is_cold(inode))
> +		return true;
> +
>  	if (policy & (0x1 << F2FS_IPU_FORCE))
>  		return true;
>  	if (policy & (0x1 << F2FS_IPU_SSR) && need_SSR(sbi))
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2 v2] f2fs: introduce gc_urgent mode for background GC
  2017-08-08  1:42 ` [PATCH 2/2] f2fs: introduce gc_urgent mode for background GC Jaegeuk Kim
@ 2017-08-08  3:09   ` Jaegeuk Kim
  2017-08-08  3:15   ` [PATCH 2/2] " Chao Yu
  2017-08-10 10:44   ` Chao Yu
  2 siblings, 0 replies; 7+ messages in thread
From: Jaegeuk Kim @ 2017-08-08  3:09 UTC (permalink / raw)
  To: linux-kernel, linux-fsdevel, linux-f2fs-devel

Change log from v1:
 - update Documentation.

This patch adds a sysfs entry to control urgent mode for background GC.
If this is set, background GC thread conducts GC with gc_urgent_sleep_time
all the time.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
 Documentation/ABI/testing/sysfs-fs-f2fs | 12 ++++++++++++
 Documentation/filesystems/f2fs.txt      |  9 +++++++++
 fs/f2fs/gc.c                            | 17 +++++++++++++++--
 fs/f2fs/gc.h                            |  4 ++++
 fs/f2fs/sysfs.c                         |  9 +++++++++
 5 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
index c579ce5e0ef5..11b7f4ebea7c 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -139,3 +139,15 @@ Date:		June 2017
 Contact:	"Chao Yu" <yuchao0@huawei.com>
 Description:
 		 Controls current reserved blocks in system.
+
+What:		/sys/fs/f2fs/<disk>/gc_urgent
+Date:		August 2017
+Contact:	"Jaegeuk Kim" <jaegeuk@kernel.org>
+Description:
+		 Do background GC agressively
+
+What:		/sys/fs/f2fs/<disk>/gc_urgent_sleep_time
+Date:		August 2017
+Contact:	"Jaegeuk Kim" <jaegeuk@kernel.org>
+Description:
+		 Controls sleep time of GC urgent mode
diff --git a/Documentation/filesystems/f2fs.txt b/Documentation/filesystems/f2fs.txt
index b8f495a8b67d..84f36896766c 100644
--- a/Documentation/filesystems/f2fs.txt
+++ b/Documentation/filesystems/f2fs.txt
@@ -210,6 +210,15 @@ Files in /sys/fs/f2fs/<devname>
                               gc_idle = 1 will select the Cost Benefit approach
                               & setting gc_idle = 2 will select the greedy approach.
 
+ gc_urgent                    This parameter controls triggering background GCs
+                              urgently or not. Setting gc_urgent = 0 [default]
+                              makes back to default behavior, while if it is set
+                              to 1, background thread starts to do GC by given
+                              gc_urgent_sleep_time interval.
+
+ gc_urgent_sleep_time         This parameter controls sleep time for gc_urgent.
+                              500 ms is set by default. See above gc_urgent.
+
  reclaim_segments             This parameter controls the number of prefree
                               segments to be reclaimed. If the number of prefree
 			      segments is larger than the number of segments
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 620dca443b29..8da7c14a9d29 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -35,9 +35,14 @@ static int gc_thread_func(void *data)
 	set_freezable();
 	do {
 		wait_event_interruptible_timeout(*wq,
-				kthread_should_stop() || freezing(current),
+				kthread_should_stop() || freezing(current) ||
+				gc_th->gc_wake,
 				msecs_to_jiffies(wait_ms));
 
+		/* give it a try one time */
+		if (gc_th->gc_wake)
+			gc_th->gc_wake = 0;
+
 		if (try_to_freeze())
 			continue;
 		if (kthread_should_stop())
@@ -74,6 +79,11 @@ static int gc_thread_func(void *data)
 		if (!mutex_trylock(&sbi->gc_mutex))
 			goto next;
 
+		if (gc_th->gc_urgent) {
+			wait_ms = gc_th->urgent_sleep_time;
+			goto do_gc;
+		}
+
 		if (!is_idle(sbi)) {
 			increase_sleep_time(gc_th, &wait_ms);
 			mutex_unlock(&sbi->gc_mutex);
@@ -84,7 +94,7 @@ static int gc_thread_func(void *data)
 			decrease_sleep_time(gc_th, &wait_ms);
 		else
 			increase_sleep_time(gc_th, &wait_ms);
-
+do_gc:
 		stat_inc_bggc_count(sbi);
 
 		/* if return value is not zero, no victim was selected */
@@ -115,11 +125,14 @@ int start_gc_thread(struct f2fs_sb_info *sbi)
 		goto out;
 	}
 
+	gc_th->urgent_sleep_time = DEF_GC_THREAD_URGENT_SLEEP_TIME;
 	gc_th->min_sleep_time = DEF_GC_THREAD_MIN_SLEEP_TIME;
 	gc_th->max_sleep_time = DEF_GC_THREAD_MAX_SLEEP_TIME;
 	gc_th->no_gc_sleep_time = DEF_GC_THREAD_NOGC_SLEEP_TIME;
 
 	gc_th->gc_idle = 0;
+	gc_th->gc_urgent = 0;
+	gc_th->gc_wake= 0;
 
 	sbi->gc_thread = gc_th;
 	init_waitqueue_head(&sbi->gc_thread->gc_wait_queue_head);
diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h
index a993967dcdb9..57a9000ce3af 100644
--- a/fs/f2fs/gc.h
+++ b/fs/f2fs/gc.h
@@ -13,6 +13,7 @@
 						 * whether IO subsystem is idle
 						 * or not
 						 */
+#define DEF_GC_THREAD_URGENT_SLEEP_TIME	500	/* 500 ms */
 #define DEF_GC_THREAD_MIN_SLEEP_TIME	30000	/* milliseconds */
 #define DEF_GC_THREAD_MAX_SLEEP_TIME	60000
 #define DEF_GC_THREAD_NOGC_SLEEP_TIME	300000	/* wait 5 min */
@@ -27,12 +28,15 @@ struct f2fs_gc_kthread {
 	wait_queue_head_t gc_wait_queue_head;
 
 	/* for gc sleep time */
+	unsigned int urgent_sleep_time;
 	unsigned int min_sleep_time;
 	unsigned int max_sleep_time;
 	unsigned int no_gc_sleep_time;
 
 	/* for changing gc mode */
 	unsigned int gc_idle;
+	unsigned int gc_urgent;
+	unsigned int gc_wake;
 };
 
 struct gc_inode_list {
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 4e5a95e9e666..b769a3d776de 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -161,6 +161,10 @@ static ssize_t f2fs_sbi_store(struct f2fs_attr *a,
 
 	if (!strcmp(a->attr.name, "iostat_enable") && *ui == 0)
 		f2fs_reset_iostat(sbi);
+	if (!strcmp(a->attr.name, "gc_urgent") && t == 1 && sbi->gc_thread) {
+		sbi->gc_thread->gc_wake = 1;
+		wake_up_interruptible_all(&sbi->gc_thread->gc_wait_queue_head);
+	}
 
 	return count;
 }
@@ -240,10 +244,13 @@ static struct f2fs_attr f2fs_attr_##_name = {			\
 	.id	= _id,						\
 }
 
+F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_urgent_sleep_time,
+							urgent_sleep_time);
 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time);
 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time);
 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time);
 F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_idle, gc_idle);
+F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_urgent, gc_urgent);
 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments);
 F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_small_discards, max_discards);
 F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, discard_granularity, discard_granularity);
@@ -281,10 +288,12 @@ F2FS_FEATURE_RO_ATTR(inode_checksum, FEAT_INODE_CHECKSUM);
 
 #define ATTR_LIST(name) (&f2fs_attr_##name.attr)
 static struct attribute *f2fs_attrs[] = {
+	ATTR_LIST(gc_urgent_sleep_time),
 	ATTR_LIST(gc_min_sleep_time),
 	ATTR_LIST(gc_max_sleep_time),
 	ATTR_LIST(gc_no_gc_sleep_time),
 	ATTR_LIST(gc_idle),
+	ATTR_LIST(gc_urgent),
 	ATTR_LIST(reclaim_segments),
 	ATTR_LIST(max_small_discards),
 	ATTR_LIST(discard_granularity),
-- 
2.13.0.rc1.294.g07d810a77f-goog

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] f2fs: introduce gc_urgent mode for background GC
  2017-08-08  1:42 ` [PATCH 2/2] f2fs: introduce gc_urgent mode for background GC Jaegeuk Kim
  2017-08-08  3:09   ` [PATCH 2/2 v2] " Jaegeuk Kim
@ 2017-08-08  3:15   ` Chao Yu
  2017-08-08  3:40     ` Jaegeuk Kim
  2017-08-10 10:44   ` Chao Yu
  2 siblings, 1 reply; 7+ messages in thread
From: Chao Yu @ 2017-08-08  3:15 UTC (permalink / raw)
  To: Jaegeuk Kim, linux-kernel, linux-fsdevel, linux-f2fs-devel

Hi Jaegeuk,

On 2017/8/8 9:42, Jaegeuk Kim wrote:
> This patch adds a sysfs entry to control urgent mode for background GC.
> If this is set, background GC thread conducts GC with gc_urgent_sleep_time
> all the time.

Good idea.

If we want to add more gc policy, current approach is not friendly to be
extended, and sysfs nodes are also become more and more, it's not friendly to
user. So I'd like to suggest adding /sys/fs/f2fs/<disk>/gc_policy only, and
exposing original policy as normal_mode, and then introduce urgent_mode and
reuse gc_min_sleep_time as gc_urgent_sleep_time in this patch.

e.g.

enum gc_policy {
	GC_NORMAL,
	GC_URGENT,
};

If we want to turn on urgent_mode, we could:
echo 1 > /sys/fs/f2fs/<disk>/gc_policy
echo 1000 > /sys/fs/f2fs/<disk>/gc_min_sleep_time

How do you think?

Thanks,

> 
> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
> ---
>  Documentation/ABI/testing/sysfs-fs-f2fs | 12 ++++++++++++
>  fs/f2fs/gc.c                            | 17 +++++++++++++++--
>  fs/f2fs/gc.h                            |  4 ++++
>  fs/f2fs/sysfs.c                         |  9 +++++++++
>  4 files changed, 40 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
> index c579ce5e0ef5..11b7f4ebea7c 100644
> --- a/Documentation/ABI/testing/sysfs-fs-f2fs
> +++ b/Documentation/ABI/testing/sysfs-fs-f2fs
> @@ -139,3 +139,15 @@ Date:		June 2017
>  Contact:	"Chao Yu" <yuchao0@huawei.com>
>  Description:
>  		 Controls current reserved blocks in system.
> +
> +What:		/sys/fs/f2fs/<disk>/gc_urgent
> +Date:		August 2017
> +Contact:	"Jaegeuk Kim" <jaegeuk@kernel.org>
> +Description:
> +		 Do background GC agressively
> +
> +What:		/sys/fs/f2fs/<disk>/gc_urgent_sleep_time
> +Date:		August 2017
> +Contact:	"Jaegeuk Kim" <jaegeuk@kernel.org>
> +Description:
> +		 Controls sleep time of GC urgent mode
> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> index 620dca443b29..8da7c14a9d29 100644
> --- a/fs/f2fs/gc.c
> +++ b/fs/f2fs/gc.c
> @@ -35,9 +35,14 @@ static int gc_thread_func(void *data)
>  	set_freezable();
>  	do {
>  		wait_event_interruptible_timeout(*wq,
> -				kthread_should_stop() || freezing(current),
> +				kthread_should_stop() || freezing(current) ||
> +				gc_th->gc_wake,
>  				msecs_to_jiffies(wait_ms));
>  
> +		/* give it a try one time */
> +		if (gc_th->gc_wake)
> +			gc_th->gc_wake = 0;
> +
>  		if (try_to_freeze())
>  			continue;
>  		if (kthread_should_stop())
> @@ -74,6 +79,11 @@ static int gc_thread_func(void *data)
>  		if (!mutex_trylock(&sbi->gc_mutex))
>  			goto next;
>  
> +		if (gc_th->gc_urgent) {
> +			wait_ms = gc_th->urgent_sleep_time;
> +			goto do_gc;
> +		}
> +
>  		if (!is_idle(sbi)) {
>  			increase_sleep_time(gc_th, &wait_ms);
>  			mutex_unlock(&sbi->gc_mutex);
> @@ -84,7 +94,7 @@ static int gc_thread_func(void *data)
>  			decrease_sleep_time(gc_th, &wait_ms);
>  		else
>  			increase_sleep_time(gc_th, &wait_ms);
> -
> +do_gc:
>  		stat_inc_bggc_count(sbi);
>  
>  		/* if return value is not zero, no victim was selected */
> @@ -115,11 +125,14 @@ int start_gc_thread(struct f2fs_sb_info *sbi)
>  		goto out;
>  	}
>  
> +	gc_th->urgent_sleep_time = DEF_GC_THREAD_URGENT_SLEEP_TIME;
>  	gc_th->min_sleep_time = DEF_GC_THREAD_MIN_SLEEP_TIME;
>  	gc_th->max_sleep_time = DEF_GC_THREAD_MAX_SLEEP_TIME;
>  	gc_th->no_gc_sleep_time = DEF_GC_THREAD_NOGC_SLEEP_TIME;
>  
>  	gc_th->gc_idle = 0;
> +	gc_th->gc_urgent = 0;
> +	gc_th->gc_wake= 0;
>  
>  	sbi->gc_thread = gc_th;
>  	init_waitqueue_head(&sbi->gc_thread->gc_wait_queue_head);
> diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h
> index a993967dcdb9..57a9000ce3af 100644
> --- a/fs/f2fs/gc.h
> +++ b/fs/f2fs/gc.h
> @@ -13,6 +13,7 @@
>  						 * whether IO subsystem is idle
>  						 * or not
>  						 */
> +#define DEF_GC_THREAD_URGENT_SLEEP_TIME	500	/* 500 ms */
>  #define DEF_GC_THREAD_MIN_SLEEP_TIME	30000	/* milliseconds */
>  #define DEF_GC_THREAD_MAX_SLEEP_TIME	60000
>  #define DEF_GC_THREAD_NOGC_SLEEP_TIME	300000	/* wait 5 min */
> @@ -27,12 +28,15 @@ struct f2fs_gc_kthread {
>  	wait_queue_head_t gc_wait_queue_head;
>  
>  	/* for gc sleep time */
> +	unsigned int urgent_sleep_time;
>  	unsigned int min_sleep_time;
>  	unsigned int max_sleep_time;
>  	unsigned int no_gc_sleep_time;
>  
>  	/* for changing gc mode */
>  	unsigned int gc_idle;
> +	unsigned int gc_urgent;
> +	unsigned int gc_wake;
>  };
>  
>  struct gc_inode_list {
> diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
> index 4e5a95e9e666..b769a3d776de 100644
> --- a/fs/f2fs/sysfs.c
> +++ b/fs/f2fs/sysfs.c
> @@ -161,6 +161,10 @@ static ssize_t f2fs_sbi_store(struct f2fs_attr *a,
>  
>  	if (!strcmp(a->attr.name, "iostat_enable") && *ui == 0)
>  		f2fs_reset_iostat(sbi);
> +	if (!strcmp(a->attr.name, "gc_urgent") && t == 1 && sbi->gc_thread) {
> +		sbi->gc_thread->gc_wake = 1;
> +		wake_up_interruptible_all(&sbi->gc_thread->gc_wait_queue_head);
> +	}
>  
>  	return count;
>  }
> @@ -240,10 +244,13 @@ static struct f2fs_attr f2fs_attr_##_name = {			\
>  	.id	= _id,						\
>  }
>  
> +F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_urgent_sleep_time,
> +							urgent_sleep_time);
>  F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time);
>  F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time);
>  F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time);
>  F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_idle, gc_idle);
> +F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_urgent, gc_urgent);
>  F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments);
>  F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_small_discards, max_discards);
>  F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, discard_granularity, discard_granularity);
> @@ -281,10 +288,12 @@ F2FS_FEATURE_RO_ATTR(inode_checksum, FEAT_INODE_CHECKSUM);
>  
>  #define ATTR_LIST(name) (&f2fs_attr_##name.attr)
>  static struct attribute *f2fs_attrs[] = {
> +	ATTR_LIST(gc_urgent_sleep_time),
>  	ATTR_LIST(gc_min_sleep_time),
>  	ATTR_LIST(gc_max_sleep_time),
>  	ATTR_LIST(gc_no_gc_sleep_time),
>  	ATTR_LIST(gc_idle),
> +	ATTR_LIST(gc_urgent),
>  	ATTR_LIST(reclaim_segments),
>  	ATTR_LIST(max_small_discards),
>  	ATTR_LIST(discard_granularity),
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] f2fs: introduce gc_urgent mode for background GC
  2017-08-08  3:15   ` [PATCH 2/2] " Chao Yu
@ 2017-08-08  3:40     ` Jaegeuk Kim
  0 siblings, 0 replies; 7+ messages in thread
From: Jaegeuk Kim @ 2017-08-08  3:40 UTC (permalink / raw)
  To: Chao Yu; +Cc: linux-kernel, linux-fsdevel, linux-f2fs-devel

Hi Chao,

On 08/08, Chao Yu wrote:
> Hi Jaegeuk,
> 
> On 2017/8/8 9:42, Jaegeuk Kim wrote:
> > This patch adds a sysfs entry to control urgent mode for background GC.
> > If this is set, background GC thread conducts GC with gc_urgent_sleep_time
> > all the time.
> 
> Good idea.
> 
> If we want to add more gc policy, current approach is not friendly to be
> extended, and sysfs nodes are also become more and more, it's not friendly to
> user. So I'd like to suggest adding /sys/fs/f2fs/<disk>/gc_policy only, and
> exposing original policy as normal_mode, and then introduce urgent_mode and
> reuse gc_min_sleep_time as gc_urgent_sleep_time in this patch.
> 
> e.g.
> 
> enum gc_policy {
> 	GC_NORMAL,
> 	GC_URGENT,
> };
> 
> If we want to turn on urgent_mode, we could:
> echo 1 > /sys/fs/f2fs/<disk>/gc_policy
> echo 1000 > /sys/fs/f2fs/<disk>/gc_min_sleep_time

I want to keep previous gc_min_sleep_time, so that user can go back to normal
state seamlessly.

Thanks,

> 
> How do you think?
> 
> Thanks,
> 
> > 
> > Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
> > ---
> >  Documentation/ABI/testing/sysfs-fs-f2fs | 12 ++++++++++++
> >  fs/f2fs/gc.c                            | 17 +++++++++++++++--
> >  fs/f2fs/gc.h                            |  4 ++++
> >  fs/f2fs/sysfs.c                         |  9 +++++++++
> >  4 files changed, 40 insertions(+), 2 deletions(-)
> > 
> > diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
> > index c579ce5e0ef5..11b7f4ebea7c 100644
> > --- a/Documentation/ABI/testing/sysfs-fs-f2fs
> > +++ b/Documentation/ABI/testing/sysfs-fs-f2fs
> > @@ -139,3 +139,15 @@ Date:		June 2017
> >  Contact:	"Chao Yu" <yuchao0@huawei.com>
> >  Description:
> >  		 Controls current reserved blocks in system.
> > +
> > +What:		/sys/fs/f2fs/<disk>/gc_urgent
> > +Date:		August 2017
> > +Contact:	"Jaegeuk Kim" <jaegeuk@kernel.org>
> > +Description:
> > +		 Do background GC agressively
> > +
> > +What:		/sys/fs/f2fs/<disk>/gc_urgent_sleep_time
> > +Date:		August 2017
> > +Contact:	"Jaegeuk Kim" <jaegeuk@kernel.org>
> > +Description:
> > +		 Controls sleep time of GC urgent mode
> > diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> > index 620dca443b29..8da7c14a9d29 100644
> > --- a/fs/f2fs/gc.c
> > +++ b/fs/f2fs/gc.c
> > @@ -35,9 +35,14 @@ static int gc_thread_func(void *data)
> >  	set_freezable();
> >  	do {
> >  		wait_event_interruptible_timeout(*wq,
> > -				kthread_should_stop() || freezing(current),
> > +				kthread_should_stop() || freezing(current) ||
> > +				gc_th->gc_wake,
> >  				msecs_to_jiffies(wait_ms));
> >  
> > +		/* give it a try one time */
> > +		if (gc_th->gc_wake)
> > +			gc_th->gc_wake = 0;
> > +
> >  		if (try_to_freeze())
> >  			continue;
> >  		if (kthread_should_stop())
> > @@ -74,6 +79,11 @@ static int gc_thread_func(void *data)
> >  		if (!mutex_trylock(&sbi->gc_mutex))
> >  			goto next;
> >  
> > +		if (gc_th->gc_urgent) {
> > +			wait_ms = gc_th->urgent_sleep_time;
> > +			goto do_gc;
> > +		}
> > +
> >  		if (!is_idle(sbi)) {
> >  			increase_sleep_time(gc_th, &wait_ms);
> >  			mutex_unlock(&sbi->gc_mutex);
> > @@ -84,7 +94,7 @@ static int gc_thread_func(void *data)
> >  			decrease_sleep_time(gc_th, &wait_ms);
> >  		else
> >  			increase_sleep_time(gc_th, &wait_ms);
> > -
> > +do_gc:
> >  		stat_inc_bggc_count(sbi);
> >  
> >  		/* if return value is not zero, no victim was selected */
> > @@ -115,11 +125,14 @@ int start_gc_thread(struct f2fs_sb_info *sbi)
> >  		goto out;
> >  	}
> >  
> > +	gc_th->urgent_sleep_time = DEF_GC_THREAD_URGENT_SLEEP_TIME;
> >  	gc_th->min_sleep_time = DEF_GC_THREAD_MIN_SLEEP_TIME;
> >  	gc_th->max_sleep_time = DEF_GC_THREAD_MAX_SLEEP_TIME;
> >  	gc_th->no_gc_sleep_time = DEF_GC_THREAD_NOGC_SLEEP_TIME;
> >  
> >  	gc_th->gc_idle = 0;
> > +	gc_th->gc_urgent = 0;
> > +	gc_th->gc_wake= 0;
> >  
> >  	sbi->gc_thread = gc_th;
> >  	init_waitqueue_head(&sbi->gc_thread->gc_wait_queue_head);
> > diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h
> > index a993967dcdb9..57a9000ce3af 100644
> > --- a/fs/f2fs/gc.h
> > +++ b/fs/f2fs/gc.h
> > @@ -13,6 +13,7 @@
> >  						 * whether IO subsystem is idle
> >  						 * or not
> >  						 */
> > +#define DEF_GC_THREAD_URGENT_SLEEP_TIME	500	/* 500 ms */
> >  #define DEF_GC_THREAD_MIN_SLEEP_TIME	30000	/* milliseconds */
> >  #define DEF_GC_THREAD_MAX_SLEEP_TIME	60000
> >  #define DEF_GC_THREAD_NOGC_SLEEP_TIME	300000	/* wait 5 min */
> > @@ -27,12 +28,15 @@ struct f2fs_gc_kthread {
> >  	wait_queue_head_t gc_wait_queue_head;
> >  
> >  	/* for gc sleep time */
> > +	unsigned int urgent_sleep_time;
> >  	unsigned int min_sleep_time;
> >  	unsigned int max_sleep_time;
> >  	unsigned int no_gc_sleep_time;
> >  
> >  	/* for changing gc mode */
> >  	unsigned int gc_idle;
> > +	unsigned int gc_urgent;
> > +	unsigned int gc_wake;
> >  };
> >  
> >  struct gc_inode_list {
> > diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
> > index 4e5a95e9e666..b769a3d776de 100644
> > --- a/fs/f2fs/sysfs.c
> > +++ b/fs/f2fs/sysfs.c
> > @@ -161,6 +161,10 @@ static ssize_t f2fs_sbi_store(struct f2fs_attr *a,
> >  
> >  	if (!strcmp(a->attr.name, "iostat_enable") && *ui == 0)
> >  		f2fs_reset_iostat(sbi);
> > +	if (!strcmp(a->attr.name, "gc_urgent") && t == 1 && sbi->gc_thread) {
> > +		sbi->gc_thread->gc_wake = 1;
> > +		wake_up_interruptible_all(&sbi->gc_thread->gc_wait_queue_head);
> > +	}
> >  
> >  	return count;
> >  }
> > @@ -240,10 +244,13 @@ static struct f2fs_attr f2fs_attr_##_name = {			\
> >  	.id	= _id,						\
> >  }
> >  
> > +F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_urgent_sleep_time,
> > +							urgent_sleep_time);
> >  F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_min_sleep_time, min_sleep_time);
> >  F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_max_sleep_time, max_sleep_time);
> >  F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time);
> >  F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_idle, gc_idle);
> > +F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_urgent, gc_urgent);
> >  F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments);
> >  F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_small_discards, max_discards);
> >  F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, discard_granularity, discard_granularity);
> > @@ -281,10 +288,12 @@ F2FS_FEATURE_RO_ATTR(inode_checksum, FEAT_INODE_CHECKSUM);
> >  
> >  #define ATTR_LIST(name) (&f2fs_attr_##name.attr)
> >  static struct attribute *f2fs_attrs[] = {
> > +	ATTR_LIST(gc_urgent_sleep_time),
> >  	ATTR_LIST(gc_min_sleep_time),
> >  	ATTR_LIST(gc_max_sleep_time),
> >  	ATTR_LIST(gc_no_gc_sleep_time),
> >  	ATTR_LIST(gc_idle),
> > +	ATTR_LIST(gc_urgent),
> >  	ATTR_LIST(reclaim_segments),
> >  	ATTR_LIST(max_small_discards),
> >  	ATTR_LIST(discard_granularity),
> > 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] f2fs: introduce gc_urgent mode for background GC
  2017-08-08  1:42 ` [PATCH 2/2] f2fs: introduce gc_urgent mode for background GC Jaegeuk Kim
  2017-08-08  3:09   ` [PATCH 2/2 v2] " Jaegeuk Kim
  2017-08-08  3:15   ` [PATCH 2/2] " Chao Yu
@ 2017-08-10 10:44   ` Chao Yu
  2 siblings, 0 replies; 7+ messages in thread
From: Chao Yu @ 2017-08-10 10:44 UTC (permalink / raw)
  To: Jaegeuk Kim, linux-kernel, linux-fsdevel, linux-f2fs-devel

On 2017/8/8 9:42, Jaegeuk Kim wrote:
> This patch adds a sysfs entry to control urgent mode for background GC.
> If this is set, background GC thread conducts GC with gc_urgent_sleep_time
> all the time.
> 
> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>

Reviewed-by: Chao Yu <yuchao0@huawei.com>

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2017-08-10 10:45 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-08  1:42 [PATCH 1/2] f2fs: use IPU for cold files Jaegeuk Kim
2017-08-08  1:42 ` [PATCH 2/2] f2fs: introduce gc_urgent mode for background GC Jaegeuk Kim
2017-08-08  3:09   ` [PATCH 2/2 v2] " Jaegeuk Kim
2017-08-08  3:15   ` [PATCH 2/2] " Chao Yu
2017-08-08  3:40     ` Jaegeuk Kim
2017-08-10 10:44   ` Chao Yu
2017-08-08  2:57 ` [PATCH 1/2] f2fs: use IPU for cold files Chao Yu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).