lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Mon, 27 Nov 2017 23:09:48 -0800
From:   Davidlohr Bueso <dave@...olabs.net>
To:     Giuseppe Scrivano <gscrivan@...hat.com>
Cc:     linux-kernel@...r.kernel.org, gregkh@...uxfoundation.org,
        mingo@...nel.org, akpm@...ux-foundation.org
Subject: Re: [RFC PATCH] ipc, mqueue: lazy call kern_mount_data in new
 namespaces

This is akpm domain.

On Mon, 27 Nov 2017, Giuseppe Scrivano wrote:

>kern_mount_data is a relatively expensive operation when creating a
>new IPC namespace, so delay the mount until its first usage when not
>creating the the global namespace.
>
>On my machine, the time for creating 1000 new IPC namespaces dropped
>from ~8s to ~2s.

Nice.

>
>Signed-off-by: Giuseppe Scrivano <gscrivan@...hat.com>
>---
> include/linux/ipc_namespace.h |  2 +-
> ipc/mqueue.c                  | 47 ++++++++++++++++++++++++++++++++++---------
> ipc/namespace.c               |  2 +-
> 3 files changed, 39 insertions(+), 12 deletions(-)
>
>diff --git a/include/linux/ipc_namespace.h b/include/linux/ipc_namespace.h
>index b5630c8eb2f3..a06617c113f1 100644
>--- a/include/linux/ipc_namespace.h
>+++ b/include/linux/ipc_namespace.h
>@@ -81,7 +81,7 @@ static inline void shm_destroy_orphaned(struct ipc_namespace *ns) {}
> #endif /* CONFIG_SYSVIPC */
>
> #ifdef CONFIG_POSIX_MQUEUE
>-extern int mq_init_ns(struct ipc_namespace *ns);
>+extern int mq_init_ns(struct ipc_namespace *ns, bool mount);
> /*
>  * POSIX Message Queue default values:
>  *
>diff --git a/ipc/mqueue.c b/ipc/mqueue.c
>index d24025626310..46d2795bbf93 100644
>--- a/ipc/mqueue.c
>+++ b/ipc/mqueue.c
>@@ -87,6 +87,7 @@ struct mqueue_inode_info {
> 	unsigned long qsize; /* size of queue in memory (sum of all msgs) */
> };
>
>+static struct file_system_type mqueue_fs_type;
> static const struct inode_operations mqueue_dir_inode_operations;
> static const struct file_operations mqueue_file_operations;
> static const struct super_operations mqueue_super_ops;
>@@ -776,10 +777,24 @@ static int do_mq_open(const char __user *u_name, int oflag, umode_t mode,
> 	struct filename *name;
> 	int fd, error;
> 	struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
>-	struct vfsmount *mnt = ipc_ns->mq_mnt;
>-	struct dentry *root = mnt->mnt_root;
>+	struct vfsmount *mnt;
>+	struct dentry *root;
> 	int ro;
>
>+	spin_lock(&mq_lock);
>+	mnt = ipc_ns->mq_mnt;
>+	if (unlikely(!mnt)) {
>+		mnt = kern_mount_data(&mqueue_fs_type, ipc_ns);
>+		if (IS_ERR(mnt)) {
>+			spin_unlock(&mq_lock);
>+			return PTR_ERR(mnt);
>+		}
>+		ipc_ns->mq_mnt = mnt;
>+	}
>+	spin_unlock(&mq_lock);
>+
>+	root = mnt->mnt_root;
>+
> 	audit_mq_open(oflag, mode, attr);
>
> 	if (IS_ERR(name = getname(u_name)))
>@@ -863,6 +878,9 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name)
> 	struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
> 	struct vfsmount *mnt = ipc_ns->mq_mnt;
>
>+	if (!mnt)
>+		return -ENOENT;
>+
> 	name = getname(u_name);
> 	if (IS_ERR(name))
> 		return PTR_ERR(name);
>@@ -1581,7 +1599,8 @@ static struct file_system_type mqueue_fs_type = {
> 	.fs_flags = FS_USERNS_MOUNT,
> };
>
>-int mq_init_ns(struct ipc_namespace *ns)
>+
>+int mq_init_ns(struct ipc_namespace *ns, bool mount)
> {
> 	ns->mq_queues_count  = 0;
> 	ns->mq_queues_max    = DFLT_QUEUESMAX;
>@@ -1590,23 +1609,31 @@ int mq_init_ns(struct ipc_namespace *ns)
> 	ns->mq_msg_default   = DFLT_MSG;
> 	ns->mq_msgsize_default  = DFLT_MSGSIZE;
>
>-	ns->mq_mnt = kern_mount_data(&mqueue_fs_type, ns);
>-	if (IS_ERR(ns->mq_mnt)) {
>-		int err = PTR_ERR(ns->mq_mnt);
>+	if (!mount)
> 		ns->mq_mnt = NULL;
>-		return err;
>+	else {
>+		int err;
>+
>+		ns->mq_mnt = kern_mount_data(&mqueue_fs_type, ns);
>+		if (IS_ERR(ns->mq_mnt)) {
>+			err = PTR_ERR(ns->mq_mnt);
>+			ns->mq_mnt = NULL;
>+			return err;
>+		}
> 	}
> 	return 0;
> }
>
> void mq_clear_sbinfo(struct ipc_namespace *ns)
> {
>-	ns->mq_mnt->mnt_sb->s_fs_info = NULL;
>+	if (ns->mq_mnt)
>+		ns->mq_mnt->mnt_sb->s_fs_info = NULL;
> }
>
> void mq_put_mnt(struct ipc_namespace *ns)
> {
>-	kern_unmount(ns->mq_mnt);
>+	if (ns->mq_mnt)
>+		kern_unmount(ns->mq_mnt);
> }
>
> static int __init init_mqueue_fs(void)
>@@ -1628,7 +1655,7 @@ static int __init init_mqueue_fs(void)
>
> 	spin_lock_init(&mq_lock);
>
>-	error = mq_init_ns(&init_ipc_ns);
>+	error = mq_init_ns(&init_ipc_ns, true);
> 	if (error)
> 		goto out_filesystem;
>
>diff --git a/ipc/namespace.c b/ipc/namespace.c
>index f59a89966f92..9d3689577f66 100644
>--- a/ipc/namespace.c
>+++ b/ipc/namespace.c
>@@ -65,7 +65,7 @@ static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns,
> 	if (err)
> 		goto fail_destroy_msg;
>
>-	err = mq_init_ns(ns);
>+	err = mq_init_ns(ns, false);
> 	if (err)
> 		goto fail_destroy_shm;
>
>-- 
>2.14.3
>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