[PATCH v5 1/3] ipc/sem: account dynamically allocated sops arrays to memcg
From: Yingjie Wang
Date: Thu Oct 29 2026 - 01:03:55 EST
Commit 6a4746ba0619 ("ipc: remove memcg accounting for sops objects in
do_semtimedop()") removed accounting based on the assumption that sops
arrays would remain small, describing a maximum cost of two pages.
SEMOPM is a UAPI default that can be changed at build time and through
the per-namespace sysctl. Commit 50ec499b9a43 ("sysctl: allow change
system v ipc sysctls inside ipc namespace") made that limit tunable by
IPC namespace owners without capabilities in the initial user namespace.
do_semtimedop() keeps up to SEMOPM_FAST operations on the stack. Charge
every larger, dynamically allocated operation array to the caller's memory
cgroup. This avoids a second size threshold and prevents a configured
SEMOPM limit from expanding an unaccounted heap-allocation range.
In a 4-vCPU KVM guest, with the benchmark pinned to one vCPU in a leaf
memory cgroup, accounting raised the median time per successful semop()
call by 2.3% to 3.2% for 65, 500 and 1000 operations, compared with
unaccounted allocation. An invalid semid, which allocates and copies the
array before returning EINVAL, rose by 5.6% to 11.9%. The 64-operation
stack path changed by at most 0.9%, and successful calls in the root
cgroup by at most 2.3%. Each result used 21 samples from three boots.
Suggested-by: Shakeel Butt <shakeel.butt@xxxxxxxxx>
Link: https://lore.kernel.org/r/20261016152609.2528805-1-x-professor@xxxxxxxxxxx
Fixes: 6a4746ba0619 ("ipc: remove memcg accounting for sops objects in do_semtimedop()")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Yingjie Wang <x-professor@xxxxxxxxxxx>
---
ipc/sem.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ipc/sem.c b/ipc/sem.c
index 5ec41de7e85b2..ea95cca5bb0ec 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -2234,7 +2234,7 @@ static long do_semtimedop(int semid, struct sembuf __user *tsops,
return -EINVAL;
if (nsops > SEMOPM_FAST) {
- sops = kvmalloc_objs(*sops, nsops);
+ sops = kvmalloc_objs(*sops, nsops, GFP_KERNEL_ACCOUNT);
if (sops == NULL)
return -ENOMEM;
}
--
2.43.0