All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Reduce the overprovision size a lot in f2fs
@ 2017-02-17 12:53 ` Yunlong Song
  0 siblings, 0 replies; 11+ messages in thread
From: Yunlong Song @ 2017-02-17 12:53 UTC (permalink / raw)
  To: jaegeuk, cm224.lee, yuchao0, chao, sylinux, yunlong.song,
	miaoxie, zhouxiyu
  Cc: bintian.wang, linux-fsdevel, linux-f2fs-devel, linux-kernel

Rethink the meaning of reserved segments and overprovision segments in f2fs

The key issue is that flash FTL has already made overprovision itself, e.g. 7%,
according to the difference between gigabyte (GB) and gibibyte (GiB). And this
part can nenver be seen by the upper file system. The device capacity which it
tells the upper file system is the other part which does not include the
overprovision part, which means the whole device capacity that file system knows
can "all" be used for write safely. The overprovision flash FTL has already reserved
includes the needed capacity for garbage collection and other operations. So,
filesystem can just take it easy and do not need to set the reserved segments and
overprovision segments again in mkfs.f2fs.

I want to explain more in detail. First, let's forget the section alignment
issue in the following talk, since it is really not possible in real production
case. As a result, f2fs does not need to behave like flash (i.e., new write
must come after erase for a block page in flash).

Take a look at the current design of mkfs.f2fs:

	c.reserved_segments = (2 * (100 / c.overprovision + 1) + 6) * c.segs_per_sec;

The original motivation may be like this:

For example, if ovp is 20%, we select 5 victim segments to reclaim one free
segment in the worst case. During this migration, we need additional 4 free
segments to write valid blocks in the victim segments. Other remaining added
segments are just to keep as a buffer to prepare any abnormal situation.

But f2fs does not have to bahave like flash, so why do we need 4 more free segments
here? For current codes of f2fs gc, we only need 1 free segment:

Initial status: 1 free segment is needed

  segment 0     segment 1     segment 2     segment 3     segment 4     segment 5
|20% invalid| |20% invalid| |20% invalid| |20% invalid| |20% invalid|   | free |
|80%   valid| |80%   valid| |80%   valid| |80%   valid| |80%   valid|   | free |


step 1: segment 0 -> segment 5, free segment 0

  segment 0     segment 1     segment 2     segment 3     segment 4      segment 5
|    free   | |20% invalid| |20% invalid| |20% invalid| |20% invalid|   |20%  free|
|    free   | |80%   valid| |80%   valid| |80%   valid| |80%   valid|   |80% valid|


step 2: segment 1 -> segment 5 and segment 0, free segment 1

  segment 0     segment 1     segment 2     segment 3     segment 4      segment 5
|40%    free| |    free   | |20% invalid| |20% invalid| |20% invalid|   |20% valid|
|60%   valid| |    free   | |80%   valid| |80%   valid| |80%   valid|   |80% valid|


step 3: segment 2 -> segment 0 and segment 1, free segment 2

  segment 0     segment 1     segment 2     segment 3     segment 4      segment 5
|40%   valid| |60%    free| |    free   | |20% invalid| |20% invalid|   |20% valid|
|60%   valid| |40%   valid| |    free   | |80%   valid| |80%   valid|   |80% valid|


step 4: segment 3 -> segment 1 and segment 2, free segment 3

  segment 0     segment 1     segment 2     segment 3     segment 4      segment 5
|40%   valid| |60%   valid| |80%    free| |    free   | |20% invalid|   |20% valid|
|60%   valid| |40%   valid| |20%   valid| |    free   | |80%   valid|   |80% valid|


step 5: segment 4 -> segment 2, free segment 4

  segment 0     segment 1     segment 2     segment 3     segment 4      segment 5
|40%   valid| |60%   valid| |80%   valid| |    free   | |    free   |   |20% valid|
|60%   valid| |40%   valid| |20%   valid| |    free   | |    free   |   |80% valid|

done. Now there are 1 new free segment.

If we change the f2fs gc codes in future, we can even let the initial 1 free
segment go away, just copy valid data among the 5 segments themselves using SSR.

So the previous formula:

	c.reserved_segments = (2 * (100 / c.overprovision + 1) + 6) * c.segs_per_sec;

is not needed, we can set reserved_segments to any value if we want, no matter
what value c.overprovision is, just take it away from the formula.

And take take a look at the overprov_segment_count in current design of
mkfs.f2fs:

set_cp(overprov_segment_count, (get_sb(segment_count_main) - get_cp(rsvd_segment_count)) * c.overprovision / 100);

The original motivation may be like this:

For example, if ovp is 20%, the worst case is that each segment is 20% invalid,
then all the segments can not be selected as victim target for FTL GC, then
there is (segment_count_main - rsvd_segment_count) * 20%, which are all invalid
blocks and can not be used for write, thus we should regard this as
overprovision segments, which can never be used by user. However, as we
have explained above, all the device capacity which FTL tells f2fs can be used
for write, so it is not correct to use this formula. In fact, we do not need to set
the overprovision segments at all for this consideration.

Yunlong Song (2):
  mkfs.f2fs: add option to set the value of reserved segments
    and overprovision segments
  f2fs: fix the case when there is no free segment to allocate for
    CURSEG_WARM_NODE

 fs/f2fs/segment.c | 2 --
 1 file changed, 2 deletions(-)

-- 
1.8.5.2

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

* [PATCH 0/2] Reduce the overprovision size a lot in f2fs
@ 2017-02-17 12:53 ` Yunlong Song
  0 siblings, 0 replies; 11+ messages in thread
