[Devel] [PATCH hci-8.1 v3 1/2] sched: Fix sched_getaffinity syscall
Vladimir Riabchun
vladimir.riabchun at virtuozzo.com
Thu Oct 29 13:16:06 MSK 2026
We observed incorrect cpu numbers inside containers:
[root at localhost ~]# nproc
64
even when there were much less physical/virtual CPUs.
The root cause is incorrect bitmap_fill usage - it sets whole
integers only, without handling bit tails, so the actual number of
set bits is 64 = bits in ULONG.
If we use cpumask only or vcpus only, nproc and other getaffinity
users will get incorrect info about CT resources.
We can't run on more than count(cpuset) CPUs and we are
limited by vCPU number. So the minimum of these two is the
real limit.
Return first bits set - anyway they can't be used for anything
except counting from inside CT. Host behavior is not changed.
It is also intentional that we perform VE check against current
exec env - CT users will get virtualized view and host users
will get real affinity without vCPU info.
https://virtuozzo.atlassian.net/browse/VSTOR-141682
Signed-off-by: Vladimir Riabchun <vladimir.riabchun at virtuozzo.com>
---
kernel/sched/syscalls.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/kernel/sched/syscalls.c b/kernel/sched/syscalls.c
index 6d921043e9e7..ce5200c84573 100644
--- a/kernel/sched/syscalls.c
+++ b/kernel/sched/syscalls.c
@@ -1316,15 +1316,23 @@ long sched_getaffinity(pid_t pid, struct cpumask *mask)
if (retval)
return retval;
+ scoped_guard (raw_spinlock_irqsave, &p->pi_lock) {
+ cpumask_and(mask, &p->cpus_mask, cpu_active_mask);
+ }
+
if (!ve_is_super(get_exec_env())) {
+ /*
+ * setaffinity is not available inside CT, so these bits
+ * can only be used for counting.
+ * We can't have more than vcpus and we can't run on CPUs
+ * outside the mask. Reporting smallest will provide true
+ * information about CT resources.
+ */
+ unsigned int vcpus_avail = min(task_nr_cpus(p), cpumask_weight(mask));
cpumask_clear(mask);
- bitmap_fill(cpumask_bits(mask), num_online_vcpus());
- return 0;
+ bitmap_set(cpumask_bits(mask), 0, vcpus_avail);
}
- guard(raw_spinlock_irqsave)(&p->pi_lock);
- cpumask_and(mask, &p->cpus_mask, cpu_active_mask);
-
return 0;
}
--
2.52.0
More information about the Devel
mailing list