Commit a80c4adc authored by Rik van Riel's avatar Rik van Riel Committed by Al Viro

ipc,namespace: make ipc namespace allocation wait for pending free

Currently the ipc namespace allocation will fail when there are
ipc_namespace structures pending to be freed. This results in the
simple test case below, as well as some real world workloads, to
get allocation failures even when the number of ipc namespaces in
actual use is way below the limit.

int main()
{
	int i;

	for (i = 0; i < 100000; i++) {
		if (unshare(CLONE_NEWIPC) < 0)
			error(EXIT_FAILURE, errno, "unshare");
	}
}

Make the allocation of an ipc_namespace wait for pending frees,
so it will succeed.

real	6m19.197s
user	0m0.041s
sys	0m1.019s
Signed-off-by: default avatarRik van Riel <riel@surriel.com>
Reported-by: default avatarChris Mason <clm@meta.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent b7bfaa76
......@@ -19,6 +19,12 @@
#include "util.h"
/*
* The work queue is used to avoid the cost of synchronize_rcu in kern_unmount.
*/
static void free_ipc(struct work_struct *unused);
static DECLARE_WORK(free_ipc_work, free_ipc);
static struct ucounts *inc_ipc_namespaces(struct user_namespace *ns)
{
return inc_ucount(ns, current_euid(), UCOUNT_IPC_NAMESPACES);
......@@ -37,9 +43,18 @@ static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns,
int err;
err = -ENOSPC;
again:
ucounts = inc_ipc_namespaces(user_ns);
if (!ucounts)
if (!ucounts) {
/*
* IPC namespaces are freed asynchronously, by free_ipc_work.
* If frees were pending, flush_work will wait, and
* return true. Fail the allocation if no frees are pending.
*/
if (flush_work(&free_ipc_work))
goto again;
goto fail;
}
err = -ENOMEM;
ns = kzalloc(sizeof(struct ipc_namespace), GFP_KERNEL_ACCOUNT);
......@@ -157,11 +172,6 @@ static void free_ipc(struct work_struct *unused)
free_ipc_ns(n);
}
/*
* The work queue is used to avoid the cost of synchronize_rcu in kern_unmount.
*/
static DECLARE_WORK(free_ipc_work, free_ipc);
/*
* put_ipc_ns - drop a reference to an ipc namespace.
* @ns: the namespace to put
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment