]> git.ipfire.org Git - thirdparty/linux.git/commit
Merge patch series "further damage-control lack of clone scalability"
authorChristian Brauner <brauner@kernel.org>
Fri, 5 Dec 2025 10:11:38 +0000 (11:11 +0100)
committerChristian Brauner <brauner@kernel.org>
Mon, 15 Dec 2025 13:33:38 +0000 (14:33 +0100)
commit961b2ad1b4131c947cbc75700c83a6deb0c91d02
treec4d5409a5c3f3f173c86cb990d78c55fbed5905d
parent887e97745ec336c2f49b6c0af3c4cc00a5df3211
parent6d864a1b182532e7570383af8825fa4ddcd24243
Merge patch series "further damage-control lack of clone scalability"

Mateusz Guzik <mjguzik@gmail.com> says:

When spawning and killing threads in separate processes in parallel the
primary bottleneck on the stock kernel is pidmap_lock, largely because
of a back-to-back acquire in the common case.

Benchmark code at the end.

With this patchset alloc_pid() only takes the lock once and consequently
alleviates the problem. While scalability improves, the lock remains the
primary bottleneck by a large margin.

I believe idr is a poor choice for the task at hand to begin with, but
sorting out that out beyond the scope of this patchset. At the same time
any replacement would be best evaluated against a state where the
above relock problem is fixed.

Performance improvement varies between reboots. When benchmarking with
20 processes creating and killing threads in a loop, the unpatched
baseline hovers around 465k ops/s, while patched is anything between
~510k ops/s and ~560k depending on false-sharing (which I only minimally
sanitized). So this is at least 10% if you are unlucky.

bench from will-it-scale:

char *testcase_description = "Thread creation and teardown";

static void *worker(void *arg)
{
        return (NULL);
}

void testcase(unsigned long long *iterations, unsigned long nr)
{
        pthread_t thread[1];
        int error;

        while (1) {
                for (int i = 0; i < 1; i++) {
                        error = pthread_create(&thread[i], NULL, worker, NULL);
                        assert(error == 0);
                }
                for (int i = 0; i < 1; i++) {
                        error = pthread_join(thread[i], NULL);
                        assert(error == 0);
                }
                (*iterations)++;
        }
}

v2:
- cosmetic fixes from Oleg
- drop idr_preload_many, relock pidmap + call idr_preload again instead
- write a commit message for the alloc pid patch

* patches from https://patch.msgid.link/20251203092851.287617-1-mjguzik@gmail.com:
  pid: only take pidmap_lock once on alloc
  ns: pad refcount

Link: https://patch.msgid.link/20251203092851.287617-1-mjguzik@gmail.com
Signed-off-by: Christian Brauner <brauner@kernel.org>