linux-f2fs-devel.lists.sourceforge.net archive mirror
 help / color / mirror / Atom feed
* [f2fs-dev] [PATCH] f2fs: add discard_cpuset mount opt
@ 2023-03-01 15:22 Yangtao Li via Linux-f2fs-devel
  2023-03-01 18:37 ` kernel test robot
  2023-03-02  5:02 ` kernel test robot
  0 siblings, 2 replies; 3+ messages in thread
From: Yangtao Li via Linux-f2fs-devel @ 2023-03-01 15:22 UTC (permalink / raw)
  To: jaegeuk, chao; +Cc: Yangtao Li, linux-kernel, linux-f2fs-devel

It makes the discard process run faster on a more powerful CPU, or not.

Signed-off-by: Yangtao Li <frank.li@vivo.com>
---
 Documentation/filesystems/f2fs.rst |  2 ++
 fs/f2fs/f2fs.h                     |  1 +
 fs/f2fs/segment.c                  |  8 +++++-
 fs/f2fs/super.c                    | 39 ++++++++++++++++++++++++++++++
 4 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst
index 2055e72871fe..dc005f3b784a 100644
--- a/Documentation/filesystems/f2fs.rst
+++ b/Documentation/filesystems/f2fs.rst
@@ -351,6 +351,8 @@ age_extent_cache	 Enable an age extent cache based on rb-tree. It records
 			 data block update frequency of the extent per inode, in
 			 order to provide better temperature hints for data block
 			 allocation.
+discard_cpuset=%u		 Set the cpumask of dicard thread, it makes the discard
+			 process run faster on a more powerful CPU, or not.
 ======================== ============================================================
 
 Debugfs Entries
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index b0ab2062038a..62ce02a87d33 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -183,6 +183,7 @@ struct f2fs_mount_info {
 	int compress_mode;			/* compression mode */
 	unsigned char extensions[COMPRESS_EXT_NUM][F2FS_EXTENSION_LEN];	/* extensions */
 	unsigned char noextensions[COMPRESS_EXT_NUM][F2FS_EXTENSION_LEN]; /* extensions */
+	struct cpumask discard_cpumask; /* discard thread cpumask */
 };
 
 #define F2FS_FEATURE_ENCRYPT		0x0001
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 227e25836173..2648c564833e 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2054,11 +2054,17 @@ int f2fs_start_discard_thread(struct f2fs_sb_info *sbi)
 	if (!f2fs_realtime_discard_enable(sbi))
 		return 0;
 
-	dcc->f2fs_issue_discard = kthread_run(issue_discard_thread, sbi,
+	dcc->f2fs_issue_discard = kthread_create(issue_discard_thread, sbi,
 				"f2fs_discard-%u:%u", MAJOR(dev), MINOR(dev));
 	if (IS_ERR(dcc->f2fs_issue_discard)) {
 		err = PTR_ERR(dcc->f2fs_issue_discard);
 		dcc->f2fs_issue_discard = NULL;
+	} else {
+		if (!cpumask_empty(&F2FS_OPTION(sbi).discard_cpumask)) {
+			kthread_bind_mask(dcc->f2fs_issue_discard,
+					&F2FS_OPTION(sbi).discard_cpumask);
+		}
+		wake_up_process(dcc->f2fs_issue_discard);
 	}
 
 	return err;
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index fbaaabbcd6de..e2d0fcc2369c 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -164,6 +164,7 @@ enum {
 	Opt_discard_unit,
 	Opt_memory_mode,
 	Opt_age_extent_cache,
+	Opt_discard_cpuset,
 	Opt_err,
 };
 
@@ -243,6 +244,7 @@ static match_table_t f2fs_tokens = {
 	{Opt_discard_unit, "discard_unit=%s"},
 	{Opt_memory_mode, "memory=%s"},
 	{Opt_age_extent_cache, "age_extent_cache"},
+	{Opt_discard_cpuset, "discard_cpuset=%u"},
 	{Opt_err, NULL},
 };
 
@@ -1256,6 +1258,22 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
 		case Opt_age_extent_cache:
 			set_opt(sbi, AGE_EXTENT_CACHE);
 			break;
+		case Opt_discard_cpuset:
+			if (!f2fs_hw_support_discard(sbi)) {
+				f2fs_warn(sbi, "device does not support discard");
+				break;
+			}
+
+			if (args->from && match_int(args, &arg))
+				return -EINVAL;
+
+			if (!cpu_possible(arg)) {
+				f2fs_err(sbi, "invalid cpu%d for discard_cpuset", arg);
+				return -EINVAL;
+			}
+
+			cpumask_set_cpu(arg, &F2FS_OPTION(sbi).discard_cpumask);
+			break;
 		default:
 			f2fs_err(sbi, "Unrecognized mount option \"%s\" or missing value",
 				 p);
@@ -1358,6 +1376,14 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
 		f2fs_err(sbi, "Allow to mount readonly mode only");
 		return -EROFS;
 	}
