[Devel,RHEL7,COMMIT] ve/fs: convert per-VE number of currently mounted fs to atomic_t

Submitted by Konstantin Khorenko on Aug. 11, 2017, 2:50 p.m.

Details

Message ID 201708111450.v7BEoAag005500@finist_cl7.x64_64.work.ct
State New
Series "ve/fs/mount: make work with ve->mnt_nr race free"
Headers show

Commit Message

Konstantin Khorenko Aug. 11, 2017, 2:50 p.m.
The commit is pushed to "branch-rh7-3.10.0-514.26.1.vz7.35.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-514.26.1.vz7.35.3
------>
commit 1990556a5e34b24badbd3f0f5486ba97bd0fd29c
Author: Konstantin Khorenko <khorenko@virtuozzo.com>
Date:   Fri Aug 11 18:50:10 2017 +0400

    ve/fs: convert per-VE number of currently mounted fs to atomic_t
    
    At the moment ve->mnt_nr is not atomic and not guarded by any lock =>
    convert it to atomic_t in order to avoid races on updates
    
    https://jira.sw.ru/browse/PSBM-69880
    
    Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
    Reviewed-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
 include/linux/ve.h | 9 +++++----
 kernel/ve/ve.c     | 4 ++--
 2 files changed, 7 insertions(+), 6 deletions(-)

Patch hide | download patch | download mbox

diff --git a/include/linux/ve.h b/include/linux/ve.h
index 94dd068..f430ccd 100644
--- a/include/linux/ve.h
+++ b/include/linux/ve.h
@@ -122,7 +122,7 @@  struct ve_struct {
 	/* Number of mounts. May become unbalanced if VE0 mounts something
 	 * and the VE unmounts it. This is acceptable.
 	 */
-	int			mnt_nr;
+	atomic_t		mnt_nr;
 #ifdef CONFIG_COREDUMP
 	char 			core_pattern[CORENAME_MAX_SIZE];
 #endif
@@ -232,17 +232,18 @@  static inline int ve_mount_allowed(void)
 {
 	struct ve_struct *ve = get_exec_env();
 
-	return ve_is_super(ve) || ve->mnt_nr < (int)sysctl_ve_mount_nr;
+	return ve_is_super(ve) ||
+		atomic_read(&ve->mnt_nr) < (int)sysctl_ve_mount_nr;
 }
 
 static inline void ve_mount_nr_inc(void)
 {
-	get_exec_env()->mnt_nr++;
+	atomic_inc(&get_exec_env()->mnt_nr);
 }
 
 static inline void ve_mount_nr_dec(void)
 {
-	get_exec_env()->mnt_nr--;
+	atomic_dec(&get_exec_env()->mnt_nr);
 }
 
 #else	/* CONFIG_VE */
diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c
index 140f160..0a835f3 100644
--- a/kernel/ve/ve.c
+++ b/kernel/ve/ve.c
@@ -78,7 +78,7 @@  struct ve_struct ve0 = {
 #endif
 	.sched_lat_ve.cur	= &ve0_lat_stats,
 	.init_cred		= &init_cred,
-	.mnt_nr			= 0,
+	.mnt_nr			= ATOMIC_INIT(0),
 	.netns_avail_nr		= ATOMIC_INIT(INT_MAX),
 	.netns_max_nr		= INT_MAX,
 	.netif_avail_nr		= ATOMIC_INIT(INT_MAX),
@@ -692,7 +692,7 @@  static struct cgroup_subsys_state *ve_create(struct cgroup *cg)
 	ve->aio_nr = 0;
 	ve->aio_max_nr = AIO_MAX_NR_DEFAULT;
 #endif
-	ve->mnt_nr = 0;
+	atomic_set(&ve->mnt_nr, 0);
 
 #ifdef CONFIG_COREDUMP
 	strcpy(ve->core_pattern, "core");