From: Yunlong Song @ 2017-02-17 12:53 UTC (permalink / raw)
  To: jaegeuk, cm224.lee, yuchao0, chao, sylinux, yunlong.song,
	miaoxie, zhouxiyu
  Cc: bintian.wang, linux-fsdevel, linux-f2fs-devel, linux-kernel

Rethink the meaning of reserved segments and overprovision segments in f2fs

The key issue is that flash FTL has already made overprovision itself, e.g. 7%,
according to the difference between gigabyte (GB) and gibibyte (GiB). And this
part can nenver be seen by the upper file system. The device capacity which it
tells the upper file system is the other part which does not include the
overprovision part, which means the whole device capacity that file system knows
can "all" be used for write safely. The overprovision flash FTL has already reserved
includes the needed capacity for garbage collection and other operations. So,
filesystem can just take it easy and do not need to set the reserved segments and
overprovision segments again in mkfs.f2fs.

I want to explain more in detail. First, let's forget the section alignment
issue in the following talk, since it is really not possible in real production
case. As a result, f2fs does not need to behave like flash (i.e., new write
must come after erase for a block page in flash).

Take a look at the current design of mkfs.f2fs:

	c.reserved_segments = (2 * (100 / c.overprovision + 1) + 6) * c.segs_per_sec;

The original motivation may be like this:

For example, if ovp is 20%, we select 5 victim segments to reclaim one free
segment in the worst case. During this migration, we need additional 4 free
segments to write valid blocks in the victim segments. Other remaining added
segments are just to keep as a buffer to prepare any abnormal situation.

But f2fs does not have to bahave like flash, so why do we need 4 more free segments
here? For current codes of f2fs gc, we only need 1 free segment:

Initial status: 1 free segment is needed

  segment 0     segment 1     segment 2     segment 3     segment 4     segment 5
|20% invalid| |20% invalid| |20% invalid| |20% invalid| |20% invalid|   | free |
|80%   valid| |80%   valid| |80%   valid| |80%   valid| |80%   valid|   | free |


step 1: segment 0 -> segment 5, free segment 0

  segment 0     segment 1     segment 2     segment 3     segment 4      segment 5
|    free   | |20% invalid| |20% invalid| |20% invalid| |20% invalid|   |20%  free|
|    free   | |80%   valid| |80%   valid| |80%   valid| |80%   valid|   |80% valid|


step 2: segment 1 -> segment 5 and segment 0, free segment 1

  segment 0     segment 1     segment 2     segment 3     segment 4      segment 5
|40%    free| |    free   | |20% invalid| |20% invalid| |20% invalid|   |20% valid|
|60%   valid| |    free   | |80%   valid| |80%   valid| |80%   valid|   |80% valid|


step 3: segment 2 -> segment 0 and segment 1, free segment 2

  segment 0     segment 1     segment 2     segment 3     segment 4      segment 5
|40%   valid| |60%    free| |    free   | |20% invalid| |20% invalid|   |20% valid|
|60%   valid| |40%   valid| |    free   | |80%   valid| |80%   valid|   |80% valid|


step 4: segment 3 -> segment 1 and segment 2, free segment 3

  segment 0     segment 1     segment 2     segment 3     segment 4      segment 5
|40%   valid| |60%   valid| |80%    free| |    free   | |20% invalid|   |20% valid|
|60%   valid| |40%   valid| |20%   valid| |    free   | |80%   valid|   |80% valid|


step 5: segment 4 -> segment 2, free segment 4

  segment 0     segment 1     segment 2     segment 3     segment 4      segment 5
|40%   valid| |60%   valid| |80%   valid| |    free   | |    free   |   |20% valid|
|60%   valid| |40%   valid| |20%   valid| |    free   | |    free   |   |80% valid|

done. Now there are 1 new free segment.

If we change the f2fs gc codes in future, we can even let the initial 1 free
segment go away, just copy valid data among the 5 segments themselves using SSR.

So the previous formula:

	c.reserved_segments = (2 * (100 / c.overprovision + 1) + 6) * c.segs_per_sec;

is not needed, we can set reserved_segments to any value if we want, no matter
what value c.overprovision is, just take it away from the formula.

And take take a look at the overprov_segment_count in current design of
mkfs.f2fs:

set_cp(overprov_segment_count, (get_sb(segment_count_main) - get_cp(rsvd_segment_count)) * c.overprovision / 100);

The original motivation may be like this:

For example, if ovp is 20%, the worst case is that each segment is 20% invalid,
then all the segments can not be selected as victim target for FTL GC, then
there is (segment_count_main - rsvd_segment_count) * 20%, which are all invalid
blocks and can not be used for write, thus we should regard this as
overprovision segments, which can never be used by user. However, as we
have explained above, all the device capacity which FTL tells f2fs can be used
for write, so it is not correct to use this formula. In fact, we do not need to set
the overprovision segments at all for this consideration.