+
+	if (!cpumask_empty(&F2FS_OPTION(sbi).discard_cpumask) &&
+			!cpumask_intersects(cpu_online_mask,
+				&F2FS_OPTION(sbi).discard_cpumask)) {
+		f2fs_err(sbi, "Must include one online CPU for discard_cpuset");
+		return -EINVAL;
+	}
+
 	return 0;
 }
 
@@ -1884,6 +1910,7 @@ static inline void f2fs_show_compress_options(struct seq_file *seq,
 static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
 {
 	struct f2fs_sb_info *sbi = F2FS_SB(root->d_sb);
+	unsigned int cpu;
 
 	if (F2FS_OPTION(sbi).bggc_mode == BGGC_MODE_SYNC)
 		seq_printf(seq, ",background_gc=%s", "sync");
@@ -1909,6 +1936,8 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
 			seq_printf(seq, ",discard_unit=%s", "segment");
 		else if (F2FS_OPTION(sbi).discard_unit == DISCARD_UNIT_SECTION)
 			seq_printf(seq, ",discard_unit=%s", "section");
+		for_each_cpu(cpu, &F2FS_OPTION(sbi).discard_cpumask)
+			seq_printf(seq, ",discard_cpuset=%u", cpu);
 	} else {
 		seq_puts(seq, ",nodiscard");
 	}
@@ -2222,6 +2251,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
 	bool no_discard = !test_opt(sbi, DISCARD);
 	bool no_compress_cache = !test_opt(sbi, COMPRESS_CACHE);
 	bool block_unit_discard = f2fs_block_unit_discard(sbi);
+	struct cpumask old_discard_cpumask;
 #ifdef CONFIG_QUOTA
 	int i, j;
 #endif
@@ -2232,6 +2262,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
 	 */
 	org_mount_opt = sbi->mount_opt;
 	old_sb_flags = sb->s_flags;
+	cpumask_copy(&old_discard_cpumask, &F2FS_OPTION(sbi).discard_cpumask);
 
 #ifdef CONFIG_QUOTA
 	org_mount_opt.s_jquota_fmt = F2FS_OPTION(sbi).s_jquota_fmt;
@@ -2340,6 +2371,13 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
 		goto restore_opts;
 	}
 
+	if (!cpumask_equal(&F2FS_OPTION(sbi).discard_cpumask,
+		&old_discard_cpumask)) {
+		err = -EINVAL;
+		f2fs_warn(sbi, "switch discard_cpuset option is not allowed");
+		goto restore_opts;
+	}
+
 	if ((*flags & SB_RDONLY) && test_opt(sbi, DISABLE_CHECKPOINT)) {
 		err = -EINVAL;
 		f2fs_warn(sbi, "disabling checkpoint not compatible with read-only");
@@ -2481,6 +2519,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
 		F2FS_OPTION(sbi).s_qf_names[i] = org_mount_opt.s_qf_names[i];
 	}
 #endif
+	cpumask_copy(&F2FS_OPTION(sbi).discard_cpumask, &old_discard_cpumask);
 	sbi->mount_opt = org_mount_opt;
 	sb->s_flags = old_sb_flags;
 	return err;
-- 
2.25.1



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

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

end of thread, other threads:[~2023-03-02  5:03 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-03-01 15:22 [f2fs-dev] [PATCH] f2fs: add discard_cpuset mount opt Yangtao Li via Linux-f2fs-devel
2023-03-01 18:37 ` kernel test robot
2023-03-02  5:02 ` kernel test robot

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).