From: Yang Yingliang yangyingliang@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8ND8I
--------------------------------
When files cgroup is enabled, it's will leads syscall performance regression in UnixBench. Add a helper files_cgroup_enabled() and use it to control if use files cgroup, wen can use cgroup_disable=files in cmdline to disable files cgroup.
syscall of UnixBench (large is better) enable files cgroup: 2868.5 disable files cgroup: 3177.0 disable config of files cgroup: 3186.5
Signed-off-by: Yang Yingliang yangyingliang@huawei.com Signed-off-by: chenridong chenridong@huawei.com --- .../admin-guide/kernel-parameters.txt | 7 +++--- fs/file.c | 23 ++++++++++++------- include/linux/filescontrol.h | 6 +++++ 3 files changed, 25 insertions(+), 11 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 41644336e358..ceb709ceb663 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -565,9 +565,10 @@ - if foo is an optional feature then the feature is disabled and corresponding cgroup files are not created - {Currently only "memory" controller deal with this and - cut the overhead, others just disable the usage. So - only cgroup_disable=memory is actually worthy} + {Currently only "memory" and and "files" controller + deal with this and cut the overhead, others just + disable the usage. So only cgroup_disable=memory and + cgroup_disable=files are actually worthy} Specifying "pressure" disables per-cgroup pressure stall information accounting feature
diff --git a/fs/file.c b/fs/file.c index b44712c62758..6c63342ef506 100644 --- a/fs/file.c +++ b/fs/file.c @@ -339,7 +339,8 @@ struct files_struct *dup_fd(struct files_struct *oldf, unsigned int max_fds, int new_fdt->full_fds_bits = newf->full_fds_bits_init; new_fdt->fd = &newf->fd_array[0]; #ifdef CONFIG_CGROUP_FILES - files_cgroup_assign(newf); + if (files_cgroup_enabled()) + files_cgroup_assign(newf); #endif
spin_lock(&oldf->file_lock); @@ -405,10 +406,12 @@ struct files_struct *dup_fd(struct files_struct *oldf, unsigned int max_fds, int
rcu_assign_pointer(newf->fdt, new_fdt); #ifdef CONFIG_CGROUP_FILES + if (!files_cgroup_enabled()) + return newf; if (!files_cgroup_alloc_fd(newf, files_cgroup_count_fds(newf))) return newf;
-/* could not get enough FD resources. Need to clean up. */ + /* could not get enough FD resources. Need to clean up. */ new_fds = new_fdt->fd; for (i = open_files; i != 0; i--) { struct file *f = *new_fds++; @@ -425,7 +428,8 @@ struct files_struct *dup_fd(struct files_struct *oldf, unsigned int max_fds, int
out_release: #ifdef CONFIG_CGROUP_FILES - files_cgroup_remove(newf); + if (files_cgroup_enabled()) + files_cgroup_remove(newf); #endif kmem_cache_free(files_cachep, newf); out: @@ -453,7 +457,8 @@ static struct fdtable *close_files(struct files_struct * files) struct file * file = xchg(&fdt->fd[i], NULL); if (file) { #ifdef CONFIG_CGROUP_FILES - files_cgroup_unalloc_fd(files, 1); + if (files_cgroup_enabled()) + files_cgroup_unalloc_fd(files, 1); #endif filp_close(file, files); cond_resched(); @@ -464,7 +469,8 @@ static struct fdtable *close_files(struct files_struct * files) } } #ifdef CONFIG_CGROUP_FILES - files_cgroup_remove(files); + if (files_cgroup_enabled()) + files_cgroup_remove(files); #endif
return fdt; @@ -561,7 +567,7 @@ static int alloc_fd(unsigned start, unsigned end, unsigned flags) if (error) goto repeat; #ifdef CONFIG_CGROUP_FILES - if (files_cgroup_alloc_fd(files, 1)) { + if (files_cgroup_enabled() && files_cgroup_alloc_fd(files, 1)) { error = -EMFILE; goto out; } @@ -604,7 +610,7 @@ static void __put_unused_fd(struct files_struct *files, unsigned int fd) { struct fdtable *fdt = files_fdtable(files); #ifdef CONFIG_CGROUP_FILES - if (test_bit(fd, fdt->open_fds)) + if (files_cgroup_enabled() && test_bit(fd, fdt->open_fds)) files_cgroup_unalloc_fd(files, 1); #endif __clear_open_fd(fd, fdt); @@ -1170,7 +1176,8 @@ __releases(&files->file_lock) goto out; } #ifdef CONFIG_CGROUP_FILES - if (!tofree && files_cgroup_alloc_fd(files, 1)) { + if (files_cgroup_enabled() && + !tofree && files_cgroup_alloc_fd(files, 1)) { err = -EMFILE; goto out; } diff --git a/include/linux/filescontrol.h b/include/linux/filescontrol.h index 49dc620cf64e..0182f145a339 100644 --- a/include/linux/filescontrol.h +++ b/include/linux/filescontrol.h @@ -19,6 +19,7 @@ #define _LINUX_FILESCONTROL_H
#include <linux/fdtable.h> +#include <linux/cgroup.h>
#ifdef CONFIG_CGROUP_FILES
@@ -30,5 +31,10 @@ extern struct files_struct init_files; void files_cgroup_assign(struct files_struct *files); void files_cgroup_remove(struct files_struct *files);
+static inline bool files_cgroup_enabled(void) +{ + return cgroup_subsys_enabled(files_cgrp_subsys); +} + #endif /* CONFIG_CGROUP_FILES */ #endif /* _LINUX_FILESCONTROL_H */