Yunlong Song (2):
  mkfs.f2fs: add option to set the value of reserved segments
    and overprovision segments
  f2fs: fix the case when there is no free segment to allocate for
    CURSEG_WARM_NODE

 fs/f2fs/segment.c | 2 --
 1 file changed, 2 deletions(-)

-- 
1.8.5.2

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

* [PATCH 1/2] mkfs.f2fs: add option to set the value of reserved segments and overprovision segments
  2017-02-17 12:53 ` Yunlong Song
@ 2017-02-17 12:53   ` Yunlong Song
  -1 siblings, 0 replies; 11+ messages in thread
From: Yunlong Song @ 2017-02-17 12:53 UTC (permalink / raw)
  To: jaegeuk, cm224.lee, yuchao0, chao, sylinux, yunlong.song,
	miaoxie, zhouxiyu
  Cc: bintian.wang, linux-fsdevel, linux-f2fs-devel, linux-kernel

Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
---
 include/f2fs_fs.h       |  3 +++
 lib/libf2fs.c           |  3 +++
 mkfs/f2fs_format.c      | 21 ++++++++++++++-------
 mkfs/f2fs_format_main.c | 10 +++++++++-
 4 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index 97ee297..2a62660 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -304,6 +304,9 @@ struct f2fs_configuration {
 	/* sload parameters */
 	char *from_dir;
 	char *mount_point;
+
+	u_int32_t force_rsvd;
+	u_int32_t force_ovp;
 } __attribute__((packed));
 
 #ifdef CONFIG_64BIT
diff --git a/lib/libf2fs.c b/lib/libf2fs.c
index 93d3da9..971fe99 100644
--- a/lib/libf2fs.c
+++ b/lib/libf2fs.c
@@ -573,6 +573,9 @@ void f2fs_init_configuration(void)
 	c.trim = 1;
 	c.ro = 0;
 	c.kd = -1;
+
+	c.force_rsvd = 0;
+	c.force_ovp = 0;
 }
 
 static int is_mounted(const char *mpt, const char *device)
diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c
index 3c13026..42a7bd5 100644
--- a/mkfs/f2fs_format.c
+++ b/mkfs/f2fs_format.c
@@ -337,9 +337,12 @@ static int f2fs_prepare_super_block(void)
 	if (c.overprovision == 0)
 		c.overprovision = get_best_overprovision(sb);
 
