linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC next v2 0/5] ucount: add rlimit cache for ucount
@ 2025-05-09  7:20 Chen Ridong
  2025-05-09  7:20 ` [RFC next v2 1/5] user_namespace: add children list node Chen Ridong
                   ` (7 more replies)
  0 siblings, 8 replies; 17+ messages in thread
From: Chen Ridong @ 2025-05-09  7:20 UTC (permalink / raw)
  To: akpm, paulmck, bigeasy, legion, roman.gushchin, brauner, tglx,
	frederic, peterz, oleg, joel.granados, viro, lorenzo.stoakes,
	avagin, mengensun, linux, jlayton, ruanjinjie, kees
  Cc: linux-kernel, lujialin4, chenridong

The will-it-scale test case signal1 [1] has been observed. and the test
results reveal that the signal sending system call lacks linearity.
To further investigate this issue, we initiated a series of tests by
launching varying numbers of dockers and closely monitored the throughput
of each individual docker. The detailed test outcomes are presented as
follows:

	| Dockers     |1      |4      |8      |16     |32     |64     |
	| Throughput  |380068 |353204 |308948 |306453 |180659 |129152 |

The data clearly demonstrates a discernible trend: as the quantity of
dockers increases, the throughput per container progressively declines.
In-depth analysis has identified the root cause of this performance
degradation. The ucouts module conducts statistics on rlimit, which
involves a significant number of atomic operations. These atomic
operations, when acting on the same variable, trigger a substantial number
of cache misses or remote accesses, ultimately resulting in a drop in
performance.

Notably, even though a new user_namespace is created upon docker startup,
the problem persists. This is because all these dockers share the same
parent node, meaning that rlimit statistics continuously modify the same
atomic variable.

Currently, when incrementing a specific rlimit within a child user
namespace by 1, the corresponding rlimit in the parent node must also be
incremented by 1. Specifically, if the ucounts corresponding to a task in
Docker B is ucount_b_1, after incrementing the rlimit of ucount_b_1 by 1,
the rlimit of the parent node, init_ucounts, must also be incremented by 1.
This operation should be ensured to stay within the limits set for the
user namespaces.

	init_user_ns                             init_ucounts
	^                                              ^
	|                        |                     |
	|<---- usr_ns_a(docker A)|usr_ns_a->ucount---->|
	|                        |                     |
	|<---- usr_ns_b(docker B)|usr_ns_a->ucount---->|
					^
					|
					|
					|
					ucount_b_1

What is expected is that dockers operating within separate namespaces
should remain isolated and not interfere with one another. Regrettably,
the current signal system call fails to achieve this desired level of
isolation.

Proposal:

To address the aforementioned issues, the concept of implementing a cache
for each namespace's rlimit has been proposed. If a cache is added for
each user namespace's rlimit, a certain amount of rlimits can be allocated
to a particular namespace in one go. When resources are abundant, these
resources do not need to be immediately returned to the parent node. Within
a user namespace, if there are available values in the cache, there is no
need to request additional resources from the parent node.

	init_user_ns                             init_ucounts
	^                                              ^
	|                        |                     |
	|<---- usr_ns_a(docker A)|usr_ns_a->ucount---->|
	|                        |                     |
	|<---- usr_ns_b(docker B)|usr_ns_b->ucount---->|
			^		^
			|		|
			cache_rlimit--->|
					|
					ucount_b_1


The ultimate objective of this solution is to achieve complete isolation
among namespaces. After applying this patch set, the final test results
indicate that in the signal1 test case, the performance does not
deteriorate as the number of containers increases. This effectively meets
the goal of linear scalability.

	| Dockers     |1      |4      |8      |16     |32     |64     |
	| Throughput  |381809 |382284 |380640 |383515 |381318 |380120 |

Challenges:

When checking the pending signals in the parent node using the command
 cat /proc/self/status | grep SigQ, the retrieved value includes the
cached signal counts from its child nodes. As a result, the SigQ value
in the parent node fails to accurately and instantaneously reflect the
actual number of pending signals.

	# cat /proc/self/status | grep SigQ
	SigQ:	16/6187667

TODO:

Add cache for the other rlimits.

[1] https://github.com/antonblanchard/will-it-scale/blob/master/tests/

Chen Ridong (5):
  user_namespace: add children list node
  usernamespace: make usernamespace rcu safe
  user_namespace: add user_ns iteration helper
  uounts: factor out __inc_rlimit_get_ucounts/__dec_rlimit_put_ucounts
  ucount: add rlimit cache for ucount

 include/linux/user_namespace.h |  23 ++++-
 kernel/signal.c                |   2 +-
 kernel/ucount.c                | 181 +++++++++++++++++++++++++++++----
 kernel/user.c                  |   2 +
 kernel/user_namespace.c        |  60 ++++++++++-
 5 files changed, 243 insertions(+), 25 deletions(-)

-- 
2.34.1


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

end of thread, other threads:[~2025-05-22 22:48 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-09  7:20 [RFC next v2 0/5] ucount: add rlimit cache for ucount Chen Ridong
2025-05-09  7:20 ` [RFC next v2 1/5] user_namespace: add children list node Chen Ridong
2025-05-09  7:20 ` [RFC next v2 2/5] usernamespace: make usernamespace rcu safe Chen Ridong
2025-05-09  7:20 ` [RFC next v2 3/5] user_namespace: add user_ns iteration helper Chen Ridong
2025-05-09  7:20 ` [RFC next v2 4/5] uounts: factor out __inc_rlimit_get_ucounts/__dec_rlimit_put_ucounts Chen Ridong
2025-05-09  7:20 ` [RFC next v2 5/5] ucount: add rlimit cache for ucount Chen Ridong
2025-05-09 20:18 ` [RFC next v2 0/5] " Andrew Morton
2025-05-12 10:48   ` Sebastian Andrzej Siewior
2025-05-13  1:48     ` Chen Ridong
2025-05-15 10:29 ` Christian Brauner
2025-05-15 12:04   ` Chen Ridong
2025-05-16 11:48 ` Alexey Gladkov
2025-05-19 13:39   ` Chen Ridong
2025-05-19 16:32     ` Alexey Gladkov
2025-05-21  1:32       ` Chen Ridong
2025-05-21  7:29         ` Alexey Gladkov
2025-05-22 22:48           ` Andrei Vagin

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