All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jaegeuk Kim <jaegeuk@kernel.org>
To: Yonggil Song <yonggil.song@samsung.com>
Cc: Seokhwan Kim <sukka.kim@samsung.com>,
	Jorn Lee <lunar.lee@samsung.com>,
	"linux-f2fs-devel@lists.sourceforge.net"
	<linux-f2fs-devel@lists.sourceforge.net>
Subject: Re: [f2fs-dev] [PATCH v1] mkfs.f2fs: Introduce configurable reserved sections
Date: Mon, 27 Mar 2023 14:26:59 -0700	[thread overview]
Message-ID: <ZCIKIzPmJyjA44JK@google.com> (raw)
In-Reply-To: <20230317044151epcms2p5872591b638dab3261a9dd563253f1b94@epcms2p5>

On 03/17, Yonggil Song wrote:
> Overview
> ========
> 
> This option allows zoned block device users to configure GC reserved and
> overprovision area manually according to their demands on performance of
> sustained write latency and WAF.
> 
> Problem
> =======
> 
> The overprovision segments that mkfs generates are mostly occupied by GC
> reserved. This degrades WAF performance.
> 
> Experiment
> ==========
> 
> The following experiment evaluated the application of configurable reserved.
> The experimental environment is as follows.
> 
>   System info
>     - 4.2Ghz, 8 core CPU
>     - 64GiB Memory
>   Device info
>     - a conventional null_blk with 448MiB capacity(meta area) and
>     - a sequential null_blk with 953 zones of 64MiB
>   Format
>     - as-is (find out ovp ratio): mkfs.f2fs <conv null_blk> -c <seq null_blk> -m
>         Info: Overprovision ratio = 3.700%
>         Info: Overprovision segments = 1152 (GC reserved = 1088)
>     - config rsvd: mkfs.f2fs <conv null_blk> -c <seq null_blk> -m 8 -o 2.965
>         Info: Overprovision ratio = 2.965%
>         Info: Overprovision segments = 1152 (GC reserved = 256)
>   Mount
>     - mount <conv null_blk> <mount point>
>   Fio script
>     - fio --rw=randwrite --bs=4k --ba=4k --filesize=58630m --norandommap --overwrite=1 --name=job1 --filename=<mount point>/sustain --time_based --runtime=2h
>   WAF calculation
>     - (IOs on conv. null_blk + IOs on seq. null_blk) / random write IOs
> 
> Conclusion
> ==========
> 
> In the experiment, it can be shown that reducing the reserved segments
> decreases WAF to 10% (from 222 to 23) although it triggers checkpoint more
> frequently during gc. With direct IO, the WAF of as-is gets much higher.
> In other words, a user can configure more reserved segments for lower GC
> latency or allocate less reserved segments for lower WAF on the same number
> of OP segments.
> 
> Signed-off-by: Yonggil Song <yonggil.song@samsung.com>
> ---
>  include/f2fs_fs.h       | 22 ++++++++++++++++++++--
>  lib/libf2fs.c           | 22 ++++++++++++++++++++++
>  man/mkfs.f2fs.8         |  9 +++++++--
>  mkfs/f2fs_format.c      | 29 +++++++++++++++++++++++------
>  mkfs/f2fs_format_main.c |  5 +++--
>  5 files changed, 75 insertions(+), 12 deletions(-)
> 
> diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
> index 333ae07a5ebd..1d41e9f8397e 100644
> --- a/include/f2fs_fs.h
> +++ b/include/f2fs_fs.h
> @@ -375,6 +375,10 @@ static inline uint64_t bswap_64(uint64_t val)
>  
>  #define LPF "lost+found"
>  
> +/* one for gc buffer, the other for node */
> +#define MIN_RSVD_SECS	(uint32_t)(NR_CURSEG_TYPE + 2)
> +#define CONFIG_RSVD_DEFAULT_OP_RATIO	3.0
> +
>  enum f2fs_config_func {
>  	MKFS,
>  	FSCK,
> @@ -460,6 +464,7 @@ typedef struct {
>  #define ALIGN_UP(addrs, size)	ALIGN_DOWN(((addrs) + (size) - 1), (size))
>  
>  struct f2fs_configuration {
> +	uint32_t conf_reserved_sections;
>  	uint32_t reserved_segments;
>  	uint32_t new_reserved_segments;
>  	int sparse_mode;
> @@ -1614,6 +1619,20 @@ extern uint32_t f2fs_get_usable_segments(struct f2fs_super_block *sb);
>  #define ZONE_ALIGN(blks)	SIZE_ALIGN(blks, c.blks_per_seg * \
>  					c.segs_per_zone)
>  
> +static inline double get_reserved(struct f2fs_super_block *sb, double ovp)
> +{
> +	double reserved;
> +	uint32_t usable_main_segs = f2fs_get_usable_segments(sb);
> +	uint32_t segs_per_sec = round_up(usable_main_segs, get_sb(section_count));
> +
> +	if (c.conf_reserved_sections)
> +		reserved = c.conf_reserved_sections * segs_per_sec;
> +	else
> +		reserved = (100 / ovp + 1 + NR_CURSEG_TYPE) * segs_per_sec;
> +
> +	return reserved;
> +}
> +
>  static inline double get_best_overprovision(struct f2fs_super_block *sb)
>  {
>  	double reserved, ovp, candidate, end, diff, space;
> @@ -1631,8 +1650,7 @@ static inline double get_best_overprovision(struct f2fs_super_block *sb)
>  	}
>  
>  	for (; candidate <= end; candidate += diff) {
> -		reserved = (100 / candidate + 1 + NR_CURSEG_TYPE) *
> -				round_up(usable_main_segs, get_sb(section_count));
> +		reserved = get_reserved(sb, candidate);
>  		ovp = (usable_main_segs - reserved) * candidate / 100;
>  		if (ovp < 0)
>  			continue;
> diff --git a/lib/libf2fs.c b/lib/libf2fs.c
> index f63307a42a08..b5644ff6ebdd 100644
> --- a/lib/libf2fs.c
> +++ b/lib/libf2fs.c
> @@ -1069,6 +1069,28 @@ int get_device_info(int i)
>  				dev->nr_rnd_zones);
>  		MSG(0, "      %zu blocks per zone\n",
>  				dev->zone_blocks);
> +		if (c.conf_reserved_sections) {
> +			if (c.conf_reserved_sections < MIN_RSVD_SECS) {
> +				MSG(0, "      Too small sections are reserved(%u secs)\n",
> +				    c.conf_reserved_sections);
> +				c.conf_reserved_sections =
> +					max(c.conf_reserved_sections, MIN_RSVD_SECS);
> +				MSG(0, "      It is operated as a minimum reserved sections(%u secs)\n",
> +				    c.conf_reserved_sections);
> +			} else {
> +				MSG(0, "      %u sections are reserved\n",
> +				c.conf_reserved_sections);
> +			}
> +			if (!c.overprovision) {
> +				c.overprovision = CONFIG_RSVD_DEFAULT_OP_RATIO;
> +				MSG(0, "      Overprovision ratio is set to default(%.1lf%%)\n",
> +				    c.overprovision);
> +			}
> +		} else {
> +			MSG(0,
> +				"      0 reserved sections are received.\n"
> +				"      Reserved sections are calculating\n");
> +		}
>  	}
>  #endif
>  	/* adjust wanted_total_sectors */
> diff --git a/man/mkfs.f2fs.8 b/man/mkfs.f2fs.8
> index a6249f6ef6ed..800c4c79bf37 100644
> --- a/man/mkfs.f2fs.8
> +++ b/man/mkfs.f2fs.8
> @@ -43,6 +43,7 @@ mkfs.f2fs \- create an F2FS file system
>  ]
>  [
>  .B \-m
> +.I #-of-reserved-sections
>  ]
>  [
>  .B \-o
> @@ -152,8 +153,12 @@ Enable extended node bitmap.
>  .BI \-l " volume-label"
>  Specify the volume label to the partition mounted as F2FS.
>  .TP
> -.BI \-m
> -Specify f2fs filesystem to supports the block zoned feature.
> +.BI \-m " #-of-reserved-sections"
> +Specify f2fs filesystem to supports the block zoned feature and reserved sections.
> +If specified to non-zero, reserved segments count is set to the larger size
> +between 8 sections and the input value.  If specified to zero, the best number
> +will be assigned automatically according to the partition size. If overprovision-ratio-percentage
> +is not specifed, it will set to default 3.0%.
>  Without it, the filesystem doesn't support the feature.
>  .TP
>  .BI \-o " overprovision-ratio-percentage"
> diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c
> index f4a49acc498c..22e53be5003d 100644
> --- a/mkfs/f2fs_format.c
> +++ b/mkfs/f2fs_format.c
> @@ -483,9 +483,7 @@ static int f2fs_prepare_super_block(void)
>  	if (c.overprovision == 0)
>  		c.overprovision = get_best_overprovision(sb);
>  
> -	c.reserved_segments =
> -			(100 / c.overprovision + 1 + NR_CURSEG_TYPE) *
> -			round_up(f2fs_get_usable_segments(sb), get_sb(section_count));
> +	c.reserved_segments = get_reserved(sb, c.overprovision);
>  
>  	if (c.feature & cpu_to_le32(F2FS_FEATURE_RO)) {
>  		c.overprovision = 0;
> @@ -765,11 +763,30 @@ static int f2fs_write_check_point_pack(void)
>  			get_cp(rsvd_segment_count)) *
>  			c.overprovision / 100);
>  
> -	if (get_cp(overprov_segment_count) < get_cp(rsvd_segment_count))
> +	if (!(c.conf_reserved_sections) &&
> +	    get_cp(overprov_segment_count) < get_cp(rsvd_segment_count))
>  		set_cp(overprov_segment_count, get_cp(rsvd_segment_count));
>  
> -	set_cp(overprov_segment_count, get_cp(overprov_segment_count) +
> -			2 * get_sb(segs_per_sec));
> +	/*
> +	 * If conf_reserved_sections has a non zero value, overprov_segment_count
> +	 * is set to overprov_segment_count + rsvd_segment_count.
> +	 */
> +	if (c.conf_reserved_sections) {
> +		/*
> +		 * Overprovision segments must be bigger than two sections.
> +		 * In non configurable reserved section case, overprovision
> +		 * segments are always bigger than two sections.
> +		 */
> +		if (get_cp(overprov_segment_count) < 2 * get_sb(segs_per_sec)) {
> +			MSG(0, "\tError: Not enough overprovision segments (%u)\n",
> +			    get_cp(overprov_segment_count));
> +			goto free_cp_payload;
> +		}
> +		set_cp(overprov_segment_count, get_cp(overprov_segment_count) +
> +				get_cp(rsvd_segment_count));
> +	 } else
> +		set_cp(overprov_segment_count, get_cp(overprov_segment_count) +
> +				2 * get_sb(segs_per_sec));
>  
>  	if (f2fs_get_usable_segments(sb) <= get_cp(overprov_segment_count)) {
>  		MSG(0, "\tError: Not enough segments to create F2FS Volume\n");
> diff --git a/mkfs/f2fs_format_main.c b/mkfs/f2fs_format_main.c
> index f50971c4591c..a4accda91780 100644
> --- a/mkfs/f2fs_format_main.c
> +++ b/mkfs/f2fs_format_main.c
> @@ -61,7 +61,7 @@ static void mkfs_usage()
>  	MSG(0, "  -i extended node bitmap, node ratio is 20%% by default\n");
>  	MSG(0, "  -l label\n");
>  	MSG(0, "  -U uuid\n");
> -	MSG(0, "  -m support zoned block device [default:0]\n");
> +	MSG(0, "  -m support zoned block device, # of reserved sections [default:0]\n");
>  	MSG(0, "  -o overprovision percentage [default:auto]\n");
>  	MSG(0, "  -O feature1[,feature2,...] e.g. \"encrypt\"\n");
>  	MSG(0, "  -C [encoding[:flag1,...]] Support casefolding with optional flags\n");
> @@ -176,7 +176,7 @@ static void add_default_options(void)
>  
>  static void f2fs_parse_options(int argc, char *argv[])
>  {
> -	static const char *option_string = "qa:c:C:d:e:E:g:hil:mo:O:rR:s:S:z:t:T:U:Vfw:";
> +	static const char *option_string = "qa:c:C:d:e:E:g:hil:m:o:O:rR:s:S:z:t:T:U:Vfw:";
>  	static const struct option long_opts[] = {
>  		{ .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' },
>  		{ .name = NULL, .has_arg = 0, .flag = NULL, .val = 0 }
> @@ -235,6 +235,7 @@ static void f2fs_parse_options(int argc, char *argv[])
>  			break;
>  		case 'm':
>  			c.zoned_mode = 1;
> +			c.conf_reserved_sections = atoi(optarg);

This breaks the existing "-m" option. Can you address to support that?

>  			break;
>  		case 'o':
>  			c.overprovision = atof(optarg);
> -- 
> 2.34.1


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

  reply	other threads:[~2023-03-27 21:27 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CGME20230317044151epcms2p5872591b638dab3261a9dd563253f1b94@epcms2p5>
2023-03-17  4:41 ` [f2fs-dev] [PATCH v1] mkfs.f2fs: Introduce configurable reserved sections Yonggil Song
2023-03-27 21:26   ` Jaegeuk Kim [this message]
2023-03-28  8:06     ` [f2fs-dev] (2) " Yonggil Song
2023-04-04  6:21       ` [f2fs-dev] [PATCH v2] " Yonggil Song

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZCIKIzPmJyjA44JK@google.com \
    --to=jaegeuk@kernel.org \
    --cc=linux-f2fs-devel@lists.sourceforge.net \
    --cc=lunar.lee@samsung.com \
    --cc=sukka.kim@samsung.com \
    --cc=yonggil.song@samsung.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.