-	c.reserved_segments =
-			(2 * (100 / c.overprovision + 1) + 6)
-			* c.segs_per_sec;
+	if (c.force_rsvd)
+		c.reserved_segments = c.force_rsvd;
+	else
+		c.reserved_segments =
+				(2 * (100 / c.overprovision + 1) + 6)
+				* c.segs_per_sec;
 
 	if (c.overprovision == 0 || c.total_segments < F2FS_MIN_SEGMENTS ||
 		(c.devices[0].total_sectors *
@@ -522,13 +525,17 @@ static int f2fs_write_check_point_pack(void)
 	set_cp(cur_data_blkoff[0], 1);
 	set_cp(valid_block_count, 2);
 	set_cp(rsvd_segment_count, c.reserved_segments);
-	set_cp(overprov_segment_count, (get_sb(segment_count_main) -
-			get_cp(rsvd_segment_count)) *
-			c.overprovision / 100);
+	if (c.force_ovp)
+		set_cp(overprov_segment_count, c.force_ovp);
+	else
+		set_cp(overprov_segment_count, (get_sb(segment_count_main) -
+				get_cp(rsvd_segment_count)) *
+				c.overprovision / 100);
 	set_cp(overprov_segment_count, get_cp(overprov_segment_count) +
 			get_cp(rsvd_segment_count));
 
-	MSG(0, "Info: Overprovision ratio = %.3lf%%\n", c.overprovision);
+	if (c.force_rsvd == 0 || c.force_ovp == 0)
+		MSG(0, "Info: Overprovision ratio = %.3lf%%\n", c.overprovision);
 	MSG(0, "Info: Overprovision segments = %u (GC reserved = %u)\n",
 					get_cp(overprov_segment_count),
 					c.reserved_segments);
diff --git a/mkfs/f2fs_format_main.c b/mkfs/f2fs_format_main.c
index 5bb1faf..45c513b 100644
--- a/mkfs/f2fs_format_main.c
+++ b/mkfs/f2fs_format_main.c
@@ -39,6 +39,8 @@ static void mkfs_usage()
 	MSG(0, "  -z # of sections per zone [default:1]\n");
 	MSG(0, "  -t 0: nodiscard, 1: discard [default:1]\n");
 	MSG(0, "  -m support zoned block device [default:0]\n");
+	MSG(0, "  -r force set reserved segments\n");
+	MSG(0, "  -R force set overprovision segments\n");
 	MSG(0, "sectors: number of sectors. [default: determined by device size]\n");
 	exit(1);
 }
@@ -72,7 +74,7 @@ static void parse_feature(const char *features)
 
 static void f2fs_parse_options(int argc, char *argv[])
 {
-	static const char *option_string = "qa:c:d:e:l:mo:O:s:z:t:";
+	static const char *option_string = "qa:c:d:e:l:mo:O:s:z:t:r:R:";
 	int32_t option=0;
 
 	while ((option = getopt(argc,argv,option_string)) != EOF) {
@@ -128,6 +130,12 @@ static void f2fs_parse_options(int argc, char *argv[])
 		case 't':
 			c.trim = atoi(optarg);
 			break;
+		case 'r':
+			c.force_rsvd = atoi(optarg);
+			break;
+		case 'R':
+			c.force_ovp = atoi(optarg);
+			break;
 		default:
 			MSG(0, "\tError: Unknown option %c\n",option);
 			mkfs_usage();
-- 
1.8.5.2

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

* [PATCH 1/2] mkfs.f2fs: add option to set the value of reserved segments and overprovision segments
@ 2017-02-17 12:53   ` Yunlong Song
  0 siblings, 0 replies; 11+ messages in thread
From: Yunlong Song @ 2017-02-17 12:53 UTC (permalink / raw)
  To: jaegeuk, cm224.lee, yuchao0, chao, sylinux, yunlong.song,
	miaoxie, zhouxiyu
  Cc: bintian.wang, linux-fsdevel, linux-f2fs-devel, linux-kernel

Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
---
 include/f2fs_fs.h       |  3 +++
 lib/libf2fs.c           |  3 +++
 mkfs/f2fs_format.c      | 21 ++++++++++++++-------
 mkfs/f2fs_format_main.c | 10 +++++++++-
 4 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index 97ee297..2a62660 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -304,6 +304,9 @@ struct f2fs_configuration {
 	/* sload parameters */
 	char *from_dir;
 	char *mount_point;
+
+	u_int32_t force_rsvd;
+	u_int32_t force_ovp;
 } __attribute__((packed));
 
 #ifdef CONFIG_64BIT
diff --git a/lib/libf2fs.c b/lib/libf2fs.c
index 93d3da9..971fe99 100644
--- a/lib/libf2fs.c
+++ b/lib/libf2fs.c
@@ -573,6 +573,9 @@ void f2fs_init_configuration(void)
 	c.trim = 1;
 	c.ro = 0;
 	c.kd = -1;
+
+	c.force_rsvd = 0;
+	c.force_ovp = 0;
 }
 
 static int is_mounted(const char *mpt, const char *device)
diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c
index 3c13026..42a7bd5 100644
--- a/mkfs/f2fs_format.c
+++ b/mkfs/f2fs_format.c
@@ -337,9 +337,12 @@ static int f2fs_prepare_super_block(void)
 	if (c.overprovision == 0)
 		c.overprovision = get_best_overprovision(sb);
 
-	c.reserved_segments =
-			(2 * (100 / c.overprovision + 1) + 6)
-			* c.segs_per_sec;
+	if (c.force_rsvd)
+		c.reserved_segments = c.force_rsvd;
+	else
+		c.reserved_segments =
+				(2 * (100 / c.overprovision + 1) + 6)
+				* c.segs_per_sec;
 
 	if (c.overprovision == 0 || c.total_segments < F2FS_MIN_SEGMENTS ||
 		(c.devices[0].total_sectors *
@@ -522,13 +525,17 @@ static int f2fs_write_check_point_pack(void)
 	set_cp(cur_data_blkoff[0], 1);
 	set_cp(valid_block_count, 2);
 	set_cp(rsvd_segment_count, c.reserved_segments);
-	set_cp(overprov_segment_count, (get_sb(segment_count_main) -
-			get_cp(rsvd_segment_count)) *
-			c.overprovision / 100);
+	if (c.force_ovp)
+		set_cp(overprov_segment_count, c.force_ovp);
+	else
+		set_cp(overprov_segment_count, (get_sb(segment_count_main) -
+				get_cp(rsvd_segment_count)) *
+				c.overprovision / 100);
 	set_cp(overprov_segment_count, get_cp(overprov_segment_count) +
 			get_cp(rsvd_segment_count));
 
-	MSG(0, "Info: Overprovision ratio = %.3lf%%\n", c.overprovision);
+	if (c.force_rsvd == 0 || c.force_ovp == 0)
+		MSG(0, "Info: Overprovision ratio = %.3lf%%\n", c.overprovision);
 	MSG(0, "Info: Overprovision segments = %u (GC reserved = %u)\n",
 					get_cp(overprov_segment_count),
 					c.reserved_segments);
diff --git a/mkfs/f2fs_format_main.c b/mkfs/f2fs_format_main.c
index 5bb1faf..45c513b 100644
--- a/mkfs/f2fs_format_main.c
+++ b/mkfs/f2fs_format_main.c
@@ -39,6 +39,8 @@ static void mkfs_usage()
 	MSG(0, "  -z # of sections per zone [default:1]\n");
 	MSG(0, "  -t 0: nodiscard, 1: discard [default:1]\n");
 	MSG(0, "  -m support zoned block device [default:0]\n");
+	MSG(0, "  -r force set reserved segments\n");
+	MSG(0, "  -R force set overprovision segments\n");
 	MSG(0, "sectors: number of sectors. [default: determined by device size]\n");
 	exit(1);
 }
@@ -72,7 +74,7 @@ static void parse_feature(const char *features)
 
 static void f2fs_parse_options(int argc, char *argv[])
 {
-	static const char *option_string = "qa:c:d:e:l:mo:O:s:z:t:";
+	static const char *option_string = "qa:c:d:e:l:mo:O:s:z:t:r:R:";
 	int32_t option=0;
 
 	while ((option = getopt(argc,argv,option_string)) != EOF) {
@@ -128,6 +130,12 @@ static void f2fs_parse_options(int argc, char *argv[])
 		case 't':
 			c.trim = atoi(optarg);
 			break;
+		case 'r':
+			c.force_rsvd = atoi(optarg);
+			break;
+		case 'R':
+			c.force_ovp = atoi(optarg);
+			break;
 		default:
 			MSG(0, "\tError: Unknown option %c\n",option);
 			mkfs_usage();
-- 
1.8.5.2

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

* [PATCH 2/2] f2fs: fix the case when there is no free segment to allocate for CURSEG_WARM_NODE
  2017-02-17 12:53 ` Yunlong Song
@ 2017-02-17 12:53   ` Yunlong Song
  -1 siblings, 0 replies; 11+ messages in thread
From: Yunlong Song @ 2017-02-17 12:53 UTC (permalink / raw)
  To: jaegeuk, cm224.lee, yuchao0, chao, sylinux, yunlong.song,
	miaoxie, zhouxiyu
  Cc: bintian.wang, linux-fsdevel, linux-f2fs-devel, linux-kernel

If the free segments are used up, then new_curseg will fail for
CURSEG_WARM_NODE, in this case, we should use change_curseg instead of
new_curseg.

Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
---
 fs/f2fs/segment.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index df2ff5c..32820cd 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -1564,8 +1564,6 @@ static void allocate_segment_by_default(struct f2fs_sb_info *sbi,
 
 	if (force)
 		new_curseg(sbi, type, true);
-	else if (type == CURSEG_WARM_NODE)
-		new_curseg(sbi, type, false);
 	else if (curseg->alloc_type == LFS && is_next_segment_free(sbi, type))
 		new_curseg(sbi, type, false);
 	else if (need_SSR(sbi) && get_ssr_segment(sbi, type))
-- 
1.8.5.2

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

* [PATCH 2/2] f2fs: fix the case when there is no free segment to allocate for CURSEG_WARM_NODE
@ 2017-02-17 12:53   ` Yunlong Song
  0 siblings, 0 replies; 11+ messages in thread
From: Yunlong Song @ 2017-02-17 12:53 UTC (permalink / raw)
  To: jaegeuk, cm224.lee, yuchao0, chao, sylinux, yunlong.song,
	miaoxie, zhouxiyu
  Cc: bintian.wang, linux-fsdevel, linux-f2fs-devel, linux-kernel

If the free segments are used up, then new_curseg will fail for
CURSEG_WARM_NODE, in this case, we should use change_curseg instead of
new_curseg.

Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
---
 fs/f2fs/segment.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index df2ff5c..32820cd 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -1564,8 +1564,6 @@ static void allocate_segment_by_default(struct f2fs_sb_info *sbi,
 
 	if (force)
 		new_curseg(sbi, type, true);
-	else if (type == CURSEG_WARM_NODE)
-		new_curseg(sbi, type, false);
 	else if (curseg->alloc_type == LFS && is_next_segment_free(sbi, type))
 		new_curseg(sbi, type, false);
 	else if (need_SSR(sbi) && get_ssr_segment(sbi, type))
-- 
1.8.5.2

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

* Re: [PATCH 2/2] f2fs: fix the case when there is no free segment to allocate for CURSEG_WARM_NODE
  2017-02-17 12:53   ` Yunlong Song
  (?)
@ 2017-02-17 18:39   ` Jaegeuk Kim
  2017-02-23 12:06       ` Chao Yu
  -1 siblings, 1 reply; 11+ messages in thread
From: Jaegeuk Kim @ 2017-02-17 18:39 UTC (permalink / raw)
  To: Yunlong Song
  Cc: cm224.lee, yuchao0, chao, sylinux, miaoxie, zhouxiyu,
	bintian.wang, linux-fsdevel, linux-f2fs-devel, linux-kernel

Hi Yunlong,

I already started to test this since a couple of days ago. :)

http://git.kernel.org/cgit/linux/kernel/git/jaegeuk/f2fs.git/commit/?h=dev-test&id=908b5f463c82eaf972b149a26bb310f5e25064fd

Thanks,

On 02/17, Yunlong Song wrote:
> If the free segments are used up, then new_curseg will fail for
> CURSEG_WARM_NODE, in this case, we should use change_curseg instead of
> new_curseg.
> 
> Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
> ---
>  fs/f2fs/segment.c | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index df2ff5c..32820cd 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -1564,8 +1564,6 @@ static void allocate_segment_by_default(struct f2fs_sb_info *sbi,
>  
>  	if (force)
>  		new_curseg(sbi, type, true);
> -	else if (type == CURSEG_WARM_NODE)
> -		new_curseg(sbi, type, false);
>  	else if (curseg->alloc_type == LFS && is_next_segment_free(sbi, type))
>  		new_curseg(sbi, type, false);
>  	else if (need_SSR(sbi) && get_ssr_segment(sbi, type))
> -- 
> 1.8.5.2

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

* Re: [PATCH 0/2] Reduce the overprovision size a lot in f2fs
  2017-02-17 12:53 ` Yunlong Song
                   ` (2 preceding siblings ...)
  (?)
@ 2017-02-17 19:33 ` Jaegeuk Kim
  -1 siblings, 0 replies; 11+ messages in thread
From: Jaegeuk Kim @ 2017-02-17 19:33 UTC (permalink / raw)
  To: Yunlong Song
  Cc: cm224.lee, yuchao0, chao, sylinux, miaoxie, zhouxiyu,
	bintian.wang, linux-fsdevel, linux-f2fs-devel, linux-kernel

Hi Yunlong,

On 02/17, Yunlong Song wrote:
> Rethink the meaning of reserved segments and overprovision segments in f2fs
> 
> The key issue is that flash FTL has already made overprovision itself, e.g. 7%,
> according to the difference between gigabyte (GB) and gibibyte (GiB). And this
> part can nenver be seen by the upper file system. The device capacity which it
> tells the upper file system is the other part which does not include the
> overprovision part, which means the whole device capacity that file system knows
> can "all" be used for write safely. The overprovision flash FTL has already reserved
> includes the needed capacity for garbage collection and other operations. So,
> filesystem can just take it easy and do not need to set the reserved segments and
> overprovision segments again in mkfs.f2fs.
>
> I want to explain more in detail. First, let's forget the section alignment
> issue in the following talk, since it is really not possible in real production
> case. As a result, f2fs does not need to behave like flash (i.e., new write
> must come after erase for a block page in flash).

Simply say no, F2FS has nothing to do with FTL, and LFS acts like flash.

> Take a look at the current design of mkfs.f2fs:
> 
> 	c.reserved_segments = (2 * (100 / c.overprovision + 1) + 6) * c.segs_per_sec;
> 
> The original motivation may be like this:
> 
> For example, if ovp is 20%, we select 5 victim segments to reclaim one free
> segment in the worst case. During this migration, we need additional 4 free
> segments to write valid blocks in the victim segments. Other remaining added
> segments are just to keep as a buffer to prepare any abnormal situation.
> 
> But f2fs does not have to bahave like flash, so why do we need 4 more free segments
> here? For current codes of f2fs gc, we only need 1 free segment:
> 
> Initial status: 1 free segment is needed
> 
>   segment 0     segment 1     segment 2     segment 3     segment 4     segment 5
> |20% invalid| |20% invalid| |20% invalid| |20% invalid| |20% invalid|   | free |
> |80%   valid| |80%   valid| |80%   valid| |80%   valid| |80%   valid|   | free |
> 
> 
> step 1: segment 0 -> segment 5, free segment 0

Should be step 1: segment 0 -> segment 5, prefree segment 0
Anyway,

>   segment 0     segment 1     segment 2     segment 3     segment 4      segment 5
> |    free   | |20% invalid| |20% invalid| |20% invalid| |20% invalid|   |20%  free|
> |    free   | |80%   valid| |80%   valid| |80%   valid| |80%   valid|   |80% valid|
> 
> 
> step 2: segment 1 -> segment 5 and segment 0, free segment 1

Here, we cannot use segment 0 to fill 60% to handle power-cut. If power-cut
happens after this, we will lose prevous data in segment 0. That's why we're
using prefree segments.

Thanks,

> 
>   segment 0     segment 1     segment 2     segment 3     segment 4      segment 5
> |40%    free| |    free   | |20% invalid| |20% invalid| |20% invalid|   |20% valid|
> |60%   valid| |    free   | |80%   valid| |80%   valid| |80%   valid|   |80% valid|
> 
> 
> step 3: segment 2 -> segment 0 and segment 1, free segment 2
> 
>   segment 0     segment 1     segment 2     segment 3     segment 4      segment 5
> |40%   valid| |60%    free| |    free   | |20% invalid| |20% invalid|   |20% valid|
> |60%   valid| |40%   valid| |    free   | |80%   valid| |80%   valid|   |80% valid|
> 
> 
> step 4: segment 3 -> segment 1 and segment 2, free segment 3
> 
>   segment 0     segment 1     segment 2     segment 3     segment 4      segment 5
> |40%   valid| |60%   valid| |80%    free| |    free   | |20% invalid|   |20% valid|
> |60%   valid| |40%   valid| |20%   valid| |    free   | |80%   valid|   |80% valid|
> 
> 
> step 5: segment 4 -> segment 2, free segment 4
> 
>   segment 0     segment 1     segment 2     segment 3     segment 4      segment 5
> |40%   valid| |60%   valid| |80%   valid| |    free   | |    free   |   |20% valid|
> |60%   valid| |40%   valid| |20%   valid| |    free   | |    free   |   |80% valid|
> 
> done. Now there are 1 new free segment.
> 
> If we change the f2fs gc codes in future, we can even let the initial 1 free
> segment go away, just copy valid data among the 5 segments themselves using SSR.
> 
> So the previous formula:
> 
> 	c.reserved_segments = (2 * (100 / c.overprovision + 1) + 6) * c.segs_per_sec;
> 
> is not needed, we can set reserved_segments to any value if we want, no matter
> what value c.overprovision is, just take it away from the formula.
> 
> And take take a look at the overprov_segment_count in current design of
> mkfs.f2fs:
> 
> set_cp(overprov_segment_count, (get_sb(segment_count_main) - get_cp(rsvd_segment_count)) * c.overprovision / 100);
> 
> The original motivation may be like this:
> 
> For example, if ovp is 20%, the worst case is that each segment is 20% invalid,
> then all the segments can not be selected as victim target for FTL GC, then
> there is (segment_count_main - rsvd_segment_count) * 20%, which are all invalid
> blocks and can not be used for write, thus we should regard this as
> overprovision segments, which can never be used by user. However, as we
> have explained above, all the device capacity which FTL tells f2fs can be used
> for write, so it is not correct to use this formula. In fact, we do not need to set
> the overprovision segments at all for this consideration.
> 
> Yunlong Song (2):
>   mkfs.f2fs: add option to set the value of reserved segments
>     and overprovision segments
>   f2fs: fix the case when there is no free segment to allocate for
>     CURSEG_WARM_NODE
> 
>  fs/f2fs/segment.c | 2 --
>  1 file changed, 2 deletions(-)
> 
> -- 
> 1.8.5.2

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

* Re: [PATCH 2/2] f2fs: fix the case when there is no free segment to allocate for CURSEG_WARM_NODE
  2017-02-17 18:39   ` Jaegeuk Kim
@ 2017-02-23 12:06       ` Chao Yu
  0 siblings, 0 replies; 11+ messages in thread
From: Chao Yu @ 2017-02-23 12:06 UTC (permalink / raw)
  To: Jaegeuk Kim, Yunlong Song
  Cc: cm224.lee, chao, sylinux, miaoxie, zhouxiyu, bintian.wang,
	linux-fsdevel, linux-f2fs-devel, linux-kernel

On 2017/2/18 2:39, Jaegeuk Kim wrote:
> Hi Yunlong,
> 
> I already started to test this since a couple of days ago. :)
> 
> http://git.kernel.org/cgit/linux/kernel/git/jaegeuk/f2fs.git/commit/?h=dev-test&id=908b5f463c82eaf972b149a26bb310f5e25064fd

Hi, Jaegeuk,

Could you send this patch into mailing list? Anyway I will comment in this patch
first. :)

> 
> Thanks,
> 
> On 02/17, Yunlong Song wrote:
>> If the free segments are used up, then new_curseg will fail for
>> CURSEG_WARM_NODE, in this case, we should use change_curseg instead of
>> new_curseg.
>>
>> Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
>> ---
>>  fs/f2fs/segment.c | 2 --
>>  1 file changed, 2 deletions(-)
>>
>> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
>> index df2ff5c..32820cd 100644
>> --- a/fs/f2fs/segment.c
>> +++ b/fs/f2fs/segment.c
>> @@ -1564,8 +1564,6 @@ static void allocate_segment_by_default(struct f2fs_sb_info *sbi,
>>  
>>  	if (force)
>>  		new_curseg(sbi, type, true);
>> -	else if (type == CURSEG_WARM_NODE)

Would it be better to check CP_CRC_RECOVERY_FLAG for compatibility of old image?

else if (!is_set_ckpt_flags(CP_CRC_RECOVERY_FLAG) && type == CURSEG_WARM_NODE)
	new_curseg(sbi, type, false);

Thanks,

>> -		new_curseg(sbi, type, false);
>>  	else if (curseg->alloc_type == LFS && is_next_segment_free(sbi, type))
>>  		new_curseg(sbi, type, false);
>>  	else if (need_SSR(sbi) && get_ssr_segment(sbi, type))
>> -- 
>> 1.8.5.2
> 
> .
> 

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

* Re: [PATCH 2/2] f2fs: fix the case when there is no free segment to allocate for CURSEG_WARM_NODE
@ 2017-02-23 12:06       ` Chao Yu
  0 siblings, 0 replies; 11+ messages in thread
From: Chao Yu @ 2017-02-23 12:06 UTC (permalink / raw)
  To: Jaegeuk Kim, Yunlong Song
  Cc: cm224.lee, chao, sylinux, miaoxie, zhouxiyu, bintian.wang,
	linux-fsdevel, linux-f2fs-devel, linux-kernel

On 2017/2/18 2:39, Jaegeuk Kim wrote:
> Hi Yunlong,
> 
> I already started to test this since a couple of days ago. :)
> 
> http://git.kernel.org/cgit/linux/kernel/git/jaegeuk/f2fs.git/commit/?h=dev-test&id=908b5f463c82eaf972b149a26bb310f5e25064fd

Hi, Jaegeuk,

Could you send this patch into mailing list? Anyway I will comment in this patch
first. :)

> 
> Thanks,
> 
> On 02/17, Yunlong Song wrote:
>> If the free segments are used up, then new_curseg will fail for
>> CURSEG_WARM_NODE, in this case, we should use change_curseg instead of
>> new_curseg.
>>
>> Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
>> ---
>>  fs/f2fs/segment.c | 2 --
>>  1 file changed, 2 deletions(-)
>>
>> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
>> index df2ff5c..32820cd 100644
>> --- a/fs/f2fs/segment.c
>> +++ b/fs/f2fs/segment.c
>> @@ -1564,8 +1564,6 @@ static void allocate_segment_by_default(struct f2fs_sb_info *sbi,
>>  
>>  	if (force)
>>  		new_curseg(sbi, type, true);
>> -	else if (type == CURSEG_WARM_NODE)

Would it be better to check CP_CRC_RECOVERY_FLAG for compatibility of old image?

else if (!is_set_ckpt_flags(CP_CRC_RECOVERY_FLAG) && type == CURSEG_WARM_NODE)
	new_curseg(sbi, type, false);

Thanks,

>> -		new_curseg(sbi, type, false);
>>  	else if (curseg->alloc_type == LFS && is_next_segment_free(sbi, type))
>>  		new_curseg(sbi, type, false);
>>  	else if (need_SSR(sbi) && get_ssr_segment(sbi, type))
>> -- 
>> 1.8.5.2
> 
> .
> 

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

* Re: [PATCH 2/2] f2fs: fix the case when there is no free segment to allocate for CURSEG_WARM_NODE
  2017-02-23 12:06       ` Chao Yu
  (?)
@ 2017-02-23 19:27       ` Jaegeuk Kim
  -1 siblings, 0 replies; 11+ messages in thread
From: Jaegeuk Kim @ 2017-02-23 19:27 UTC (permalink / raw)
  To: Chao Yu
  Cc: Yunlong Song, cm224.lee, chao, sylinux, miaoxie, zhouxiyu,
	bintian.wang, linux-fsdevel, linux-f2fs-devel, linux-kernel

On 02/23, Chao Yu wrote:
> On 2017/2/18 2:39, Jaegeuk Kim wrote:
> > Hi Yunlong,
> > 
> > I already started to test this since a couple of days ago. :)
> > 
> > http://git.kernel.org/cgit/linux/kernel/git/jaegeuk/f2fs.git/commit/?h=dev-test&id=908b5f463c82eaf972b149a26bb310f5e25064fd
> 
> Hi, Jaegeuk,
> 
> Could you send this patch into mailing list? Anyway I will comment in this patch
> first. :)
> 
> > 
> > Thanks,
> > 
> > On 02/17, Yunlong Song wrote:
> >> If the free segments are used up, then new_curseg will fail for
> >> CURSEG_WARM_NODE, in this case, we should use change_curseg instead of
> >> new_curseg.
> >>
> >> Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
> >> ---
> >>  fs/f2fs/segment.c | 2 --
> >>  1 file changed, 2 deletions(-)
> >>
> >> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> >> index df2ff5c..32820cd 100644
> >> --- a/fs/f2fs/segment.c
> >> +++ b/fs/f2fs/segment.c
> >> @@ -1564,8 +1564,6 @@ static void allocate_segment_by_default(struct f2fs_sb_info *sbi,
> >>  
> >>  	if (force)
> >>  		new_curseg(sbi, type, true);
> >> -	else if (type == CURSEG_WARM_NODE)
> 
> Would it be better to check CP_CRC_RECOVERY_FLAG for compatibility of old image?
> 
> else if (!is_set_ckpt_flags(CP_CRC_RECOVERY_FLAG) && type == CURSEG_WARM_NODE)
> 	new_curseg(sbi, type, false);

Agreed, when considering any potential risk. ;)

>From 5b6c6be2d878bd7ec4dc2cb4e2a2da2779fe52ab Mon Sep 17 00:00:00 2001
From: Jaegeuk Kim <jaegeuk@kernel.org>
Date: Tue, 14 Feb 2017 19:32:51 -0800
Subject: [PATCH] f2fs: use SSR for warm node as well

We have had node chains, but haven't used it so far due to stale node blocks.
Now, we have crc|cp_ver in node footer and give random cp_ver at format time,
we can start to use it again.

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

diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index b2e0769a09d0..0b42b0cdd674 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -1563,7 +1563,8 @@ static void allocate_segment_by_default(struct f2fs_sb_info *sbi,
 
 	if (force)
 		new_curseg(sbi, type, true);
-	else if (type == CURSEG_WARM_NODE)
+	else if (!is_set_ckpt_flags(sbi, CP_CRC_RECOVERY_FLAG) &&
+					type == CURSEG_WARM_NODE)
 		new_curseg(sbi, type, false);
 	else if (curseg->alloc_type == LFS && is_next_segment_free(sbi, type))
 		new_curseg(sbi, type, false);
-- 
2.11.0

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

end of thread, other threads:[~2017-02-23 19:27 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-17 12:53 [PATCH 0/2] Reduce the overprovision size a lot in f2fs Yunlong Song
2017-02-17 12:53 ` Yunlong Song
2017-02-17 12:53 ` [PATCH 1/2] mkfs.f2fs: add option to set the value of reserved segments and overprovision segments Yunlong Song
2017-02-17 12:53   ` Yunlong Song
2017-02-17 12:53 ` [PATCH 2/2] f2fs: fix the case when there is no free segment to allocate for CURSEG_WARM_NODE Yunlong Song
2017-02-17 12:53   ` Yunlong Song
2017-02-17 18:39   ` Jaegeuk Kim
2017-02-23 12:06     ` Chao Yu
2017-02-23 12:06       ` Chao Yu
2017-02-23 19:27       ` Jaegeuk Kim
2017-02-17 19:33 ` [PATCH 0/2] Reduce the overprovision size a lot in f2fs Jaegeuk Kim

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.